diff --git a/aws/data_source_aws_vpc_endpoint.go b/aws/data_source_aws_vpc_endpoint.go index 2669ceb8e0e..c8fc0acc0be 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 { @@ -19,51 +20,65 @@ func dataSourceAwsVpcEndpoint() *schema.Resource { Optional: true, Computed: true, }, - "vpc_id": { + "service_name": { Type: schema.TypeString, Optional: true, Computed: true, }, - "service_name": { + "state": { Type: schema.TypeString, Optional: true, Computed: true, }, - "state": { + "vpc_id": { Type: schema.TypeString, Optional: true, Computed: true, }, - "vpc_endpoint_type": { - Type: schema.TypeString, + "cidr_blocks": { + Type: schema.TypeList, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, - "policy": { - 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, + }, + }, + }, }, - "route_table_ids": { + "network_interface_ids": { Type: schema.TypeSet, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, "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": { - Type: schema.TypeSet, + "requester_managed": { + Type: schema.TypeBool, Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, - "network_interface_ids": { + "route_table_ids": { Type: schema.TypeSet, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, @@ -75,25 +90,15 @@ func dataSourceAwsVpcEndpoint() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "private_dns_enabled": { - Type: schema.TypeBool, + "subnet_ids": { + Type: schema.TypeSet, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, }, - "dns_entry": { - Type: schema.TypeList, + "vpc_endpoint_type": { + Type: schema.TypeString, 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 +126,80 @@ 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) + } + 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) + } + // 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 b4eaa5e7dd9..fcbcef7b658 100644 --- a/aws/data_source_aws_vpc_endpoint_service.go +++ b/aws/data_source_aws_vpc_endpoint_service.go @@ -27,37 +27,41 @@ func dataSourceAwsVpcEndpointService() *schema.Resource { Computed: true, ConflictsWith: []string{"service"}, }, - "service_type": { - Type: schema.TypeString, + "acceptance_required": { + Type: schema.TypeBool, Computed: true, }, - "owner": { - Type: schema.TypeString, + "availability_zones": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, Computed: true, + Set: schema.HashString, }, - "vpc_endpoint_policy_supported": { - Type: schema.TypeBool, + "base_endpoint_dns_names": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, Computed: true, + Set: schema.HashString, }, - "acceptance_required": { + "manages_vpc_endpoints": { Type: schema.TypeBool, Computed: true, }, - "availability_zones": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, + "owner": { + 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_type": { + Type: schema.TypeString, + Computed: true, + }, + "vpc_endpoint_policy_supported": { + Type: schema.TypeBool, Computed: true, - Set: schema.HashString, }, }, } @@ -80,10 +84,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 +118,20 @@ 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_type", sd.ServiceType[0].ServiceType) + 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 1b99c812943..22b42ae7d81 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,8 @@ import ( ) func TestAccDataSourceAwsVpcEndpointService_gateway(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint_service.s3" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -17,32 +18,20 @@ 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", "com.amazonaws.us-west-2.s3"), + resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "false"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.#", "4"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.2487133097", "us-west-2a"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.221770259", "us-west-2b"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.2050015877", "us-west-2c"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.3830732582", "us-west-2d"), + resource.TestCheckResourceAttr(datasourceName, "base_endpoint_dns_names.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "base_endpoint_dns_names.3003388505", "s3.us-west-2.amazonaws.com"), + 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"), ), }, }, @@ -50,6 +39,8 @@ func TestAccDataSourceAwsVpcEndpointService_gateway(t *testing.T) { } func TestAccDataSourceAwsVpcEndpointService_interface(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint_service.ec2" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -57,30 +48,19 @@ 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", "com.amazonaws.us-west-2.ec2"), + resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "false"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.#", "3"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.2487133097", "us-west-2a"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.221770259", "us-west-2b"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.2050015877", "us-west-2c"), + resource.TestCheckResourceAttr(datasourceName, "base_endpoint_dns_names.#", "1"), + resource.TestCheckResourceAttr(datasourceName, "base_endpoint_dns_names.1880016359", "ec2.us-west-2.vpce.amazonaws.com"), + resource.TestCheckResourceAttr(datasourceName, "manages_vpc_endpoints", "false"), + resource.TestCheckResourceAttr(datasourceName, "owner", "amazon"), + resource.TestCheckResourceAttr(datasourceName, "private_dns_name", "ec2.us-west-2.amazonaws.com"), + resource.TestCheckResourceAttr(datasourceName, "service_type", "Interface"), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "false"), ), }, }, @@ -88,29 +68,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.foo" + 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, "availability_zones.2487133097", "us-west-2a"), + resource.TestCheckResourceAttr(datasourceName, "availability_zones.221770259", "us-west-2b"), + resource.TestCheckResourceAttr(datasourceName, "manages_vpc_endpoints", "false"), + testAccCheckResourceAttrAccountID(datasourceName, "owner"), + resource.TestCheckResourceAttr(datasourceName, "service_type", "Interface"), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "false"), ), }, }, @@ -137,19 +112,19 @@ data "aws_vpc_endpoint_service" "ec2" { } ` -func testAccDataSourceAwsVpcEndpointServiceCustomConfig(lbName string) string { +func testAccDataSourceAwsVpcEndpointServiceCustomConfig(rName string) string { return fmt.Sprintf( ` resource "aws_vpc" "nlb_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" + name = %[1]q subnets = [ "${aws_subnet.nlb_test_1.id}", @@ -162,7 +137,7 @@ resource "aws_lb" "nlb_test_1" { enable_deletion_protection = false tags = { - Name = "testAccVpcEndpointServiceBasicConfig_nlb1" + Name = %[1]q } } @@ -172,7 +147,7 @@ resource "aws_subnet" "nlb_test_1" { availability_zone = "us-west-2a" tags = { - Name = "tf-acc-vpc-endpoint-service-custom" + Name = %[1]q } } @@ -182,7 +157,7 @@ resource "aws_subnet" "nlb_test_2" { availability_zone = "us-west-2b" tags = { - Name = "tf-acc-vpc-endpoint-service-custom" + Name = %[1]q } } @@ -197,5 +172,5 @@ resource "aws_vpc_endpoint_service" "foo" { data "aws_vpc_endpoint_service" "foo" { service_name = "${aws_vpc_endpoint_service.foo.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 532564e019d..bd8faca3a0a 100644 --- a/aws/data_source_aws_vpc_endpoint_test.go +++ b/aws/data_source_aws_vpc_endpoint_test.go @@ -1,14 +1,14 @@ package aws import ( - "fmt" "testing" "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" ) func TestAccDataSourceAwsVpcEndpoint_gatewayBasic(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint.s3" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -16,15 +16,15 @@ func TestAccDataSourceAwsVpcEndpoint_gatewayBasic(t *testing.T) { { Config: testAccDataSourceAwsVpcEndpointConfig_gatewayBasic, 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"), ), }, }, @@ -32,6 +32,8 @@ func TestAccDataSourceAwsVpcEndpoint_gatewayBasic(t *testing.T) { } func TestAccDataSourceAwsVpcEndpoint_byId(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint.s3" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -39,7 +41,15 @@ func TestAccDataSourceAwsVpcEndpoint_byId(t *testing.T) { { Config: testAccDataSourceAwsVpcEndpointConfig_byId, 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"), ), }, }, @@ -47,6 +57,8 @@ func TestAccDataSourceAwsVpcEndpoint_byId(t *testing.T) { } func TestAccDataSourceAwsVpcEndpoint_gatewayWithRouteTable(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint.s3" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -54,11 +66,15 @@ func TestAccDataSourceAwsVpcEndpoint_gatewayWithRouteTable(t *testing.T) { { Config: testAccDataSourceAwsVpcEndpointConfig_gatewayWithRouteTable, 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"), ), }, }, @@ -66,6 +82,8 @@ func TestAccDataSourceAwsVpcEndpoint_gatewayWithRouteTable(t *testing.T) { } func TestAccDataSourceAwsVpcEndpoint_interface(t *testing.T) { + datasourceName := "data.aws_vpc_endpoint.ec2" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -73,47 +91,21 @@ func TestAccDataSourceAwsVpcEndpoint_interface(t *testing.T) { { Config: testAccDataSourceAwsVpcEndpointConfig_interface, 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"), ), }, }, }) } -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) - } - - attr := rs.Primary.Attributes - - if attr["id"] != vpceRs.Primary.Attributes["id"] { - return fmt.Errorf( - "id is %s; want %s", - attr["id"], - vpceRs.Primary.Attributes["id"], - ) - } - - return nil - } -} - const testAccDataSourceAwsVpcEndpointConfig_gatewayBasic = ` provider "aws" { region = "us-west-2" @@ -157,7 +149,7 @@ resource "aws_vpc_endpoint" "s3" { service_name = "com.amazonaws.us-west-2.s3" } -data "aws_vpc_endpoint" "by_id" { +data "aws_vpc_endpoint" "s3" { id = "${aws_vpc_endpoint.s3.id}" } ` diff --git a/aws/resource_aws_vpc_endpoint.go b/aws/resource_aws_vpc_endpoint.go index aa5c4ec36c5..c522f314b71 100644 --- a/aws/resource_aws_vpc_endpoint.go +++ b/aws/resource_aws_vpc_endpoint.go @@ -25,26 +25,20 @@ func resourceAwsVpcEndpoint() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "vpc_id": { + "service_name": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "vpc_endpoint_type": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Default: ec2.VpcEndpointTypeGateway, - ValidateFunc: validation.StringInSlice([]string{ - ec2.VpcEndpointTypeGateway, - ec2.VpcEndpointTypeInterface, - }, false), - }, - "service_name": { + "vpc_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, + "auto_accept": { + Type: schema.TypeBool, + Optional: true, + }, "policy": { Type: schema.TypeString, Optional: true, @@ -56,6 +50,11 @@ func resourceAwsVpcEndpoint() *schema.Resource { return json }, }, + "private_dns_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "route_table_ids": { Type: schema.TypeSet, Optional: true, @@ -63,44 +62,35 @@ func resourceAwsVpcEndpoint() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "subnet_ids": { + "security_group_ids": { Type: schema.TypeSet, Optional: true, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "security_group_ids": { + "subnet_ids": { Type: schema.TypeSet, Optional: true, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, }, - "private_dns_enabled": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "state": { - Type: schema.TypeString, - Computed: true, - }, - "prefix_list_id": { + "vpc_endpoint_type": { Type: schema.TypeString, - Computed: true, + Optional: true, + ForceNew: true, + Default: ec2.VpcEndpointTypeGateway, + ValidateFunc: validation.StringInSlice([]string{ + ec2.VpcEndpointTypeGateway, + ec2.VpcEndpointTypeInterface, + }, false), }, "cidr_blocks": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "network_interface_ids": { - Type: schema.TypeSet, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, "dns_entry": { Type: schema.TypeList, Computed: true, @@ -117,9 +107,23 @@ func resourceAwsVpcEndpoint() *schema.Resource { }, }, }, - "auto_accept": { + "network_interface_ids": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "prefix_list_id": { + Type: schema.TypeString, + Computed: true, + }, + "requester_managed": { Type: schema.TypeBool, - Optional: true, + Computed: true, + }, + "state": { + Type: schema.TypeString, + Computed: true, }, }, @@ -183,9 +187,9 @@ func resourceAwsVpcEndpointCreate(d *schema.ResourceData, meta interface{}) erro 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 +205,70 @@ 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) + } + 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) + } + // 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 { @@ -367,72 +434,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 +460,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 0fbaa832052..e9546f90d21 100644 --- a/aws/resource_aws_vpc_endpoint_service.go +++ b/aws/resource_aws_vpc_endpoint_service.go @@ -41,33 +41,37 @@ 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": { + "manages_vpc_endpoints": { + Type: schema.TypeBool, + Computed: true, + }, + "private_dns_name": { Type: schema.TypeString, Computed: true, }, - "availability_zones": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, + "service_name": { + Type: schema.TypeString, Computed: true, - Set: schema.HashString, }, - "private_dns_name": { + "service_type": { Type: schema.TypeString, Computed: true, }, - "base_endpoint_dns_names": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, + "state": { + Type: schema.TypeString, Computed: true, - Set: schema.HashString, }, }, } @@ -99,9 +103,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 +119,39 @@ 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) + + 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 { @@ -242,27 +278,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 +299,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 595adbba1d4..d1ccfb06f0f 100644 --- a/aws/resource_aws_vpc_endpoint_service_test.go +++ b/aws/resource_aws_vpc_endpoint_service_test.go @@ -80,32 +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" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckVpcEndpointServiceDestroy, - Steps: []resource.TestStep{ - { - Config: testAccVpcEndpointServiceBasicConfig(lbName), - }, - - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - func TestAccAWSVpcEndpointService_basic(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.foo" + 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) }, @@ -114,21 +93,27 @@ func TestAccAWSVpcEndpointService_basic(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointServiceBasicConfig(lb1Name), + Config: testAccVpcEndpointServiceBasicConfig(rName1), 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"), ), }, { - Config: testAccVpcEndpointServiceModifiedConfig(lb1Name, lb2Name), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccVpcEndpointServiceModifiedConfig(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"), + resource.TestCheckResourceAttr(resourceName, "acceptance_required", "true"), + resource.TestCheckResourceAttr(resourceName, "network_load_balancer_arns.#", "2"), + resource.TestCheckResourceAttr(resourceName, "allowed_principals.#", "0"), ), }, }, @@ -137,7 +122,8 @@ 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.foo" + rName := fmt.Sprintf("tf-testacc-vpcesvc-%s", acctest.RandStringFromCharSet(13, acctest.CharSetAlphaNum)) testDestroy := func(*terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ec2conn @@ -155,9 +141,9 @@ func TestAccAWSVpcEndpointService_removed(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointServiceBasicConfig(lbName), + Config: testAccVpcEndpointServiceBasicConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointServiceExists("aws_vpc_endpoint_service.foo", &svcCfg), + testAccCheckVpcEndpointServiceExists(resourceName, &svcCfg), testDestroy, ), ExpectNonEmptyPlan: true, @@ -223,19 +209,19 @@ func testAccCheckVpcEndpointServiceExists(n string, svcCfg *ec2.ServiceConfigura } } -func testAccVpcEndpointServiceBasicConfig(lb1Name string) string { +func testAccVpcEndpointServiceBasicConfig(rName string) string { return fmt.Sprintf( ` resource "aws_vpc" "nlb_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" + name = %[1]q subnets = [ "${aws_subnet.nlb_test_1.id}", @@ -248,7 +234,7 @@ resource "aws_lb" "nlb_test_1" { enable_deletion_protection = false tags = { - Name = "testAccVpcEndpointServiceBasicConfig_nlb1" + Name = %[1]q } } @@ -258,7 +244,7 @@ resource "aws_subnet" "nlb_test_1" { availability_zone = "us-west-2a" tags = { - Name = "tf-acc-vpc-endpoint-service-1" + Name = %[1]q } } @@ -268,7 +254,7 @@ resource "aws_subnet" "nlb_test_2" { availability_zone = "us-west-2b" tags = { - Name = "tf-acc-vpc-endpoint-service-2" + Name = %[1]q } } @@ -285,22 +271,22 @@ resource "aws_vpc_endpoint_service" "foo" { "${data.aws_caller_identity.current.arn}" ] } -`, lb1Name) +`, rName) } -func testAccVpcEndpointServiceModifiedConfig(lb1Name, lb2Name string) string { +func testAccVpcEndpointServiceModifiedConfig(rName1, rName2 string) string { return fmt.Sprintf( ` resource "aws_vpc" "nlb_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" + name = %[1]q subnets = [ "${aws_subnet.nlb_test_1.id}", @@ -313,27 +299,27 @@ resource "aws_lb" "nlb_test_1" { enable_deletion_protection = false tags = { - Name = "testAccVpcEndpointServiceBasicConfig_nlb1" + Name = %[1]q } } resource "aws_lb" "nlb_test_2" { - name = "%s" + name = %[2]q - subnets = [ - "${aws_subnet.nlb_test_1.id}", - "${aws_subnet.nlb_test_2.id}", - ] + 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 + load_balancer_type = "network" + internal = true + idle_timeout = 60 + enable_deletion_protection = false - tags = { - Name = "testAccVpcEndpointServiceBasicConfig_nlb2" - } + tags = { + Name = %[2]q } +} resource "aws_subnet" "nlb_test_1" { vpc_id = "${aws_vpc.nlb_test.id}" @@ -341,7 +327,7 @@ resource "aws_subnet" "nlb_test_1" { availability_zone = "us-west-2a" tags = { - Name = "tf-acc-vpc-endpoint-service-1" + Name = %[1]q } } @@ -351,7 +337,7 @@ resource "aws_subnet" "nlb_test_2" { availability_zone = "us-west-2b" tags = { - Name = "tf-acc-vpc-endpoint-service-2" + Name = %[1]q } } @@ -361,11 +347,11 @@ resource "aws_vpc_endpoint_service" "foo" { acceptance_required = true network_load_balancer_arns = [ - "${aws_lb.nlb_test_1.id}", - "${aws_lb.nlb_test_2.id}", + "${aws_lb.nlb_test_1.id}", + "${aws_lb.nlb_test_2.id}", ] allowed_principals = [] } -`, lb1Name, lb2Name) +`, rName1, rName2) } diff --git a/aws/resource_aws_vpc_endpoint_test.go b/aws/resource_aws_vpc_endpoint_test.go index 60460d456a5..65a1f321cfc 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) { +func TestAccAWSVpcEndpoint_gatewayBasic(t *testing.T) { + var endpoint ec2.VpcEndpoint resourceName := "aws_vpc_endpoint.s3" + rName := fmt.Sprintf("tf-testacc-vpce-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -90,38 +92,17 @@ 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_gatewayWithoutRouteTableOrPolicy(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"), ), }, }, @@ -131,44 +112,55 @@ func TestAccAWSVpcEndpoint_gatewayBasic(t *testing.T) { func TestAccAWSVpcEndpoint_gatewayWithRouteTableAndPolicy(t *testing.T) { var endpoint ec2.VpcEndpoint var routeTable ec2.RouteTable + resourceName := "aws_vpc_endpoint.s3" + resourceNameRt := "aws_route_table.default" + 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_gatewayWithRouteTableAndPolicy(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"), ), }, { - Config: testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicyModified, + Config: testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicyModified(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"), ), }, + { + 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 +194,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 +202,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 +213,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 +224,27 @@ func TestAccAWSVpcEndpoint_Gateway_Policy(t *testing.T) { func TestAccAWSVpcEndpoint_interfaceBasic(t *testing.T) { var endpoint ec2.VpcEndpoint + resourceName := "aws_vpc_endpoint.ec2" + 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"), ), }, }, @@ -257,68 +253,87 @@ func TestAccAWSVpcEndpoint_interfaceBasic(t *testing.T) { func TestAccAWSVpcEndpoint_interfaceWithSubnetAndSecurityGroup(t *testing.T) { var endpoint ec2.VpcEndpoint + resourceName := "aws_vpc_endpoint.ec2" + 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"), ), }, { - 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"), ), }, + { + 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.foo" + 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"), ), }, }, }) } + func TestAccAWSVpcEndpoint_removed(t *testing.T) { var endpoint ec2.VpcEndpoint + resourceName := "aws_vpc_endpoint.s3" + 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 +353,9 @@ func TestAccAWSVpcEndpoint_removed(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointConfig_gatewayWithoutRouteTableOrPolicy, + Config: testAccVpcEndpointConfig_gatewayWithoutRouteTableOrPolicy(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointExists("aws_vpc_endpoint.s3", &endpoint), + testAccCheckVpcEndpointExists(resourceName, &endpoint), testDestroy, ), ExpectNonEmptyPlan: true, @@ -439,28 +454,54 @@ func testAccCheckVpcEndpointPrefixListAvailable(n string) resource.TestCheckFunc } } -const testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicy = ` +func testAccVpcEndpointConfig_gatewayWithoutRouteTableOrPolicy(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "foo" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} + +data "aws_region" "current" {} + +resource "aws_vpc_endpoint" "s3" { + vpc_id = "${aws_vpc.foo.id}" + service_name = "com.amazonaws.${data.aws_region.current.name}.s3" +} +`, rName) +} + +func testAccVpcEndpointConfig_gatewayWithRouteTableAndPolicy(rName string) string { + return fmt.Sprintf(` resource "aws_vpc" "foo" { 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}" + vpc_id = "${aws_vpc.foo.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}" + vpc_id = "${aws_vpc.foo.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.default.id}", + ] + policy = <