diff --git a/aws/data_source_aws_vpc_endpoint.go b/aws/data_source_aws_vpc_endpoint.go index 2669ceb8e0e0..d09812b3813b 100644 --- a/aws/data_source_aws_vpc_endpoint.go +++ b/aws/data_source_aws_vpc_endpoint.go @@ -7,6 +7,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/structure" ) func dataSourceAwsVpcEndpoint() *schema.Resource { @@ -14,27 +15,39 @@ func dataSourceAwsVpcEndpoint() *schema.Resource { Read: dataSourceAwsVpcEndpointRead, Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Optional: true, + "cidr_blocks": { + Type: schema.TypeList, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, - "vpc_id": { - Type: schema.TypeString, - Optional: true, + "dns_entry": { + Type: schema.TypeList, Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns_name": { + Type: schema.TypeString, + Computed: true, + }, + "hosted_zone_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, }, - "service_name": { + "id": { Type: schema.TypeString, Optional: true, Computed: true, }, - "state": { - Type: schema.TypeString, - Optional: true, + "network_interface_ids": { + Type: schema.TypeSet, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, }, - "vpc_endpoint_type": { + "owner_id": { Type: schema.TypeString, Computed: true, }, @@ -42,58 +55,55 @@ func dataSourceAwsVpcEndpoint() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "route_table_ids": { - Type: schema.TypeSet, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, "prefix_list_id": { Type: schema.TypeString, Computed: true, }, - "cidr_blocks": { - Type: schema.TypeList, + "private_dns_enabled": { + Type: schema.TypeBool, Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, }, - "subnet_ids": { + "requester_managed": { + Type: schema.TypeBool, + Computed: true, + }, + "route_table_ids": { Type: schema.TypeSet, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "network_interface_ids": { + "security_group_ids": { Type: schema.TypeSet, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "security_group_ids": { + "service_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "state": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "subnet_ids": { Type: schema.TypeSet, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "private_dns_enabled": { - Type: schema.TypeBool, + "tags": tagsSchemaComputed(), + "vpc_endpoint_type": { + Type: schema.TypeString, Computed: true, }, - "dns_entry": { - Type: schema.TypeList, + "vpc_id": { + Type: schema.TypeString, + Optional: true, Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "dns_name": { - Type: schema.TypeString, - Computed: true, - }, - "hosted_zone_id": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, }, }, } @@ -121,19 +131,85 @@ func dataSourceAwsVpcEndpointRead(d *schema.ResourceData, meta interface{}) erro } log.Printf("[DEBUG] Reading VPC Endpoint: %s", req) - resp, err := conn.DescribeVpcEndpoints(req) + respVpce, err := conn.DescribeVpcEndpoints(req) if err != nil { - return err + return fmt.Errorf("error reading VPC Endpoint: %s", err) } - if resp == nil || len(resp.VpcEndpoints) == 0 { - return fmt.Errorf("no matching VPC endpoint found") + if respVpce == nil || len(respVpce.VpcEndpoints) == 0 { + return fmt.Errorf("no matching VPC Endpoint found") } - if len(resp.VpcEndpoints) > 1 { - return fmt.Errorf("multiple VPC endpoints matched; use additional constraints to reduce matches to a single VPC endpoint") + if len(respVpce.VpcEndpoints) > 1 { + return fmt.Errorf("multiple VPC Endpoints matched; use additional constraints to reduce matches to a single VPC Endpoint") } - vpce := resp.VpcEndpoints[0] + vpce := respVpce.VpcEndpoints[0] d.SetId(aws.StringValue(vpce.VpcEndpointId)) - return vpcEndpointAttributes(d, vpce, conn) + serviceName := aws.StringValue(vpce.ServiceName) + d.Set("service_name", serviceName) + d.Set("state", vpce.State) + d.Set("vpc_id", vpce.VpcId) + + respPl, err := conn.DescribePrefixLists(&ec2.DescribePrefixListsInput{ + Filters: buildEC2AttributeFilterList(map[string]string{ + "prefix-list-name": serviceName, + }), + }) + if err != nil { + return fmt.Errorf("error reading Prefix List (%s): %s", serviceName, err) + } + if respPl == nil || len(respPl.PrefixLists) == 0 { + d.Set("cidr_blocks", []interface{}{}) + } else if len(respPl.PrefixLists) > 1 { + return fmt.Errorf("multiple prefix lists associated with the service name '%s'. Unexpected", serviceName) + } else { + pl := respPl.PrefixLists[0] + + d.Set("prefix_list_id", pl.PrefixListId) + err = d.Set("cidr_blocks", flattenStringList(pl.Cidrs)) + if err != nil { + return fmt.Errorf("error setting cidr_blocks: %s", err) + } + } + + err = d.Set("dns_entry", flattenVpcEndpointDnsEntries(vpce.DnsEntries)) + if err != nil { + return fmt.Errorf("error setting dns_entry: %s", err) + } + err = d.Set("network_interface_ids", flattenStringSet(vpce.NetworkInterfaceIds)) + if err != nil { + return fmt.Errorf("error setting network_interface_ids: %s", err) + } + d.Set("owner_id", vpce.OwnerId) + policy, err := structure.NormalizeJsonString(aws.StringValue(vpce.PolicyDocument)) + if err != nil { + return fmt.Errorf("policy contains an invalid JSON: %s", err) + } + d.Set("policy", policy) + d.Set("private_dns_enabled", vpce.PrivateDnsEnabled) + err = d.Set("route_table_ids", flattenStringSet(vpce.RouteTableIds)) + if err != nil { + return fmt.Errorf("error setting route_table_ids: %s", err) + } + d.Set("requester_managed", vpce.RequesterManaged) + err = d.Set("security_group_ids", flattenVpcEndpointSecurityGroupIds(vpce.Groups)) + if err != nil { + return fmt.Errorf("error setting security_group_ids: %s", err) + } + err = d.Set("subnet_ids", flattenStringSet(vpce.SubnetIds)) + if err != nil { + return fmt.Errorf("error setting subnet_ids: %s", err) + } + err = d.Set("tags", tagsToMap(vpce.Tags)) + if err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + // VPC endpoints don't have types in GovCloud, so set type to default if empty + if vpceType := aws.StringValue(vpce.VpcEndpointType); vpceType == "" { + d.Set("vpc_endpoint_type", ec2.VpcEndpointTypeGateway) + } else { + d.Set("vpc_endpoint_type", vpceType) + } + + return nil } diff --git a/aws/data_source_aws_vpc_endpoint_service.go b/aws/data_source_aws_vpc_endpoint_service.go index b4eaa5e7dd93..3a4fc93b65c7 100644 --- a/aws/data_source_aws_vpc_endpoint_service.go +++ b/aws/data_source_aws_vpc_endpoint_service.go @@ -16,11 +16,43 @@ func dataSourceAwsVpcEndpointService() *schema.Resource { Read: dataSourceAwsVpcEndpointServiceRead, Schema: map[string]*schema.Schema{ + "acceptance_required": { + Type: schema.TypeBool, + Computed: true, + }, + "availability_zones": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + Set: schema.HashString, + }, + "base_endpoint_dns_names": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + Set: schema.HashString, + }, + "manages_vpc_endpoints": { + Type: schema.TypeBool, + Computed: true, + }, + "owner": { + Type: schema.TypeString, + Computed: true, + }, + "private_dns_name": { + Type: schema.TypeString, + Computed: true, + }, "service": { Type: schema.TypeString, Optional: true, ConflictsWith: []string{"service_name"}, }, + "service_id": { + Type: schema.TypeString, + Computed: true, + }, "service_name": { Type: schema.TypeString, Optional: true, @@ -31,34 +63,11 @@ func dataSourceAwsVpcEndpointService() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "owner": { - Type: schema.TypeString, - Computed: true, - }, + "tags": tagsSchemaComputed(), "vpc_endpoint_policy_supported": { Type: schema.TypeBool, Computed: true, }, - "acceptance_required": { - Type: schema.TypeBool, - Computed: true, - }, - "availability_zones": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Computed: true, - Set: schema.HashString, - }, - "private_dns_name": { - Type: schema.TypeString, - Computed: true, - }, - "base_endpoint_dns_names": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Computed: true, - Set: schema.HashString, - }, }, } } @@ -80,10 +89,10 @@ func dataSourceAwsVpcEndpointServiceRead(d *schema.ResourceData, meta interface{ ServiceNames: aws.StringSlice([]string{serviceName}), } - log.Printf("[DEBUG] Reading VPC Endpoint Services: %s", req) + log.Printf("[DEBUG] Reading VPC Endpoint Service: %s", req) resp, err := conn.DescribeVpcEndpointServices(req) if err != nil { - return fmt.Errorf("Error fetching VPC Endpoint Services: %s", err) + return fmt.Errorf("error reading VPC Endpoint Service (%s): %s", serviceName, err) } if resp == nil || (len(resp.ServiceNames) == 0 && len(resp.ServiceDetails) == 0) { @@ -114,13 +123,25 @@ func dataSourceAwsVpcEndpointServiceRead(d *schema.ResourceData, meta interface{ serviceName = aws.StringValue(sd.ServiceName) d.SetId(strconv.Itoa(hashcode.String(serviceName))) d.Set("service_name", serviceName) - d.Set("service_type", sd.ServiceType[0].ServiceType) - d.Set("owner", sd.Owner) - d.Set("vpc_endpoint_policy_supported", sd.VpcEndpointPolicySupported) d.Set("acceptance_required", sd.AcceptanceRequired) - d.Set("availability_zones", flattenStringList(sd.AvailabilityZones)) + err = d.Set("availability_zones", flattenStringSet(sd.AvailabilityZones)) + if err != nil { + return fmt.Errorf("error setting availability_zones: %s", err) + } + err = d.Set("base_endpoint_dns_names", flattenStringSet(sd.BaseEndpointDnsNames)) + if err != nil { + return fmt.Errorf("error setting base_endpoint_dns_names: %s", err) + } + d.Set("manages_vpc_endpoints", sd.ManagesVpcEndpoints) + d.Set("owner", sd.Owner) d.Set("private_dns_name", sd.PrivateDnsName) - d.Set("base_endpoint_dns_names", flattenStringList(sd.BaseEndpointDnsNames)) + d.Set("service_id", sd.ServiceId) + d.Set("service_type", sd.ServiceType[0].ServiceType) + err = d.Set("tags", tagsToMap(sd.Tags)) + if err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + d.Set("vpc_endpoint_policy_supported", sd.VpcEndpointPolicySupported) return nil } diff --git a/aws/data_source_aws_vpc_endpoint_service_test.go b/aws/data_source_aws_vpc_endpoint_service_test.go index 1b99c8129438..b1cd15696025 100644 --- a/aws/data_source_aws_vpc_endpoint_service_test.go +++ b/aws/data_source_aws_vpc_endpoint_service_test.go @@ -2,7 +2,6 @@ package aws import ( "fmt" - "regexp" "testing" "github.com/hashicorp/terraform/helper/acctest" @@ -10,6 +9,9 @@ import ( ) func TestAccDataSourceAwsVpcEndpointService_gateway(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint_service.test" + region := testAccGetRegion() + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -17,32 +19,16 @@ func TestAccDataSourceAwsVpcEndpointService_gateway(t *testing.T) { { Config: testAccDataSourceAwsVpcEndpointServiceGatewayConfig, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "service_name", "com.amazonaws.us-west-2.s3"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "service_type", "Gateway"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "owner", "amazon"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "vpc_endpoint_policy_supported", "true"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "acceptance_required", "false"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "availability_zones.#", "4"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "availability_zones.2487133097", "us-west-2a"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "availability_zones.221770259", "us-west-2b"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "availability_zones.2050015877", "us-west-2c"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "availability_zones.3830732582", "us-west-2d"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "private_dns_name", ""), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "base_endpoint_dns_names.#", "1"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.s3", "base_endpoint_dns_names.3003388505", "s3.us-west-2.amazonaws.com"), + resource.TestCheckResourceAttr(datasourceName, "service_name", fmt.Sprintf("com.amazonaws.%s.s3", region)), + resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "false"), + resource.TestCheckResourceAttrPair(datasourceName, "availability_zones.#", "data.aws_availability_zones.available", "names.#"), + resource.TestCheckResourceAttr(datasourceName, "base_endpoint_dns_names.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "manages_vpc_endpoints", "false"), + resource.TestCheckResourceAttr(datasourceName, "owner", "amazon"), + resource.TestCheckResourceAttr(datasourceName, "private_dns_name", ""), + resource.TestCheckResourceAttr(datasourceName, "service_type", "Gateway"), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "true"), + resource.TestCheckResourceAttr(datasourceName, "tags.%", "0"), ), }, }, @@ -50,6 +36,9 @@ func TestAccDataSourceAwsVpcEndpointService_gateway(t *testing.T) { } func TestAccDataSourceAwsVpcEndpointService_interface(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint_service.test" + region := testAccGetRegion() + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -57,30 +46,15 @@ func TestAccDataSourceAwsVpcEndpointService_interface(t *testing.T) { { Config: testAccDataSourceAwsVpcEndpointServiceInterfaceConfig, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "service_name", "com.amazonaws.us-west-2.ec2"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "service_type", "Interface"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "owner", "amazon"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "vpc_endpoint_policy_supported", "false"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "acceptance_required", "false"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "availability_zones.#", "3"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "availability_zones.2487133097", "us-west-2a"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "availability_zones.221770259", "us-west-2b"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "availability_zones.2050015877", "us-west-2c"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "private_dns_name", "ec2.us-west-2.amazonaws.com"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "base_endpoint_dns_names.#", "1"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.ec2", "base_endpoint_dns_names.1880016359", "ec2.us-west-2.vpce.amazonaws.com"), + resource.TestCheckResourceAttr(datasourceName, "service_name", fmt.Sprintf("com.amazonaws.%s.ec2", region)), + resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "false"), + resource.TestCheckResourceAttr(datasourceName, "base_endpoint_dns_names.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "manages_vpc_endpoints", "false"), + resource.TestCheckResourceAttr(datasourceName, "owner", "amazon"), + resource.TestCheckResourceAttr(datasourceName, "private_dns_name", fmt.Sprintf("ec2.%s.amazonaws.com", region)), + resource.TestCheckResourceAttr(datasourceName, "service_type", "Interface"), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "false"), + resource.TestCheckResourceAttr(datasourceName, "tags.%", "0"), ), }, }, @@ -88,29 +62,24 @@ func TestAccDataSourceAwsVpcEndpointService_interface(t *testing.T) { } func TestAccDataSourceAwsVpcEndpointService_custom(t *testing.T) { - lbName := fmt.Sprintf("testaccawsnlb-basic-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + datasourceName := "data.aws_vpc_endpoint_service.test" + rName := fmt.Sprintf("tf-testacc-vpcesvc-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsVpcEndpointServiceCustomConfig(lbName), + Config: testAccDataSourceAwsVpcEndpointServiceCustomConfig(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.foo", "service_type", "Interface"), - resource.TestMatchResourceAttr( // AWS account ID - "data.aws_vpc_endpoint_service.foo", "owner", regexp.MustCompile("^[0-9]{12}$")), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.foo", "vpc_endpoint_policy_supported", "false"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.foo", "acceptance_required", "true"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.foo", "availability_zones.#", "2"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.foo", "availability_zones.2487133097", "us-west-2a"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint_service.foo", "availability_zones.221770259", "us-west-2b"), + resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "true"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.#", "2"), + resource.TestCheckResourceAttr(datasourceName, "manages_vpc_endpoints", "false"), + testAccCheckResourceAttrAccountID(datasourceName, "owner"), + resource.TestCheckResourceAttr(datasourceName, "service_type", "Interface"), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "false"), + resource.TestCheckResourceAttr(datasourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(datasourceName, "tags.Name", rName), ), }, }, @@ -118,42 +87,35 @@ func TestAccDataSourceAwsVpcEndpointService_custom(t *testing.T) { } const testAccDataSourceAwsVpcEndpointServiceGatewayConfig = ` -provider "aws" { - region = "us-west-2" -} +data "aws_availability_zones" "available" {} -data "aws_vpc_endpoint_service" "s3" { +data "aws_vpc_endpoint_service" "test" { service = "s3" } ` const testAccDataSourceAwsVpcEndpointServiceInterfaceConfig = ` -provider "aws" { - region = "us-west-2" -} - -data "aws_vpc_endpoint_service" "ec2" { +data "aws_vpc_endpoint_service" "test" { service = "ec2" } ` -func testAccDataSourceAwsVpcEndpointServiceCustomConfig(lbName string) string { - return fmt.Sprintf( - ` -resource "aws_vpc" "nlb_test" { +func testAccDataSourceAwsVpcEndpointServiceCustomConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" tags = { - Name = "terraform-testacc-vpc-endpoint-service-custom" + Name = %[1]q } } -resource "aws_lb" "nlb_test_1" { - name = "%s" +resource "aws_lb" "test" { + name = %[1]q subnets = [ - "${aws_subnet.nlb_test_1.id}", - "${aws_subnet.nlb_test_2.id}", + "${aws_subnet.test1.id}", + "${aws_subnet.test2.id}", ] load_balancer_type = "network" @@ -162,40 +124,46 @@ resource "aws_lb" "nlb_test_1" { enable_deletion_protection = false tags = { - Name = "testAccVpcEndpointServiceBasicConfig_nlb1" + Name = %[1]q } } -resource "aws_subnet" "nlb_test_1" { - vpc_id = "${aws_vpc.nlb_test.id}" +data "aws_availability_zones" "available" {} + +resource "aws_subnet" "test1" { + vpc_id = "${aws_vpc.test.id}" cidr_block = "10.0.1.0/24" - availability_zone = "us-west-2a" + availability_zone = "${data.aws_availability_zones.available.names[0]}" tags = { - Name = "tf-acc-vpc-endpoint-service-custom" + Name = %[1]q } } -resource "aws_subnet" "nlb_test_2" { - vpc_id = "${aws_vpc.nlb_test.id}" +resource "aws_subnet" "test2" { + vpc_id = "${aws_vpc.test.id}" cidr_block = "10.0.2.0/24" - availability_zone = "us-west-2b" + availability_zone = "${data.aws_availability_zones.available.names[1]}" tags = { - Name = "tf-acc-vpc-endpoint-service-custom" + Name = %[1]q } } -resource "aws_vpc_endpoint_service" "foo" { +resource "aws_vpc_endpoint_service" "test" { acceptance_required = true network_load_balancer_arns = [ - "${aws_lb.nlb_test_1.id}", + "${aws_lb.test.id}", ] + + tags = { + Name = %[1]q + } } -data "aws_vpc_endpoint_service" "foo" { - service_name = "${aws_vpc_endpoint_service.foo.service_name}" +data "aws_vpc_endpoint_service" "test" { + service_name = "${aws_vpc_endpoint_service.test.service_name}" } -`, lbName) +`, rName) } diff --git a/aws/data_source_aws_vpc_endpoint_test.go b/aws/data_source_aws_vpc_endpoint_test.go index 532564e019de..1bfccb09b5b4 100644 --- a/aws/data_source_aws_vpc_endpoint_test.go +++ b/aws/data_source_aws_vpc_endpoint_test.go @@ -4,27 +4,32 @@ import ( "fmt" "testing" + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" ) func TestAccDataSourceAwsVpcEndpoint_gatewayBasic(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsVpcEndpointConfig_gatewayBasic, + Config: testAccDataSourceAwsVpcEndpointConfig_gatewayBasic(rName), Check: resource.ComposeTestCheckFunc( - testAccDataSourceAwsVpcEndpointCheckExists("data.aws_vpc_endpoint.s3", "aws_vpc_endpoint.s3"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint.s3", "vpc_endpoint_type", "Gateway"), - resource.TestCheckResourceAttrSet("data.aws_vpc_endpoint.s3", "prefix_list_id"), - resource.TestCheckResourceAttrSet("data.aws_vpc_endpoint.s3", "cidr_blocks.#"), - resource.TestCheckResourceAttr("data.aws_vpc_endpoint.s3", "route_table_ids.#", "0"), - resource.TestCheckResourceAttr("data.aws_vpc_endpoint.s3", "subnet_ids.#", "0"), - resource.TestCheckResourceAttr("data.aws_vpc_endpoint.s3", "network_interface_ids.#", "0"), - resource.TestCheckResourceAttr("data.aws_vpc_endpoint.s3", "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_type", "Gateway"), + resource.TestCheckResourceAttrSet(datasourceName, "prefix_list_id"), + resource.TestCheckResourceAttrSet(datasourceName, "cidr_blocks.#"), + resource.TestCheckResourceAttr(datasourceName, "route_table_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "subnet_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "network_interface_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(datasourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(datasourceName, "tags.%", "0"), + testAccCheckResourceAttrAccountID(datasourceName, "owner_id"), ), }, }, @@ -32,33 +37,56 @@ func TestAccDataSourceAwsVpcEndpoint_gatewayBasic(t *testing.T) { } func TestAccDataSourceAwsVpcEndpoint_byId(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsVpcEndpointConfig_byId, + Config: testAccDataSourceAwsVpcEndpointConfig_byId(rName), Check: resource.ComposeTestCheckFunc( - testAccDataSourceAwsVpcEndpointCheckExists("data.aws_vpc_endpoint.by_id", "aws_vpc_endpoint.s3"), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_type", "Gateway"), + resource.TestCheckResourceAttrSet(datasourceName, "prefix_list_id"), + resource.TestCheckResourceAttrSet(datasourceName, "cidr_blocks.#"), + resource.TestCheckResourceAttr(datasourceName, "route_table_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "subnet_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "network_interface_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(datasourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(datasourceName, "tags.%", "0"), + testAccCheckResourceAttrAccountID(datasourceName, "owner_id"), ), }, }, }) } -func TestAccDataSourceAwsVpcEndpoint_gatewayWithRouteTable(t *testing.T) { +func TestAccDataSourceAwsVpcEndpoint_gatewayWithRouteTableAndTags(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsVpcEndpointConfig_gatewayWithRouteTable, + Config: testAccDataSourceAwsVpcEndpointConfig_gatewayWithRouteTableAndTags(rName), Check: resource.ComposeTestCheckFunc( - testAccDataSourceAwsVpcEndpointCheckExists("data.aws_vpc_endpoint.s3", "aws_vpc_endpoint.s3"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint.s3", "vpc_endpoint_type", "Gateway"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint.s3", "route_table_ids.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_type", "Gateway"), + resource.TestCheckResourceAttrSet(datasourceName, "prefix_list_id"), + resource.TestCheckResourceAttrSet(datasourceName, "cidr_blocks.#"), + resource.TestCheckResourceAttr(datasourceName, "route_table_ids.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "subnet_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "network_interface_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(datasourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(datasourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(datasourceName, "tags.Name", rName), + testAccCheckResourceAttrAccountID(datasourceName, "owner_id"), ), }, }, @@ -66,170 +94,179 @@ func TestAccDataSourceAwsVpcEndpoint_gatewayWithRouteTable(t *testing.T) { } func TestAccDataSourceAwsVpcEndpoint_interface(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsVpcEndpointConfig_interface, + Config: testAccDataSourceAwsVpcEndpointConfig_interface(rName), Check: resource.ComposeTestCheckFunc( - testAccDataSourceAwsVpcEndpointCheckExists("data.aws_vpc_endpoint.ec2", "aws_vpc_endpoint.ec2"), - resource.TestCheckResourceAttr( - "data.aws_vpc_endpoint.ec2", "vpc_endpoint_type", "Interface"), - resource.TestCheckNoResourceAttr("data.aws_vpc_endpoint.ec2", "prefix_list_id"), - resource.TestCheckResourceAttr("data.aws_vpc_endpoint.ec2", "cidr_blocks.#", "0"), - resource.TestCheckResourceAttr("data.aws_vpc_endpoint.ec2", "route_table_ids.#", "0"), - resource.TestCheckResourceAttr("data.aws_vpc_endpoint.ec2", "subnet_ids.#", "1"), - resource.TestCheckResourceAttr("data.aws_vpc_endpoint.ec2", "security_group_ids.#", "1"), - resource.TestCheckResourceAttr("data.aws_vpc_endpoint.ec2", "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_type", "Interface"), + resource.TestCheckNoResourceAttr(datasourceName, "prefix_list_id"), + resource.TestCheckResourceAttr(datasourceName, "cidr_blocks.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "route_table_ids.#", "0"), + resource.TestCheckResourceAttr(datasourceName, "subnet_ids.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "network_interface_ids.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "security_group_ids.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(datasourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(datasourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(datasourceName, "tags.Name", rName), + testAccCheckResourceAttrAccountID(datasourceName, "owner_id"), ), }, }, }) } -func testAccDataSourceAwsVpcEndpointCheckExists(dsName, rsName string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[dsName] - if !ok { - return fmt.Errorf("root module has no resource called %s", dsName) - } - - vpceRs, ok := s.RootModule().Resources[rsName] - if !ok { - return fmt.Errorf("can't find %s in state", rsName) - } +func testAccDataSourceAwsVpcEndpointConfig_gatewayBasic(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.1.0.0/16" - attr := rs.Primary.Attributes + tags = { + Name = %[1]q + } +} - if attr["id"] != vpceRs.Primary.Attributes["id"] { - return fmt.Errorf( - "id is %s; want %s", - attr["id"], - vpceRs.Primary.Attributes["id"], - ) - } +data "aws_region" "current" {} - return nil - } +resource "aws_vpc_endpoint" "test" { + vpc_id = "${aws_vpc.test.id}" + service_name = "com.amazonaws.${data.aws_region.current.name}.s3" } -const testAccDataSourceAwsVpcEndpointConfig_gatewayBasic = ` -provider "aws" { - region = "us-west-2" +data "aws_vpc_endpoint" "test" { + vpc_id = "${aws_vpc.test.id}" + service_name = "${aws_vpc_endpoint.test.service_name}" + state = "available" +} +`, rName) } -resource "aws_vpc" "foo" { +func testAccDataSourceAwsVpcEndpointConfig_byId(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { cidr_block = "10.1.0.0/16" tags = { - Name = "terraform-testacc-vpc-endpoint-data-source-gw-basic" + Name = %[1]q } } -resource "aws_vpc_endpoint" "s3" { - vpc_id = "${aws_vpc.foo.id}" - service_name = "com.amazonaws.us-west-2.s3" -} +data "aws_region" "current" {} -data "aws_vpc_endpoint" "s3" { - vpc_id = "${aws_vpc.foo.id}" - service_name = "${aws_vpc_endpoint.s3.service_name}" - state = "available" +resource "aws_vpc_endpoint" "test" { + vpc_id = "${aws_vpc.test.id}" + service_name = "com.amazonaws.${data.aws_region.current.name}.s3" } -` -const testAccDataSourceAwsVpcEndpointConfig_byId = ` -provider "aws" { - region = "us-west-2" +data "aws_vpc_endpoint" "test" { + id = "${aws_vpc_endpoint.test.id}" +} +`, rName) } -resource "aws_vpc" "foo" { +func testAccDataSourceAwsVpcEndpointConfig_gatewayWithRouteTableAndTags(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { cidr_block = "10.1.0.0/16" tags = { - Name = "terraform-testacc-vpc-endpoint-data-source-by-id" + Name = %[1]q } } -resource "aws_vpc_endpoint" "s3" { - vpc_id = "${aws_vpc.foo.id}" - service_name = "com.amazonaws.us-west-2.s3" -} +resource "aws_route_table" "test" { + vpc_id = "${aws_vpc.test.id}" -data "aws_vpc_endpoint" "by_id" { - id = "${aws_vpc_endpoint.s3.id}" + tags = { + Name = %[1]q + } } -` -const testAccDataSourceAwsVpcEndpointConfig_gatewayWithRouteTable = ` -provider "aws" { - region = "us-west-2" -} +data "aws_region" "current" {} -resource "aws_vpc" "foo" { - cidr_block = "10.1.0.0/16" +resource "aws_vpc_endpoint" "test" { + vpc_id = "${aws_vpc.test.id}" + service_name = "com.amazonaws.${data.aws_region.current.name}.s3" + + route_table_ids = [ + "${aws_route_table.test.id}", + ] tags = { - Name = "terraform-testacc-vpc-endpoint-data-source-with-route-table" + Name = %[1]q } } -resource "aws_route_table" "rt" { - vpc_id = "${aws_vpc.foo.id}" +data "aws_vpc_endpoint" "test" { + vpc_id = "${aws_vpc.test.id}" + service_name = "${aws_vpc_endpoint.test.service_name}" + state = "available" } - -resource "aws_vpc_endpoint" "s3" { - vpc_id = "${aws_vpc.foo.id}" - service_name = "com.amazonaws.us-west-2.s3" - route_table_ids = ["${aws_route_table.rt.id}"] +`, rName) } -data "aws_vpc_endpoint" "s3" { - vpc_id = "${aws_vpc.foo.id}" - service_name = "${aws_vpc_endpoint.s3.service_name}" - state = "available" -} -` +func testAccDataSourceAwsVpcEndpointConfig_interface(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.1.0.0/16" -const testAccDataSourceAwsVpcEndpointConfig_interface = ` -provider "aws" { - region = "us-west-2" + tags = { + Name = %[1]q + } } -resource "aws_vpc" "foo" { - cidr_block = "10.1.0.0/16" +data "aws_availability_zones" "available" {} + +resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test.id}" + cidr_block = "${aws_vpc.test.cidr_block}" + availability_zone = "${data.aws_availability_zones.available.names[0]}" tags = { - Name = "terraform-testacc-vpc-endpoint-data-source-interface" + Name = %[1]q } } -resource "aws_subnet" "sn" { - vpc_id = "${aws_vpc.foo.id}" - cidr_block = "${aws_vpc.foo.cidr_block}" - availability_zone = "us-west-2a" +resource "aws_security_group" "test" { + vpc_id = "${aws_vpc.test.id}" + name = %[1]q + tags = { - Name = "tf-acc-vpc-endpoint-data-source-interface" + Name = %[1]q } } -resource "aws_security_group" "sg" { - vpc_id = "${aws_vpc.foo.id}" -} +data "aws_region" "current" {} -resource "aws_vpc_endpoint" "ec2" { - vpc_id = "${aws_vpc.foo.id}" - vpc_endpoint_type = "Interface" - service_name = "com.amazonaws.us-west-2.ec2" - subnet_ids = ["${aws_subnet.sn.id}"] - security_group_ids = ["${aws_security_group.sg.id}"] +resource "aws_vpc_endpoint" "test" { + vpc_id = "${aws_vpc.test.id}" + vpc_endpoint_type = "Interface" + service_name = "com.amazonaws.${data.aws_region.current.name}.ec2" private_dns_enabled = false + + subnet_ids = [ + "${aws_subnet.test.id}", + ] + + security_group_ids = [ + "${aws_security_group.test.id}", + ] + + tags = { + Name = %[1]q + } } -data "aws_vpc_endpoint" "ec2" { - vpc_id = "${aws_vpc.foo.id}" - service_name = "${aws_vpc_endpoint.ec2.service_name}" - state = "available" +data "aws_vpc_endpoint" "test" { + vpc_id = "${aws_vpc.test.id}" + service_name = "${aws_vpc_endpoint.test.service_name}" + state = "available" +} +`, rName) } -` diff --git a/aws/resource_aws_vpc_endpoint.go b/aws/resource_aws_vpc_endpoint.go index aa5c4ec36c5f..86c2434f8850 100644 --- a/aws/resource_aws_vpc_endpoint.go +++ b/aws/resource_aws_vpc_endpoint.go @@ -25,25 +25,40 @@ func resourceAwsVpcEndpoint() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "vpc_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "vpc_endpoint_type": { - Type: schema.TypeString, + "auto_accept": { + Type: schema.TypeBool, Optional: true, - ForceNew: true, - Default: ec2.VpcEndpointTypeGateway, - ValidateFunc: validation.StringInSlice([]string{ - ec2.VpcEndpointTypeGateway, - ec2.VpcEndpointTypeInterface, - }, false), }, - "service_name": { + "cidr_blocks": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "dns_entry": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns_name": { + Type: schema.TypeString, + Computed: true, + }, + "hosted_zone_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "network_interface_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "owner_id": { Type: schema.TypeString, - Required: true, - ForceNew: true, + Computed: true, }, "policy": { Type: schema.TypeString, @@ -56,14 +71,20 @@ func resourceAwsVpcEndpoint() *schema.Resource { return json }, }, - "route_table_ids": { - Type: schema.TypeSet, + "prefix_list_id": { + Type: schema.TypeString, + Computed: true, + }, + "private_dns_enabled": { + Type: schema.TypeBool, Optional: true, + Default: false, + }, + "requester_managed": { + Type: schema.TypeBool, Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, - "subnet_ids": { + "route_table_ids": { Type: schema.TypeSet, Optional: true, Computed: true, @@ -77,49 +98,37 @@ func resourceAwsVpcEndpoint() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "private_dns_enabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "state": { + "service_name": { Type: schema.TypeString, - Computed: true, + Required: true, + ForceNew: true, }, - "prefix_list_id": { + "state": { Type: schema.TypeString, Computed: true, }, - "cidr_blocks": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "network_interface_ids": { + "subnet_ids": { Type: schema.TypeSet, + Optional: true, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "dns_entry": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "dns_name": { - Type: schema.TypeString, - Computed: true, - }, - "hosted_zone_id": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "auto_accept": { - Type: schema.TypeBool, + "tags": tagsSchema(), + "vpc_endpoint_type": { + Type: schema.TypeString, Optional: true, + ForceNew: true, + Default: ec2.VpcEndpointTypeGateway, + ValidateFunc: validation.StringInSlice([]string{ + ec2.VpcEndpointTypeGateway, + ec2.VpcEndpointTypeInterface, + }, false), + }, + "vpc_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, }, }, @@ -177,15 +186,19 @@ func resourceAwsVpcEndpointCreate(d *schema.ResourceData, meta interface{}) erro return err } + if err := setTags(conn, d); err != nil { + return err + } + return resourceAwsVpcEndpointRead(d, meta) } func resourceAwsVpcEndpointRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - vpce, state, err := vpcEndpointStateRefresh(conn, d.Id())() + vpceRaw, state, err := vpcEndpointStateRefresh(conn, d.Id())() if err != nil && state != "failed" { - return fmt.Errorf("Error reading VPC Endpoint: %s", err) + return fmt.Errorf("error reading VPC Endpoint (%s): %s", d.Id(), err) } terminalStates := map[string]bool{ @@ -201,7 +214,75 @@ func resourceAwsVpcEndpointRead(d *schema.ResourceData, meta interface{}) error return nil } - return vpcEndpointAttributes(d, vpce.(*ec2.VpcEndpoint), conn) + vpce := vpceRaw.(*ec2.VpcEndpoint) + + serviceName := aws.StringValue(vpce.ServiceName) + d.Set("service_name", serviceName) + d.Set("state", vpce.State) + d.Set("vpc_id", vpce.VpcId) + + respPl, err := conn.DescribePrefixLists(&ec2.DescribePrefixListsInput{ + Filters: buildEC2AttributeFilterList(map[string]string{ + "prefix-list-name": serviceName, + }), + }) + if err != nil { + return fmt.Errorf("error reading Prefix List (%s): %s", serviceName, err) + } + if respPl == nil || len(respPl.PrefixLists) == 0 { + d.Set("cidr_blocks", []interface{}{}) + } else if len(respPl.PrefixLists) > 1 { + return fmt.Errorf("multiple prefix lists associated with the service name '%s'. Unexpected", serviceName) + } else { + pl := respPl.PrefixLists[0] + + d.Set("prefix_list_id", pl.PrefixListId) + err = d.Set("cidr_blocks", flattenStringList(pl.Cidrs)) + if err != nil { + return fmt.Errorf("error setting cidr_blocks: %s", err) + } + } + + err = d.Set("dns_entry", flattenVpcEndpointDnsEntries(vpce.DnsEntries)) + if err != nil { + return fmt.Errorf("error setting dns_entry: %s", err) + } + err = d.Set("network_interface_ids", flattenStringSet(vpce.NetworkInterfaceIds)) + if err != nil { + return fmt.Errorf("error setting network_interface_ids: %s", err) + } + d.Set("owner_id", vpce.OwnerId) + policy, err := structure.NormalizeJsonString(aws.StringValue(vpce.PolicyDocument)) + if err != nil { + return fmt.Errorf("policy contains an invalid JSON: %s", err) + } + d.Set("policy", policy) + d.Set("private_dns_enabled", vpce.PrivateDnsEnabled) + err = d.Set("route_table_ids", flattenStringSet(vpce.RouteTableIds)) + if err != nil { + return fmt.Errorf("error setting route_table_ids: %s", err) + } + d.Set("requester_managed", vpce.RequesterManaged) + err = d.Set("security_group_ids", flattenVpcEndpointSecurityGroupIds(vpce.Groups)) + if err != nil { + return fmt.Errorf("error setting security_group_ids: %s", err) + } + err = d.Set("subnet_ids", flattenStringSet(vpce.SubnetIds)) + if err != nil { + return fmt.Errorf("error setting subnet_ids: %s", err) + } + err = d.Set("tags", tagsToMap(vpce.Tags)) + if err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + // VPC endpoints don't have types in GovCloud, so set type to default if empty + if vpceType := aws.StringValue(vpce.VpcEndpointType); vpceType == "" { + d.Set("vpc_endpoint_type", ec2.VpcEndpointTypeGateway) + } else { + d.Set("vpc_endpoint_type", vpceType) + } + + return nil } func resourceAwsVpcEndpointUpdate(d *schema.ResourceData, meta interface{}) error { @@ -247,6 +328,10 @@ func resourceAwsVpcEndpointUpdate(d *schema.ResourceData, meta interface{}) erro return err } + if err := setTags(conn, d); err != nil { + return err + } + return resourceAwsVpcEndpointRead(d, meta) } @@ -367,72 +452,6 @@ func vpcEndpointWaitUntilDeleted(conn *ec2.EC2, vpceId string, timeout time.Dura return err } -func vpcEndpointAttributes(d *schema.ResourceData, vpce *ec2.VpcEndpoint, conn *ec2.EC2) error { - d.Set("state", vpce.State) - d.Set("vpc_id", vpce.VpcId) - - serviceName := aws.StringValue(vpce.ServiceName) - d.Set("service_name", serviceName) - // VPC endpoints don't have types in GovCloud, so set type to default if empty - if aws.StringValue(vpce.VpcEndpointType) == "" { - d.Set("vpc_endpoint_type", ec2.VpcEndpointTypeGateway) - } else { - d.Set("vpc_endpoint_type", vpce.VpcEndpointType) - } - - policy, err := structure.NormalizeJsonString(aws.StringValue(vpce.PolicyDocument)) - if err != nil { - return fmt.Errorf("policy contains an invalid JSON: %s", err) - } - d.Set("policy", policy) - - d.Set("route_table_ids", flattenStringList(vpce.RouteTableIds)) - - req := &ec2.DescribePrefixListsInput{} - req.Filters = buildEC2AttributeFilterList( - map[string]string{ - "prefix-list-name": serviceName, - }, - ) - resp, err := conn.DescribePrefixLists(req) - if err != nil { - return err - } - if resp != nil && len(resp.PrefixLists) > 0 { - if len(resp.PrefixLists) > 1 { - return fmt.Errorf("multiple prefix lists associated with the service name '%s'. Unexpected", serviceName) - } - - pl := resp.PrefixLists[0] - d.Set("prefix_list_id", pl.PrefixListId) - d.Set("cidr_blocks", flattenStringList(pl.Cidrs)) - } else { - d.Set("cidr_blocks", make([]string, 0)) - } - - d.Set("subnet_ids", flattenStringList(vpce.SubnetIds)) - d.Set("network_interface_ids", flattenStringList(vpce.NetworkInterfaceIds)) - - sgIds := make([]interface{}, 0, len(vpce.Groups)) - for _, group := range vpce.Groups { - sgIds = append(sgIds, aws.StringValue(group.GroupId)) - } - d.Set("security_group_ids", sgIds) - - d.Set("private_dns_enabled", vpce.PrivateDnsEnabled) - - dnsEntries := make([]interface{}, len(vpce.DnsEntries)) - for i, entry := range vpce.DnsEntries { - m := make(map[string]interface{}) - m["dns_name"] = aws.StringValue(entry.DnsName) - m["hosted_zone_id"] = aws.StringValue(entry.HostedZoneId) - dnsEntries[i] = m - } - d.Set("dns_entry", dnsEntries) - - return nil -} - func setVpcEndpointCreateList(d *schema.ResourceData, key string, c *[]*string) { if v, ok := d.GetOk(key); ok { list := v.(*schema.Set).List() @@ -459,3 +478,26 @@ func setVpcEndpointUpdateLists(d *schema.ResourceData, key string, a, r *[]*stri } } } + +func flattenVpcEndpointDnsEntries(dnsEntries []*ec2.DnsEntry) []interface{} { + vDnsEntries := []interface{}{} + + for _, dnsEntry := range dnsEntries { + vDnsEntries = append(vDnsEntries, map[string]interface{}{ + "dns_name": aws.StringValue(dnsEntry.DnsName), + "hosted_zone_id": aws.StringValue(dnsEntry.HostedZoneId), + }) + } + + return vDnsEntries +} + +func flattenVpcEndpointSecurityGroupIds(groups []*ec2.SecurityGroupIdentifier) *schema.Set { + vSecurityGroupIds := []interface{}{} + + for _, group := range groups { + vSecurityGroupIds = append(vSecurityGroupIds, aws.StringValue(group.GroupId)) + } + + return schema.NewSet(schema.HashString, vSecurityGroupIds) +} diff --git a/aws/resource_aws_vpc_endpoint_service.go b/aws/resource_aws_vpc_endpoint_service.go index 0fbaa8320529..83b728752f5d 100644 --- a/aws/resource_aws_vpc_endpoint_service.go +++ b/aws/resource_aws_vpc_endpoint_service.go @@ -27,13 +27,6 @@ func resourceAwsVpcEndpointService() *schema.Resource { Type: schema.TypeBool, Required: true, }, - "network_load_balancer_arns": { - Type: schema.TypeSet, - Required: true, - MinItems: 1, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, "allowed_principals": { Type: schema.TypeSet, Optional: true, @@ -41,34 +34,46 @@ func resourceAwsVpcEndpointService() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "state": { - Type: schema.TypeString, + "availability_zones": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, Computed: true, + Set: schema.HashString, }, - "service_name": { - Type: schema.TypeString, + "base_endpoint_dns_names": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, Computed: true, + Set: schema.HashString, }, - "service_type": { - Type: schema.TypeString, + "manages_vpc_endpoints": { + Type: schema.TypeBool, Computed: true, }, - "availability_zones": { + "network_load_balancer_arns": { Type: schema.TypeSet, + Required: true, + MinItems: 1, Elem: &schema.Schema{Type: schema.TypeString}, - Computed: true, Set: schema.HashString, }, "private_dns_name": { Type: schema.TypeString, Computed: true, }, - "base_endpoint_dns_names": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, + "service_name": { + Type: schema.TypeString, + Computed: true, + }, + "service_type": { + Type: schema.TypeString, Computed: true, - Set: schema.HashString, }, + "state": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tagsSchema(), }, } } @@ -99,9 +104,9 @@ func resourceAwsVpcEndpointServiceCreate(d *schema.ResourceData, meta interface{ func resourceAwsVpcEndpointServiceRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - svcCfg, state, err := vpcEndpointServiceStateRefresh(conn, d.Id())() + svcCfgRaw, state, err := vpcEndpointServiceStateRefresh(conn, d.Id())() if err != nil && state != ec2.ServiceStateFailed { - return fmt.Errorf("Error reading VPC Endpoint Service: %s", err.Error()) + return fmt.Errorf("error reading VPC Endpoint Service (%s): %s", d.Id(), err.Error()) } terminalStates := map[string]bool{ @@ -115,7 +120,43 @@ func resourceAwsVpcEndpointServiceRead(d *schema.ResourceData, meta interface{}) return nil } - return vpcEndpointServiceAttributes(d, svcCfg.(*ec2.ServiceConfiguration), conn) + svcCfg := svcCfgRaw.(*ec2.ServiceConfiguration) + d.Set("acceptance_required", svcCfg.AcceptanceRequired) + err = d.Set("network_load_balancer_arns", flattenStringSet(svcCfg.NetworkLoadBalancerArns)) + if err != nil { + return fmt.Errorf("error setting network_load_balancer_arns: %s", err) + } + err = d.Set("availability_zones", flattenStringSet(svcCfg.AvailabilityZones)) + if err != nil { + return fmt.Errorf("error setting availability_zones: %s", err) + } + err = d.Set("base_endpoint_dns_names", flattenStringSet(svcCfg.BaseEndpointDnsNames)) + if err != nil { + return fmt.Errorf("error setting base_endpoint_dns_names: %s", err) + } + d.Set("manages_vpc_endpoints", svcCfg.ManagesVpcEndpoints) + d.Set("private_dns_name", svcCfg.PrivateDnsName) + d.Set("service_name", svcCfg.ServiceName) + d.Set("service_type", svcCfg.ServiceType[0].ServiceType) + d.Set("state", svcCfg.ServiceState) + err = d.Set("tags", tagsToMap(svcCfg.Tags)) + if err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + + resp, err := conn.DescribeVpcEndpointServicePermissions(&ec2.DescribeVpcEndpointServicePermissionsInput{ + ServiceId: aws.String(d.Id()), + }) + if err != nil { + return fmt.Errorf("error reading VPC Endpoint Service permissions (%s): %s", d.Id(), err.Error()) + } + + err = d.Set("allowed_principals", flattenVpcEndpointServiceAllowedPrincipals(resp.AllowedPrincipals)) + if err != nil { + return fmt.Errorf("error setting allowed_principals: %s", err) + } + + return nil } func resourceAwsVpcEndpointServiceUpdate(d *schema.ResourceData, meta interface{}) error { @@ -161,6 +202,11 @@ func resourceAwsVpcEndpointServiceUpdate(d *schema.ResourceData, meta interface{ d.SetPartial("allowed_principals") } + if err := setTags(conn, d); err != nil { + return err + } + d.SetPartial("tags") + d.Partial(false) return resourceAwsVpcEndpointServiceRead(d, meta) } @@ -242,27 +288,6 @@ func waitForVpcEndpointServiceDeletion(conn *ec2.EC2, serviceID string) error { return err } -func vpcEndpointServiceAttributes(d *schema.ResourceData, svcCfg *ec2.ServiceConfiguration, conn *ec2.EC2) error { - d.Set("acceptance_required", svcCfg.AcceptanceRequired) - d.Set("network_load_balancer_arns", flattenStringList(svcCfg.NetworkLoadBalancerArns)) - d.Set("state", svcCfg.ServiceState) - d.Set("service_name", svcCfg.ServiceName) - d.Set("service_type", svcCfg.ServiceType[0].ServiceType) - d.Set("availability_zones", flattenStringList(svcCfg.AvailabilityZones)) - d.Set("private_dns_name", svcCfg.PrivateDnsName) - d.Set("base_endpoint_dns_names", flattenStringList(svcCfg.BaseEndpointDnsNames)) - - resp, err := conn.DescribeVpcEndpointServicePermissions(&ec2.DescribeVpcEndpointServicePermissionsInput{ - ServiceId: aws.String(d.Id()), - }) - if err != nil { - return err - } - d.Set("allowed_principals", flattenVpcEndpointServiceAllowedPrincipals(resp.AllowedPrincipals)) - - return nil -} - func setVpcEndpointServiceUpdateLists(d *schema.ResourceData, key string, a, r *[]*string) bool { if !d.HasChange(key) { return false @@ -284,3 +309,15 @@ func setVpcEndpointServiceUpdateLists(d *schema.ResourceData, key string, a, r * return true } + +func flattenVpcEndpointServiceAllowedPrincipals(allowedPrincipals []*ec2.AllowedPrincipal) *schema.Set { + vPrincipals := []interface{}{} + + for _, allowedPrincipal := range allowedPrincipals { + if allowedPrincipal.Principal != nil { + vPrincipals = append(vPrincipals, aws.StringValue(allowedPrincipal.Principal)) + } + } + + return schema.NewSet(schema.HashString, vPrincipals) +} diff --git a/aws/resource_aws_vpc_endpoint_service_test.go b/aws/resource_aws_vpc_endpoint_service_test.go index 595adbba1d4e..2f800280f52a 100644 --- a/aws/resource_aws_vpc_endpoint_service_test.go +++ b/aws/resource_aws_vpc_endpoint_service_test.go @@ -80,9 +80,11 @@ func testSweepEc2VpcEndpointServices(region string) error { return nil } -func TestAccAWSVpcEndpointService_importBasic(t *testing.T) { - lbName := fmt.Sprintf("testaccawsnlb-basic-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) - resourceName := "aws_vpc_endpoint_service.foo" +func TestAccAWSVpcEndpointService_basic(t *testing.T) { + var svcCfg ec2.ServiceConfiguration + resourceName := "aws_vpc_endpoint_service.test" + rName1 := fmt.Sprintf("tf-testacc-vpcesvc-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) + rName2 := fmt.Sprintf("tf-testacc-vpcesvc-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -90,9 +92,16 @@ func TestAccAWSVpcEndpointService_importBasic(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointServiceBasicConfig(lbName), + Config: testAccVpcEndpointServiceConfig_basic(rName1, rName2), + Check: resource.ComposeTestCheckFunc( + testAccCheckVpcEndpointServiceExists(resourceName, &svcCfg), + resource.TestCheckResourceAttr(resourceName, "acceptance_required", "false"), + resource.TestCheckResourceAttr(resourceName, "network_load_balancer_arns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "allowed_principals.#", "0"), + resource.TestCheckResourceAttr(resourceName, "manages_vpc_endpoints", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), }, - { ResourceName: resourceName, ImportState: true, @@ -102,33 +111,46 @@ func TestAccAWSVpcEndpointService_importBasic(t *testing.T) { }) } -func TestAccAWSVpcEndpointService_basic(t *testing.T) { +func TestAccAWSVpcEndpointService_AllowedPrincipalsAndTags(t *testing.T) { var svcCfg ec2.ServiceConfiguration - lb1Name := fmt.Sprintf("testaccawsnlb-basic-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) - lb2Name := fmt.Sprintf("testaccawsnlb-basic-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + resourceName := "aws_vpc_endpoint_service.test" + rName1 := fmt.Sprintf("tf-testacc-vpcesvc-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) + rName2 := fmt.Sprintf("tf-testacc-vpcesvc-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - IDRefreshName: "aws_vpc_endpoint_service.foo", - Providers: testAccProviders, - CheckDestroy: testAccCheckVpcEndpointServiceDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckVpcEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointServiceBasicConfig(lb1Name), + Config: testAccVpcEndpointServiceConfig_allowedPrincipalsAndTags(rName1, rName2), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointServiceExists("aws_vpc_endpoint_service.foo", &svcCfg), - resource.TestCheckResourceAttr("aws_vpc_endpoint_service.foo", "acceptance_required", "false"), - resource.TestCheckResourceAttr("aws_vpc_endpoint_service.foo", "network_load_balancer_arns.#", "1"), - resource.TestCheckResourceAttr("aws_vpc_endpoint_service.foo", "allowed_principals.#", "1"), + testAccCheckVpcEndpointServiceExists(resourceName, &svcCfg), + resource.TestCheckResourceAttr(resourceName, "acceptance_required", "false"), + resource.TestCheckResourceAttr(resourceName, "network_load_balancer_arns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "allowed_principals.#", "1"), + resource.TestCheckResourceAttr(resourceName, "manages_vpc_endpoints", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), + resource.TestCheckResourceAttr(resourceName, "tags.Environment", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.Usage", "original"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName1), ), }, { - Config: testAccVpcEndpointServiceModifiedConfig(lb1Name, lb2Name), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccVpcEndpointServiceConfig_allowedPrincipalsAndTagsUpdated(rName1, rName2), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointServiceExists("aws_vpc_endpoint_service.foo", &svcCfg), - resource.TestCheckResourceAttr("aws_vpc_endpoint_service.foo", "acceptance_required", "true"), - resource.TestCheckResourceAttr("aws_vpc_endpoint_service.foo", "network_load_balancer_arns.#", "2"), - resource.TestCheckResourceAttr("aws_vpc_endpoint_service.foo", "allowed_principals.#", "0"), + testAccCheckVpcEndpointServiceExists(resourceName, &svcCfg), + resource.TestCheckResourceAttr(resourceName, "acceptance_required", "true"), + resource.TestCheckResourceAttr(resourceName, "network_load_balancer_arns.#", "2"), + resource.TestCheckResourceAttr(resourceName, "allowed_principals.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.Usage", "changed"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName1), ), }, }, @@ -137,7 +159,9 @@ func TestAccAWSVpcEndpointService_basic(t *testing.T) { func TestAccAWSVpcEndpointService_removed(t *testing.T) { var svcCfg ec2.ServiceConfiguration - lbName := fmt.Sprintf("testaccawsnlb-basic-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) + resourceName := "aws_vpc_endpoint_service.test" + rName1 := fmt.Sprintf("tf-testacc-vpcesvc-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) + rName2 := fmt.Sprintf("tf-testacc-vpcesvc-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) testDestroy := func(*terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ec2conn @@ -155,9 +179,9 @@ func TestAccAWSVpcEndpointService_removed(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointServiceBasicConfig(lbName), + Config: testAccVpcEndpointServiceConfig_basic(rName1, rName2), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointServiceExists("aws_vpc_endpoint_service.foo", &svcCfg), + testAccCheckVpcEndpointServiceExists(resourceName, &svcCfg), testDestroy, ), ExpectNonEmptyPlan: true, @@ -223,23 +247,22 @@ func testAccCheckVpcEndpointServiceExists(n string, svcCfg *ec2.ServiceConfigura } } -func testAccVpcEndpointServiceBasicConfig(lb1Name string) string { - return fmt.Sprintf( - ` -resource "aws_vpc" "nlb_test" { +func testAccVpcEndpointServiceConfig_base(rName1, rName2 string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" tags = { - Name = "terraform-testacc-vpc-endpoint-service" + Name = %[1]q } } -resource "aws_lb" "nlb_test_1" { - name = "%s" +resource "aws_lb" "test1" { + name = %[1]q subnets = [ - "${aws_subnet.nlb_test_1.id}", - "${aws_subnet.nlb_test_2.id}", + "${aws_subnet.test1.id}", + "${aws_subnet.test2.id}", ] load_balancer_type = "network" @@ -248,124 +271,104 @@ resource "aws_lb" "nlb_test_1" { enable_deletion_protection = false tags = { - Name = "testAccVpcEndpointServiceBasicConfig_nlb1" + Name = %[1]q } } -resource "aws_subnet" "nlb_test_1" { - vpc_id = "${aws_vpc.nlb_test.id}" +resource "aws_lb" "test2" { + name = %[2]q + + subnets = [ + "${aws_subnet.test1.id}", + "${aws_subnet.test2.id}", + ] + + load_balancer_type = "network" + internal = true + idle_timeout = 60 + enable_deletion_protection = false + + tags = { + Name = %[2]q + } +} + +data "aws_availability_zones" "available" {} + +resource "aws_subnet" "test1" { + vpc_id = "${aws_vpc.test.id}" cidr_block = "10.0.1.0/24" - availability_zone = "us-west-2a" + availability_zone = "${data.aws_availability_zones.available.names[0]}" tags = { - Name = "tf-acc-vpc-endpoint-service-1" + Name = %[1]q } } -resource "aws_subnet" "nlb_test_2" { - vpc_id = "${aws_vpc.nlb_test.id}" +resource "aws_subnet" "test2" { + vpc_id = "${aws_vpc.test.id}" cidr_block = "10.0.2.0/24" - availability_zone = "us-west-2b" + availability_zone = "${data.aws_availability_zones.available.names[1]}" tags = { - Name = "tf-acc-vpc-endpoint-service-2" + Name = %[1]q } } data "aws_caller_identity" "current" {} +`, rName1, rName2) +} -resource "aws_vpc_endpoint_service" "foo" { +func testAccVpcEndpointServiceConfig_basic(rName1, rName2 string) string { + return testAccVpcEndpointServiceConfig_base(rName1, rName2) + fmt.Sprintf(` +resource "aws_vpc_endpoint_service" "test" { acceptance_required = false network_load_balancer_arns = [ - "${aws_lb.nlb_test_1.id}", - ] - - allowed_principals = [ - "${data.aws_caller_identity.current.arn}" + "${aws_lb.test1.arn}", ] } -`, lb1Name) +`) } -func testAccVpcEndpointServiceModifiedConfig(lb1Name, lb2Name string) string { - return fmt.Sprintf( - ` -resource "aws_vpc" "nlb_test" { - cidr_block = "10.0.0.0/16" - - tags = { - Name = "terraform-testacc-vpc-endpoint-service" - } -} - -resource "aws_lb" "nlb_test_1" { - name = "%s" +func testAccVpcEndpointServiceConfig_allowedPrincipalsAndTags(rName1, rName2 string) string { + return testAccVpcEndpointServiceConfig_base(rName1, rName2) + fmt.Sprintf(` +resource "aws_vpc_endpoint_service" "test" { + acceptance_required = false - subnets = [ - "${aws_subnet.nlb_test_1.id}", - "${aws_subnet.nlb_test_2.id}", + network_load_balancer_arns = [ + "${aws_lb.test1.arn}", ] - load_balancer_type = "network" - internal = true - idle_timeout = 60 - enable_deletion_protection = false - - tags = { - Name = "testAccVpcEndpointServiceBasicConfig_nlb1" - } -} - -resource "aws_lb" "nlb_test_2" { - name = "%s" - - subnets = [ - "${aws_subnet.nlb_test_1.id}", - "${aws_subnet.nlb_test_2.id}", - ] - - load_balancer_type = "network" - internal = true - idle_timeout = 60 - enable_deletion_protection = false - - tags = { - Name = "testAccVpcEndpointServiceBasicConfig_nlb2" - } - } - -resource "aws_subnet" "nlb_test_1" { - vpc_id = "${aws_vpc.nlb_test.id}" - cidr_block = "10.0.1.0/24" - availability_zone = "us-west-2a" + allowed_principals = [ + "${data.aws_caller_identity.current.arn}", + ] tags = { - Name = "tf-acc-vpc-endpoint-service-1" + Environment = "test" + Usage = "original" + Name = %[1]q } } - -resource "aws_subnet" "nlb_test_2" { - vpc_id = "${aws_vpc.nlb_test.id}" - cidr_block = "10.0.2.0/24" - availability_zone = "us-west-2b" - - tags = { - Name = "tf-acc-vpc-endpoint-service-2" - } +`, rName1) } -data "aws_caller_identity" "current" {} - -resource "aws_vpc_endpoint_service" "foo" { +func testAccVpcEndpointServiceConfig_allowedPrincipalsAndTagsUpdated(rName1, rName2 string) string { + return testAccVpcEndpointServiceConfig_base(rName1, rName2) + fmt.Sprintf(` +resource "aws_vpc_endpoint_service" "test" { acceptance_required = true network_load_balancer_arns = [ - "${aws_lb.nlb_test_1.id}", - "${aws_lb.nlb_test_2.id}", + "${aws_lb.test1.arn}", + "${aws_lb.test2.arn}", ] allowed_principals = [] + + tags = { + Usage = "changed" + Name = %[1]q + } } -`, lb1Name, lb2Name) +`, rName1) } diff --git a/aws/resource_aws_vpc_endpoint_test.go b/aws/resource_aws_vpc_endpoint_test.go index 60460d456a5e..01bb046cd27d 100644 --- a/aws/resource_aws_vpc_endpoint_test.go +++ b/aws/resource_aws_vpc_endpoint_test.go @@ -81,8 +81,10 @@ func testSweepEc2VpcEndpoints(region string) error { return nil } -func TestAccAWSVpcEndpoint_importBasic(t *testing.T) { - resourceName := "aws_vpc_endpoint.s3" +func TestAccAWSVpcEndpoint_gatewayBasic(t *testing.T) { + var endpoint ec2.VpcEndpoint + resourceName := "aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -90,85 +92,86 @@ func TestAccAWSVpcEndpoint_importBasic(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicy, - }, - - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAWSVpcEndpoint_gatewayBasic(t *testing.T) { - var endpoint ec2.VpcEndpoint - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - IDRefreshName: "aws_vpc_endpoint.s3", - Providers: testAccProviders, - CheckDestroy: testAccCheckVpcEndpointDestroy, - Steps: []resource.TestStep{ - { - Config: testAccVpcEndpointConfig_gatewayWithoutRouteTableOrPolicy, + Config: testAccVpcEndpointConfig_gatewayWithoutRouteTableOrPolicyOrTags(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointExists("aws_vpc_endpoint.s3", &endpoint), - testAccCheckVpcEndpointPrefixListAvailable("aws_vpc_endpoint.s3"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "vpc_endpoint_type", "Gateway"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "route_table_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "subnet_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "network_interface_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "security_group_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "private_dns_enabled", "false"), + testAccCheckVpcEndpointExists(resourceName, &endpoint), + testAccCheckVpcEndpointPrefixListAvailable(resourceName), + resource.TestCheckResourceAttr(resourceName, "vpc_endpoint_type", "Gateway"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + testAccCheckResourceAttrAccountID(resourceName, "owner_id"), ), }, }, }) } -func TestAccAWSVpcEndpoint_gatewayWithRouteTableAndPolicy(t *testing.T) { +func TestAccAWSVpcEndpoint_gatewayWithRouteTableAndPolicyAndTags(t *testing.T) { var endpoint ec2.VpcEndpoint var routeTable ec2.RouteTable + resourceName := "aws_vpc_endpoint.test" + resourceNameRt := "aws_route_table.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - IDRefreshName: "aws_vpc_endpoint.s3", - Providers: testAccProviders, - CheckDestroy: testAccCheckVpcEndpointDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckVpcEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicy, + Config: testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicyAndTags(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointExists("aws_vpc_endpoint.s3", &endpoint), - testAccCheckRouteTableExists("aws_route_table.default", &routeTable), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "vpc_endpoint_type", "Gateway"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "route_table_ids.#", "1"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "subnet_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "network_interface_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "security_group_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "private_dns_enabled", "false"), + testAccCheckVpcEndpointExists(resourceName, &endpoint), + testAccCheckRouteTableExists(resourceNameRt, &routeTable), + testAccCheckVpcEndpointPrefixListAvailable(resourceName), + resource.TestCheckResourceAttr(resourceName, "vpc_endpoint_type", "Gateway"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), + resource.TestCheckResourceAttr(resourceName, "tags.Environment", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.Usage", "original"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + testAccCheckResourceAttrAccountID(resourceName, "owner_id"), ), }, { - Config: testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicyModified, + Config: testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicyAndTagsModified(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointExists("aws_vpc_endpoint.s3", &endpoint), - testAccCheckRouteTableExists("aws_route_table.default", &routeTable), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "vpc_endpoint_type", "Gateway"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "route_table_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "subnet_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "network_interface_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "security_group_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.s3", "private_dns_enabled", "false"), + testAccCheckVpcEndpointExists(resourceName, &endpoint), + testAccCheckRouteTableExists(resourceNameRt, &routeTable), + testAccCheckVpcEndpointPrefixListAvailable(resourceName), + resource.TestCheckResourceAttr(resourceName, "vpc_endpoint_type", "Gateway"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.Usage", "changed"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + testAccCheckResourceAttrAccountID(resourceName, "owner_id"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAWSVpcEndpoint_Gateway_Policy(t *testing.T) { +func TestAccAWSVpcEndpoint_gatewayPolicy(t *testing.T) { var endpoint ec2.VpcEndpoint // This policy checks the DiffSuppressFunc policy1 := ` @@ -202,6 +205,7 @@ func TestAccAWSVpcEndpoint_Gateway_Policy(t *testing.T) { } ` resourceName := "aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -209,7 +213,7 @@ func TestAccAWSVpcEndpoint_Gateway_Policy(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointConfigGatewayPolicy(policy1), + Config: testAccVpcEndpointConfigGatewayPolicy(rName, policy1), Check: resource.ComposeTestCheckFunc( testAccCheckVpcEndpointExists(resourceName, &endpoint), ), @@ -220,7 +224,7 @@ func TestAccAWSVpcEndpoint_Gateway_Policy(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccVpcEndpointConfigGatewayPolicy(policy2), + Config: testAccVpcEndpointConfigGatewayPolicy(rName, policy2), Check: resource.ComposeTestCheckFunc( testAccCheckVpcEndpointExists(resourceName, &endpoint), ), @@ -231,24 +235,29 @@ func TestAccAWSVpcEndpoint_Gateway_Policy(t *testing.T) { func TestAccAWSVpcEndpoint_interfaceBasic(t *testing.T) { var endpoint ec2.VpcEndpoint + resourceName := "aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - IDRefreshName: "aws_vpc_endpoint.ec2", - Providers: testAccProviders, - CheckDestroy: testAccCheckVpcEndpointDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckVpcEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointConfig_interfaceWithoutSubnet, + Config: testAccVpcEndpointConfig_interfaceWithoutSubnet(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointExists("aws_vpc_endpoint.ec2", &endpoint), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "cidr_blocks.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "vpc_endpoint_type", "Interface"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "route_table_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "subnet_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "network_interface_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "security_group_ids.#", "1"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "private_dns_enabled", "false"), + testAccCheckVpcEndpointExists(resourceName, &endpoint), + resource.TestCheckNoResourceAttr(resourceName, "prefix_list_id"), + resource.TestCheckResourceAttr(resourceName, "cidr_blocks.#", "0"), + resource.TestCheckResourceAttr(resourceName, "vpc_endpoint_type", "Interface"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + testAccCheckResourceAttrAccountID(resourceName, "owner_id"), ), }, }, @@ -257,68 +266,95 @@ func TestAccAWSVpcEndpoint_interfaceBasic(t *testing.T) { func TestAccAWSVpcEndpoint_interfaceWithSubnetAndSecurityGroup(t *testing.T) { var endpoint ec2.VpcEndpoint + resourceName := "aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - IDRefreshName: "aws_vpc_endpoint.ec2", - Providers: testAccProviders, - CheckDestroy: testAccCheckVpcEndpointDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckVpcEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointConfig_interfaceWithSubnet, + Config: testAccVpcEndpointConfig_interfaceWithSubnet(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointExists("aws_vpc_endpoint.ec2", &endpoint), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "cidr_blocks.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "vpc_endpoint_type", "Interface"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "route_table_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "subnet_ids.#", "1"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "security_group_ids.#", "2"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "private_dns_enabled", "false"), + testAccCheckVpcEndpointExists(resourceName, &endpoint), + resource.TestCheckNoResourceAttr(resourceName, "prefix_list_id"), + resource.TestCheckResourceAttr(resourceName, "cidr_blocks.#", "0"), + resource.TestCheckResourceAttr(resourceName, "vpc_endpoint_type", "Interface"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "2"), + resource.TestCheckResourceAttr(resourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + testAccCheckResourceAttrAccountID(resourceName, "owner_id"), ), }, { - Config: testAccVpcEndpointConfig_interfaceWithSubnetModified, + Config: testAccVpcEndpointConfig_interfaceWithSubnetModified(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointExists("aws_vpc_endpoint.ec2", &endpoint), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "cidr_blocks.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "vpc_endpoint_type", "Interface"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "route_table_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "subnet_ids.#", "3"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "security_group_ids.#", "1"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.ec2", "private_dns_enabled", "true"), + testAccCheckVpcEndpointExists(resourceName, &endpoint), + resource.TestCheckNoResourceAttr(resourceName, "prefix_list_id"), + resource.TestCheckResourceAttr(resourceName, "cidr_blocks.#", "0"), + resource.TestCheckResourceAttr(resourceName, "vpc_endpoint_type", "Interface"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "3"), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "private_dns_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + testAccCheckResourceAttrAccountID(resourceName, "owner_id"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } func TestAccAWSVpcEndpoint_interfaceNonAWSService(t *testing.T) { - lbName := fmt.Sprintf("testaccawsnlb-basic-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) var endpoint ec2.VpcEndpoint + resourceName := "aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - IDRefreshName: "aws_vpc_endpoint.foo", - Providers: testAccProviders, - CheckDestroy: testAccCheckVpcEndpointDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckVpcEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointConfig_interfaceNonAWSService(lbName), + Config: testAccVpcEndpointConfig_interfaceNonAWSService(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointExists("aws_vpc_endpoint.foo", &endpoint), - resource.TestCheckResourceAttr("aws_vpc_endpoint.foo", "vpc_endpoint_type", "Interface"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.foo", "subnet_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.foo", "network_interface_ids.#", "0"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.foo", "security_group_ids.#", "1"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.foo", "private_dns_enabled", "false"), - resource.TestCheckResourceAttr("aws_vpc_endpoint.foo", "state", "available"), + testAccCheckVpcEndpointExists(resourceName, &endpoint), + resource.TestCheckNoResourceAttr(resourceName, "prefix_list_id"), + resource.TestCheckResourceAttr(resourceName, "cidr_blocks.#", "0"), + resource.TestCheckResourceAttr(resourceName, "vpc_endpoint_type", "Interface"), + resource.TestCheckResourceAttr(resourceName, "route_table_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "subnet_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "network_interface_ids.#", "0"), + resource.TestCheckResourceAttr(resourceName, "security_group_ids.#", "1"), + resource.TestCheckResourceAttr(resourceName, "private_dns_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "requester_managed", "false"), + resource.TestCheckResourceAttr(resourceName, "state", "available"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + testAccCheckResourceAttrAccountID(resourceName, "owner_id"), ), }, }, }) } + func TestAccAWSVpcEndpoint_removed(t *testing.T) { var endpoint ec2.VpcEndpoint + resourceName := "aws_vpc_endpoint.test" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) // reach out and DELETE the VPC Endpoint outside of Terraform testDestroy := func(*terraform.State) error { @@ -338,9 +374,9 @@ func TestAccAWSVpcEndpoint_removed(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointConfig_gatewayWithoutRouteTableOrPolicy, + Config: testAccVpcEndpointConfig_gatewayWithoutRouteTableOrPolicyOrTags(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointExists("aws_vpc_endpoint.s3", &endpoint), + testAccCheckVpcEndpointExists(resourceName, &endpoint), testDestroy, ), ExpectNonEmptyPlan: true, @@ -439,28 +475,54 @@ func testAccCheckVpcEndpointPrefixListAvailable(n string) resource.TestCheckFunc } } -const testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicy = ` -resource "aws_vpc" "foo" { +func testAccVpcEndpointConfig_gatewayWithoutRouteTableOrPolicyOrTags(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} + +data "aws_region" "current" {} + +resource "aws_vpc_endpoint" "test" { + vpc_id = "${aws_vpc.test.id}" + service_name = "com.amazonaws.${data.aws_region.current.name}.s3" +} +`, rName) +} + +func testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicyAndTags(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" + tags = { - Name = "terraform-testacc-vpc-endpoint-gw-w-route-table-and-policy" + Name = %[1]q } } -resource "aws_subnet" "foo" { - vpc_id = "${aws_vpc.foo.id}" +resource "aws_subnet" "test" { + vpc_id = "${aws_vpc.test.id}" cidr_block = "10.0.1.0/24" + tags = { - Name = "tf-acc-vpc-endpoint-gw-w-route-table-and-policy" + Name = %[1]q } } data "aws_region" "current" {} -resource "aws_vpc_endpoint" "s3" { - vpc_id = "${aws_vpc.foo.id}" +resource "aws_vpc_endpoint" "test" { + vpc_id = "${aws_vpc.test.id}" service_name = "com.amazonaws.${data.aws_region.current.name}.s3" - route_table_ids = ["${aws_route_table.default.id}"] + + route_table_ids = [ + "${aws_route_table.test.id}", + ] + policy = <