github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/builtin/providers/aws/resource_aws_vpc_endpoint.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/aws/awserr" 9 "github.com/aws/aws-sdk-go/service/ec2" 10 "github.com/hashicorp/terraform/helper/schema" 11 ) 12 13 func resourceAwsVpcEndpoint() *schema.Resource { 14 return &schema.Resource{ 15 Create: resourceAwsVPCEndpointCreate, 16 Read: resourceAwsVPCEndpointRead, 17 Update: resourceAwsVPCEndpointUpdate, 18 Delete: resourceAwsVPCEndpointDelete, 19 Importer: &schema.ResourceImporter{ 20 State: schema.ImportStatePassthrough, 21 }, 22 23 Schema: map[string]*schema.Schema{ 24 "policy": &schema.Schema{ 25 Type: schema.TypeString, 26 Optional: true, 27 Computed: true, 28 StateFunc: normalizeJson, 29 }, 30 "vpc_id": &schema.Schema{ 31 Type: schema.TypeString, 32 Required: true, 33 ForceNew: true, 34 }, 35 "service_name": &schema.Schema{ 36 Type: schema.TypeString, 37 Required: true, 38 ForceNew: true, 39 }, 40 "route_table_ids": &schema.Schema{ 41 Type: schema.TypeSet, 42 Optional: true, 43 Elem: &schema.Schema{Type: schema.TypeString}, 44 Set: schema.HashString, 45 }, 46 "prefix_list_id": &schema.Schema{ 47 Type: schema.TypeString, 48 Computed: true, 49 }, 50 }, 51 } 52 } 53 54 func resourceAwsVPCEndpointCreate(d *schema.ResourceData, meta interface{}) error { 55 conn := meta.(*AWSClient).ec2conn 56 input := &ec2.CreateVpcEndpointInput{ 57 VpcId: aws.String(d.Get("vpc_id").(string)), 58 RouteTableIds: expandStringList(d.Get("route_table_ids").(*schema.Set).List()), 59 ServiceName: aws.String(d.Get("service_name").(string)), 60 } 61 62 if v, ok := d.GetOk("policy"); ok { 63 policy := normalizeJson(v) 64 input.PolicyDocument = aws.String(policy) 65 } 66 67 log.Printf("[DEBUG] Creating VPC Endpoint: %#v", input) 68 output, err := conn.CreateVpcEndpoint(input) 69 if err != nil { 70 return fmt.Errorf("Error creating VPC Endpoint: %s", err) 71 } 72 log.Printf("[DEBUG] VPC Endpoint %q created.", *output.VpcEndpoint.VpcEndpointId) 73 74 d.SetId(*output.VpcEndpoint.VpcEndpointId) 75 76 return resourceAwsVPCEndpointRead(d, meta) 77 } 78 79 func resourceAwsVPCEndpointRead(d *schema.ResourceData, meta interface{}) error { 80 conn := meta.(*AWSClient).ec2conn 81 input := &ec2.DescribeVpcEndpointsInput{ 82 VpcEndpointIds: []*string{aws.String(d.Id())}, 83 } 84 85 log.Printf("[DEBUG] Reading VPC Endpoint: %q", d.Id()) 86 output, err := conn.DescribeVpcEndpoints(input) 87 88 if err != nil { 89 ec2err, ok := err.(awserr.Error) 90 if !ok { 91 return fmt.Errorf("Error reading VPC Endpoint: %s", err.Error()) 92 } 93 94 if ec2err.Code() == "InvalidVpcEndpointId.NotFound" { 95 return nil 96 } 97 98 return fmt.Errorf("Error reading VPC Endpoint: %s", err.Error()) 99 } 100 101 if len(output.VpcEndpoints) != 1 { 102 return fmt.Errorf("There's no unique VPC Endpoint, but %d endpoints: %#v", 103 len(output.VpcEndpoints), output.VpcEndpoints) 104 } 105 106 vpce := output.VpcEndpoints[0] 107 108 // A VPC Endpoint is associated with exactly one prefix list name (also called Service Name). 109 // The prefix list ID can be used in security groups, so retrieve it to support that capability. 110 prefixListServiceName := *vpce.ServiceName 111 prefixListInput := &ec2.DescribePrefixListsInput{ 112 Filters: []*ec2.Filter{ 113 {Name: aws.String("prefix-list-name"), Values: []*string{aws.String(prefixListServiceName)}}, 114 }, 115 } 116 117 log.Printf("[DEBUG] Reading VPC Endpoint prefix list: %s", prefixListServiceName) 118 prefixListsOutput, err := conn.DescribePrefixLists(prefixListInput) 119 120 if err != nil { 121 _, ok := err.(awserr.Error) 122 if !ok { 123 return fmt.Errorf("Error reading VPC Endpoint prefix list: %s", err.Error()) 124 } 125 } 126 127 if len(prefixListsOutput.PrefixLists) != 1 { 128 return fmt.Errorf("There are multiple prefix lists associated with the service name '%s'. Unexpected", prefixListServiceName) 129 } 130 131 d.Set("vpc_id", vpce.VpcId) 132 d.Set("policy", normalizeJson(*vpce.PolicyDocument)) 133 d.Set("service_name", vpce.ServiceName) 134 if err := d.Set("route_table_ids", aws.StringValueSlice(vpce.RouteTableIds)); err != nil { 135 return err 136 } 137 d.Set("prefix_list_id", prefixListsOutput.PrefixLists[0].PrefixListId) 138 139 return nil 140 } 141 142 func resourceAwsVPCEndpointUpdate(d *schema.ResourceData, meta interface{}) error { 143 conn := meta.(*AWSClient).ec2conn 144 input := &ec2.ModifyVpcEndpointInput{ 145 VpcEndpointId: aws.String(d.Id()), 146 } 147 148 if d.HasChange("route_table_ids") { 149 o, n := d.GetChange("route_table_ids") 150 os := o.(*schema.Set) 151 ns := n.(*schema.Set) 152 153 add := expandStringList(ns.Difference(os).List()) 154 if len(add) > 0 { 155 input.AddRouteTableIds = add 156 } 157 158 remove := expandStringList(os.Difference(ns).List()) 159 if len(remove) > 0 { 160 input.RemoveRouteTableIds = remove 161 } 162 } 163 164 if d.HasChange("policy") { 165 policy := normalizeJson(d.Get("policy")) 166 input.PolicyDocument = aws.String(policy) 167 } 168 169 log.Printf("[DEBUG] Updating VPC Endpoint: %#v", input) 170 _, err := conn.ModifyVpcEndpoint(input) 171 if err != nil { 172 return fmt.Errorf("Error updating VPC Endpoint: %s", err) 173 } 174 log.Printf("[DEBUG] VPC Endpoint %q updated", input.VpcEndpointId) 175 176 return resourceAwsVPCEndpointRead(d, meta) 177 } 178 179 func resourceAwsVPCEndpointDelete(d *schema.ResourceData, meta interface{}) error { 180 conn := meta.(*AWSClient).ec2conn 181 input := &ec2.DeleteVpcEndpointsInput{ 182 VpcEndpointIds: []*string{aws.String(d.Id())}, 183 } 184 185 log.Printf("[DEBUG] Deleting VPC Endpoint: %#v", input) 186 _, err := conn.DeleteVpcEndpoints(input) 187 188 if err != nil { 189 ec2err, ok := err.(awserr.Error) 190 if !ok { 191 return fmt.Errorf("Error deleting VPC Endpoint: %s", err.Error()) 192 } 193 194 if ec2err.Code() == "InvalidVpcEndpointId.NotFound" { 195 log.Printf("[DEBUG] VPC Endpoint %q is already gone", d.Id()) 196 } else { 197 return fmt.Errorf("Error deleting VPC Endpoint: %s", err.Error()) 198 } 199 } 200 201 log.Printf("[DEBUG] VPC Endpoint %q deleted", d.Id()) 202 d.SetId("") 203 204 return nil 205 }