From 561c22f3012b102c46243091f64ac694f68c0102 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 28 Jun 2021 15:04:47 -0400 Subject: [PATCH 01/22] r/aws_vpc_endpoint_service_allowed_principal: Tidy up acceptance test. --- ...endpoint_service_allowed_principal_test.go | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go b/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go index cf07c24a8b37..eb0981714cdd 100644 --- a/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go +++ b/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go @@ -13,7 +13,8 @@ import ( ) func TestAccAWSVpcEndpointServiceAllowedPrincipal_basic(t *testing.T) { - lbName := fmt.Sprintf("testaccawsnlb-basic-%s", acctest.RandString(10)) + resourceName := "aws_vpc_endpoint_service_allowed_principal.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -22,9 +23,9 @@ func TestAccAWSVpcEndpointServiceAllowedPrincipal_basic(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointServiceAllowedPrincipalDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointServiceAllowedPrincipalBasicConfig(lbName), + Config: testAccVpcEndpointServiceAllowedPrincipalConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointServiceAllowedPrincipalExists("aws_vpc_endpoint_service_allowed_principal.foo"), + testAccCheckVpcEndpointServiceAllowedPrincipalExists(resourceName), ), }, }, @@ -94,23 +95,23 @@ func testAccCheckVpcEndpointServiceAllowedPrincipalExists(n string) resource.Tes } } -func testAccVpcEndpointServiceAllowedPrincipalBasicConfig(lbName string) string { +func testAccVpcEndpointServiceAllowedPrincipalConfig(rName string) string { return composeConfig(testAccAvailableAZsNoOptInConfig(), fmt.Sprintf( ` -resource "aws_vpc" "nlb_test" { +resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" tags = { - Name = "terraform-testacc-vpc-endpoint-service-allowed-principal" + 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.test[0].id, + aws_subnet.test[1].id, ] load_balancer_type = "network" @@ -119,44 +120,40 @@ 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 - cidr_block = "10.0.1.0/24" - availability_zone = data.aws_availability_zones.available.names[0] +resource "aws_subnet" "test" { + count = 2 - tags = { - Name = "tf-acc-vpc-endpoint-service-allowed-principal-1" - } -} - -resource "aws_subnet" "nlb_test_2" { - vpc_id = aws_vpc.nlb_test.id - cidr_block = "10.0.2.0/24" - availability_zone = data.aws_availability_zones.available.names[1] + vpc_id = aws_vpc.test.id + cidr_block = cidrsubnet(aws_vpc.test.cidr_block, 2, count.index) + availability_zone = data.aws_availability_zones.available.names[count.index] tags = { - Name = "tf-acc-vpc-endpoint-service-allowed-principal-2" + Name = %[1]q } } data "aws_caller_identity" "current" {} -resource "aws_vpc_endpoint_service" "foo" { +resource "aws_vpc_endpoint_service" "test" { acceptance_required = false network_load_balancer_arns = [ - aws_lb.nlb_test_1.id, + aws_lb.test.arn, ] + + tags = { + Name = %[1]q + } } -resource "aws_vpc_endpoint_service_allowed_principal" "foo" { - vpc_endpoint_service_id = aws_vpc_endpoint_service.foo.id +resource "aws_vpc_endpoint_service_allowed_principal" "test" { + vpc_endpoint_service_id = aws_vpc_endpoint_service.test.id principal_arn = data.aws_caller_identity.current.arn } -`, lbName)) +`, rName)) } From 419e077adcc1d2d3d57d1e7b3beed1a9a886cabe Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 28 Jun 2021 15:26:50 -0400 Subject: [PATCH 02/22] Use 'aws_iam_session_context' to obtain issuer ARN. --- ...ource_aws_vpc_endpoint_service_allowed_principal_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go b/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go index eb0981714cdd..521a1dacabb2 100644 --- a/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go +++ b/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go @@ -138,6 +138,10 @@ resource "aws_subnet" "test" { data "aws_caller_identity" "current" {} +data "aws_iam_session_context" "current" { + arn = data.aws_caller_identity.current.arn +} + resource "aws_vpc_endpoint_service" "test" { acceptance_required = false @@ -153,7 +157,7 @@ resource "aws_vpc_endpoint_service" "test" { resource "aws_vpc_endpoint_service_allowed_principal" "test" { vpc_endpoint_service_id = aws_vpc_endpoint_service.test.id - principal_arn = data.aws_caller_identity.current.arn + principal_arn = data.aws_iam_session_context.current.issuer_arn } `, rName)) } From d6578d6f25dd490596d76e7adb4cf41b66fb0e2b Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Mon, 6 Jun 2022 11:34:49 +0300 Subject: [PATCH 03/22] add `supported_ip_address_types` arg --- internal/service/ec2/vpc_endpoint_service.go | 23 +++++++++ .../service/ec2/vpc_endpoint_service_test.go | 48 +++++++++++++++++++ .../docs/r/vpc_endpoint_service.html.markdown | 1 + 3 files changed, 72 insertions(+) diff --git a/internal/service/ec2/vpc_endpoint_service.go b/internal/service/ec2/vpc_endpoint_service.go index 5e38bebacaa5..c211bc141b59 100644 --- a/internal/service/ec2/vpc_endpoint_service.go +++ b/internal/service/ec2/vpc_endpoint_service.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/flex" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" @@ -121,6 +122,15 @@ func ResourceVPCEndpointService() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "supported_ip_address_types": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"ipv4", "ipv6"}, false), + }, + }, "tags": tftags.TagsSchema(), "tags_all": tftags.TagsSchemaComputed(), }, @@ -154,6 +164,12 @@ func resourceVPCEndpointServiceCreate(d *schema.ResourceData, meta interface{}) } } + if v, ok := d.GetOk("supported_ip_address_types"); ok { + if v, ok := v.(*schema.Set); ok && v.Len() > 0 { + req.SupportedIpAddressTypes = flex.ExpandStringSet(v) + } + } + log.Printf("[DEBUG] Creating VPC Endpoint Service configuration: %#v", req) resp, err := conn.CreateVpcEndpointServiceConfiguration(req) if err != nil { @@ -225,6 +241,10 @@ func resourceVPCEndpointServiceRead(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("error setting gateway_load_balancer_arns: %w", err) } + if err := d.Set("supported_ip_address_types", flex.FlattenStringSet(svcCfg.SupportedIpAddressTypes)); err != nil { + return fmt.Errorf("error setting supported_ip_address_types: %w", err) + } + d.Set("manages_vpc_endpoints", svcCfg.ManagesVpcEndpoints) if err := d.Set("network_load_balancer_arns", flex.FlattenStringSet(svcCfg.NetworkLoadBalancerArns)); err != nil { @@ -319,6 +339,9 @@ func resourceVPCEndpointServiceUpdate(d *schema.ResourceData, meta interface{}) setVPCEndpointServiceUpdateLists(d, "network_load_balancer_arns", &modifyCfgReq.AddNetworkLoadBalancerArns, &modifyCfgReq.RemoveNetworkLoadBalancerArns) + setVPCEndpointServiceUpdateLists(d, "supported_ip_address_types", + &modifyCfgReq.AddSupportedIpAddressTypes, &modifyCfgReq.RemoveSupportedIpAddressTypes) + log.Printf("[DEBUG] Modifying VPC Endpoint Service configuration: %#v", modifyCfgReq) if _, err := conn.ModifyVpcEndpointServiceConfiguration(modifyCfgReq); err != nil { return fmt.Errorf("Error modifying VPC Endpoint Service configuration: %s", err.Error()) diff --git a/internal/service/ec2/vpc_endpoint_service_test.go b/internal/service/ec2/vpc_endpoint_service_test.go index ab1066a998df..76e116470db8 100644 --- a/internal/service/ec2/vpc_endpoint_service_test.go +++ b/internal/service/ec2/vpc_endpoint_service_test.go @@ -38,6 +38,8 @@ func TestAccVPCEndpointService_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "manages_vpc_endpoints", "false"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.#", "0"), + resource.TestCheckResourceAttr(resourceName, "supported_ip_address_types.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv4"), acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), ), }, @@ -50,6 +52,36 @@ func TestAccVPCEndpointService_basic(t *testing.T) { }) } +func TestAccVPCEndpointService_ipTypes(t *testing.T) { + var svcCfg ec2.ServiceConfiguration + resourceName := "aws_vpc_endpoint_service.test" + rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckVPCEndpointServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccVPCEndpointServiceConfig_ipTypes(rName1, rName2), + Check: resource.ComposeTestCheckFunc( + testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), + resource.TestCheckResourceAttr(resourceName, "supported_ip_address_types.#", "2"), + resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv4"), + resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv6"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccVPCEndpointService_allowedPrincipals(t *testing.T) { var svcCfg ec2.ServiceConfiguration resourceName := "aws_vpc_endpoint_service.test" @@ -428,6 +460,22 @@ resource "aws_vpc_endpoint_service" "test" { `) } +func testAccVPCEndpointServiceConfig_ipTypes(rName1, rName2 string) string { + return acctest.ConfigCompose( + testAccVPCEndpointServiceConfig_base(rName1, rName2), + ` +resource "aws_vpc_endpoint_service" "test" { + acceptance_required = false + + network_load_balancer_arns = [ + aws_lb.test1.arn, + ] + + supported_ip_address_types = ["ipv4", "ipv6"] +} +`) +} + func testAccVPCEndpointServiceConfig_allowedPrincipals(rName1, rName2 string) string { return acctest.ConfigCompose( testAccVPCEndpointServiceConfig_base(rName1, rName2), diff --git a/website/docs/r/vpc_endpoint_service.html.markdown b/website/docs/r/vpc_endpoint_service.html.markdown index 4aea6f963d32..c3715132cc00 100644 --- a/website/docs/r/vpc_endpoint_service.html.markdown +++ b/website/docs/r/vpc_endpoint_service.html.markdown @@ -47,6 +47,7 @@ The following arguments are supported: * `network_load_balancer_arns` - (Optional) Amazon Resource Names (ARNs) of one or more Network Load Balancers for the endpoint service. * `tags` - (Optional) A map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. * `private_dns_name` - (Optional) The private DNS name for the service. +* `supported_ip_address_types` - (Optional) The supported IP address types. The possible values are `ipv4` and `ipv6`. ## Attributes Reference From effa1c0259175f0f7c2d54cc7f143f70c23d5c37 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Mon, 6 Jun 2022 11:36:57 +0300 Subject: [PATCH 04/22] add `supported_ip_address_types` arg --- internal/service/ec2/vpc_endpoint_service_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/service/ec2/vpc_endpoint_service_test.go b/internal/service/ec2/vpc_endpoint_service_test.go index 76e116470db8..32e058cf87ed 100644 --- a/internal/service/ec2/vpc_endpoint_service_test.go +++ b/internal/service/ec2/vpc_endpoint_service_test.go @@ -68,9 +68,8 @@ func TestAccVPCEndpointService_ipTypes(t *testing.T) { Config: testAccVPCEndpointServiceConfig_ipTypes(rName1, rName2), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "supported_ip_address_types.#", "2"), + resource.TestCheckResourceAttr(resourceName, "supported_ip_address_types.#", "1"), resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv4"), - resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv6"), ), }, { @@ -471,7 +470,7 @@ resource "aws_vpc_endpoint_service" "test" { aws_lb.test1.arn, ] - supported_ip_address_types = ["ipv4", "ipv6"] + supported_ip_address_types = ["ipv4"] } `) } From 88010e5526bffca2b0261af5208544a705e71134 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Mon, 6 Jun 2022 11:43:41 +0300 Subject: [PATCH 05/22] changelog --- .changelog/25189.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/25189.txt diff --git a/.changelog/25189.txt b/.changelog/25189.txt new file mode 100644 index 000000000000..f970d2ff586e --- /dev/null +++ b/.changelog/25189.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_ec2_vpc_endpoint_service: Add `supported_ip_address_types` argument +``` \ No newline at end of file From 7a23e2f091d84f3dbfdc1a13893d58db008082a0 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Mon, 6 Jun 2022 11:54:39 +0300 Subject: [PATCH 06/22] add to update list --- internal/service/ec2/vpc_endpoint_service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/ec2/vpc_endpoint_service.go b/internal/service/ec2/vpc_endpoint_service.go index c211bc141b59..860e1184efc1 100644 --- a/internal/service/ec2/vpc_endpoint_service.go +++ b/internal/service/ec2/vpc_endpoint_service.go @@ -320,7 +320,7 @@ func flattenPrivateDNSNameConfiguration(privateDnsNameConfiguration *ec2.Private func resourceVPCEndpointServiceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - if d.HasChanges("acceptance_required", "gateway_load_balancer_arns", "network_load_balancer_arns", "private_dns_name") { + if d.HasChanges("acceptance_required", "gateway_load_balancer_arns", "network_load_balancer_arns", "private_dns_name", "supported_ip_address_types") { modifyCfgReq := &ec2.ModifyVpcEndpointServiceConfigurationInput{ ServiceId: aws.String(d.Id()), } From 8f051598a74302d399c637a15125a594b7d874cf Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Mon, 6 Jun 2022 15:15:19 +0300 Subject: [PATCH 07/22] changelog --- .changelog/25189.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/25189.txt b/.changelog/25189.txt index f970d2ff586e..44ccbad1cee7 100644 --- a/.changelog/25189.txt +++ b/.changelog/25189.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/aws_ec2_vpc_endpoint_service: Add `supported_ip_address_types` argument +resource/aws_vpc_endpoint_service: Add `supported_ip_address_types` argument ``` \ No newline at end of file From 37f97eeb9385322010c7c9da13c054962098cc44 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 20 Jun 2022 16:32:35 -0400 Subject: [PATCH 08/22] r/aws_vpc_endpoint_service: Start to tidy up resource Create. --- internal/service/ec2/vpc_endpoint_service.go | 42 ++++++++------------ 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/internal/service/ec2/vpc_endpoint_service.go b/internal/service/ec2/vpc_endpoint_service.go index 860e1184efc1..c9387005b665 100644 --- a/internal/service/ec2/vpc_endpoint_service.go +++ b/internal/service/ec2/vpc_endpoint_service.go @@ -25,6 +25,7 @@ func ResourceVPCEndpointService() *schema.Resource { Read: resourceVPCEndpointServiceRead, Update: resourceVPCEndpointServiceUpdate, Delete: resourceVPCEndpointServiceDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -39,7 +40,6 @@ func ResourceVPCEndpointService() *schema.Resource { Optional: true, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, "arn": { Type: schema.TypeString, @@ -49,13 +49,11 @@ func ResourceVPCEndpointService() *schema.Resource { 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, }, "gateway_load_balancer_arns": { Type: schema.TypeSet, @@ -65,7 +63,6 @@ func ResourceVPCEndpointService() *schema.Resource { Type: schema.TypeString, ValidateFunc: verify.ValidARN, }, - Set: schema.HashString, }, "manages_vpc_endpoints": { Type: schema.TypeBool, @@ -79,7 +76,6 @@ func ResourceVPCEndpointService() *schema.Resource { Type: schema.TypeString, ValidateFunc: verify.ValidARN, }, - Set: schema.HashString, }, "private_dns_name": { Type: schema.TypeString, @@ -144,39 +140,35 @@ func resourceVPCEndpointServiceCreate(d *schema.ResourceData, meta interface{}) defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) - req := &ec2.CreateVpcEndpointServiceConfigurationInput{ + input := &ec2.CreateVpcEndpointServiceConfigurationInput{ AcceptanceRequired: aws.Bool(d.Get("acceptance_required").(bool)), - TagSpecifications: tagSpecificationsFromKeyValueTags(tags, "vpc-endpoint-service"), + TagSpecifications: tagSpecificationsFromKeyValueTags(tags, ec2.ResourceTypeVpcEndpointService), } - if v, ok := d.GetOk("private_dns_name"); ok { - req.PrivateDnsName = aws.String(v.(string)) + + if v, ok := d.GetOk("gateway_load_balancer_arns"); ok && v.(*schema.Set).Len() > 0 { + input.GatewayLoadBalancerArns = flex.ExpandStringSet(v.(*schema.Set)) } - if v, ok := d.GetOk("gateway_load_balancer_arns"); ok { - if v, ok := v.(*schema.Set); ok && v.Len() > 0 { - req.GatewayLoadBalancerArns = flex.ExpandStringSet(v) - } + if v, ok := d.GetOk("network_load_balancer_arns"); ok && v.(*schema.Set).Len() > 0 { + input.NetworkLoadBalancerArns = flex.ExpandStringSet(v.(*schema.Set)) } - if v, ok := d.GetOk("network_load_balancer_arns"); ok { - if v, ok := v.(*schema.Set); ok && v.Len() > 0 { - req.NetworkLoadBalancerArns = flex.ExpandStringSet(v) - } + if v, ok := d.GetOk("private_dns_name"); ok { + input.PrivateDnsName = aws.String(v.(string)) } - if v, ok := d.GetOk("supported_ip_address_types"); ok { - if v, ok := v.(*schema.Set); ok && v.Len() > 0 { - req.SupportedIpAddressTypes = flex.ExpandStringSet(v) - } + if v, ok := d.GetOk("supported_ip_address_types"); ok && v.(*schema.Set).Len() > 0 { + input.SupportedIpAddressTypes = flex.ExpandStringSet(v.(*schema.Set)) } - log.Printf("[DEBUG] Creating VPC Endpoint Service configuration: %#v", req) - resp, err := conn.CreateVpcEndpointServiceConfiguration(req) + log.Printf("[DEBUG] Creating VPC Endpoint Service: %s", input) + output, err := conn.CreateVpcEndpointServiceConfiguration(input) + if err != nil { - return fmt.Errorf("Error creating VPC Endpoint Service configuration: %s", err.Error()) + return fmt.Errorf("creating VPC Endpoint Service: %w", err) } - d.SetId(aws.StringValue(resp.ServiceConfiguration.ServiceId)) + d.SetId(aws.StringValue(output.ServiceConfiguration.ServiceId)) if err := vpcEndpointServiceWaitUntilAvailable(d, conn); err != nil { return err From f942f4c9eb306d3158dcfb4dce76426bb52012be Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 20 Jun 2022 17:15:58 -0400 Subject: [PATCH 09/22] Add 'FindVPCEndpointServices' and friends. --- internal/service/ec2/find.go | 83 ++++++++++++++++++++++++++++++++-- internal/service/ec2/status.go | 25 ++++++++++ internal/service/ec2/wait.go | 40 +++++++++++++++- 3 files changed, 144 insertions(+), 4 deletions(-) diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index f3e19d22ce36..012f05365c32 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -2494,9 +2494,9 @@ func FindVPCEndpoints(conn *ec2.EC2, input *ec2.DescribeVpcEndpointsInput) ([]*e return output, nil } -func FindVPCEndpointByID(conn *ec2.EC2, vpcEndpointID string) (*ec2.VpcEndpoint, error) { +func FindVPCEndpointByID(conn *ec2.EC2, id string) (*ec2.VpcEndpoint, error) { input := &ec2.DescribeVpcEndpointsInput{ - VpcEndpointIds: aws.StringSlice([]string{vpcEndpointID}), + VpcEndpointIds: aws.StringSlice([]string{id}), } output, err := FindVPCEndpoint(conn, input) @@ -2513,7 +2513,84 @@ func FindVPCEndpointByID(conn *ec2.EC2, vpcEndpointID string) (*ec2.VpcEndpoint, } // Eventual consistency check. - if aws.StringValue(output.VpcEndpointId) != vpcEndpointID { + if aws.StringValue(output.VpcEndpointId) != id { + return nil, &resource.NotFoundError{ + LastRequest: input, + } + } + + return output, nil +} + +func FindVPCEndpointService(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServiceConfigurationsInput) (*ec2.ServiceConfiguration, error) { + output, err := FindVPCEndpointServices(conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + +func FindVPCEndpointServices(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServiceConfigurationsInput) ([]*ec2.ServiceConfiguration, error) { + var output []*ec2.ServiceConfiguration + + err := conn.DescribeVpcEndpointServiceConfigurationsPages(input, func(page *ec2.DescribeVpcEndpointServiceConfigurationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.ServiceConfigurations { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIDNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindVPCEndpointServiceByID(conn *ec2.EC2, id string) (*ec2.ServiceConfiguration, error) { + input := &ec2.DescribeVpcEndpointServiceConfigurationsInput{ + ServiceIds: aws.StringSlice([]string{id}), + } + + output, err := FindVPCEndpointService(conn, input) + + if err != nil { + return nil, err + } + + if state := aws.StringValue(output.ServiceState); state == ec2.ServiceStateDeleted || state == ec2.ServiceStateFailed { + return nil, &resource.NotFoundError{ + Message: state, + LastRequest: input, + } + } + + // Eventual consistency check. + if aws.StringValue(output.ServiceId) != id { return nil, &resource.NotFoundError{ LastRequest: input, } diff --git a/internal/service/ec2/status.go b/internal/service/ec2/status.go index 4036328fa89c..94b626615e13 100644 --- a/internal/service/ec2/status.go +++ b/internal/service/ec2/status.go @@ -1103,6 +1103,31 @@ func StatusVPCEndpointState(conn *ec2.EC2, id string) resource.StateRefreshFunc } } +func StatusVPCEndpointServiceState(conn *ec2.EC2, id string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + // Don't call FindVPCEndpointServiceByID as it maps useful status codes to NotFoundError. + output, err := FindVPCEndpointService(conn, &ec2.DescribeVpcEndpointServiceConfigurationsInput{ + ServiceIds: aws.StringSlice([]string{id}), + }) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + serviceState := aws.StringValue(output.ServiceState) + + if serviceState == ec2.ServiceStateDeleted { + return nil, "", nil + } + + return output, serviceState, nil + } +} + const ( VPCEndpointRouteTableAssociationStatusReady = "ready" ) diff --git a/internal/service/ec2/wait.go b/internal/service/ec2/wait.go index 5ad62e86c06a..65ba6d254928 100644 --- a/internal/service/ec2/wait.go +++ b/internal/service/ec2/wait.go @@ -2266,8 +2266,8 @@ func WaitVPCEndpointDeleted(conn *ec2.EC2, vpcEndpointID string, timeout time.Du stateConf := &resource.StateChangeConf{ Pending: []string{vpcEndpointStateDeleting}, Target: []string{}, - Timeout: timeout, Refresh: StatusVPCEndpointState(conn, vpcEndpointID), + Timeout: timeout, Delay: 5 * time.Second, MinTimeout: 5 * time.Second, } @@ -2281,6 +2281,44 @@ func WaitVPCEndpointDeleted(conn *ec2.EC2, vpcEndpointID string, timeout time.Du return nil, err } +func WaitVPCEndpointServiceAvailable(conn *ec2.EC2, id string, timeout time.Duration) (*ec2.ServiceConfiguration, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{ec2.ServiceStatePending}, + Target: []string{ec2.ServiceStateAvailable}, + Refresh: StatusVPCEndpointServiceState(conn, id), + Timeout: timeout, + Delay: 5 * time.Second, + MinTimeout: 5 * time.Second, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*ec2.ServiceConfiguration); ok { + return output, err + } + + return nil, err +} + +func WaitVPCEndpointServiceDeleted(conn *ec2.EC2, id string, timeout time.Duration) (*ec2.ServiceConfiguration, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{ec2.ServiceStateAvailable, ec2.ServiceStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: StatusVPCEndpointServiceState(conn, id), + Delay: 5 * time.Second, + MinTimeout: 5 * time.Second, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*ec2.ServiceConfiguration); ok { + return output, err + } + + return nil, err +} + func WaitVPCEndpointRouteTableAssociationDeleted(conn *ec2.EC2, vpcEndpointID, routeTableID string) error { stateConf := &resource.StateChangeConf{ Pending: []string{VPCEndpointRouteTableAssociationStatusReady}, From ecfbcea5f1049f7d9839c1266f6def88cba84e38 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 20 Jun 2022 17:31:57 -0400 Subject: [PATCH 10/22] r/aws_vpc_endpoint_service: Tidy up resource Create. Acceptance test output: % make testacc TESTARGS='-run=TestAccVPCEndpointService_basic' PKG=ec2 ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 2 -run=TestAccVPCEndpointService_basic -timeout 180m === RUN TestAccVPCEndpointService_basic === PAUSE TestAccVPCEndpointService_basic === CONT TestAccVPCEndpointService_basic --- PASS: TestAccVPCEndpointService_basic (222.88s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 227.028s --- internal/service/ec2/vpc_endpoint_service.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/internal/service/ec2/vpc_endpoint_service.go b/internal/service/ec2/vpc_endpoint_service.go index c9387005b665..303f7173dfb6 100644 --- a/internal/service/ec2/vpc_endpoint_service.go +++ b/internal/service/ec2/vpc_endpoint_service.go @@ -131,6 +131,12 @@ func ResourceVPCEndpointService() *schema.Resource { "tags_all": tftags.TagsSchemaComputed(), }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + CustomizeDiff: verify.SetTagsDiff, } } @@ -170,18 +176,18 @@ func resourceVPCEndpointServiceCreate(d *schema.ResourceData, meta interface{}) d.SetId(aws.StringValue(output.ServiceConfiguration.ServiceId)) - if err := vpcEndpointServiceWaitUntilAvailable(d, conn); err != nil { - return err + if _, err := WaitVPCEndpointServiceAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return fmt.Errorf("waiting for VPC Endpoint Service (%s) create: %w", d.Id(), err) } if v, ok := d.GetOk("allowed_principals"); ok && v.(*schema.Set).Len() > 0 { - modifyPermReq := &ec2.ModifyVpcEndpointServicePermissionsInput{ - ServiceId: aws.String(d.Id()), + input := &ec2.ModifyVpcEndpointServicePermissionsInput{ AddAllowedPrincipals: flex.ExpandStringSet(v.(*schema.Set)), + ServiceId: aws.String(d.Id()), } - log.Printf("[DEBUG] Adding VPC Endpoint Service permissions: %#v", modifyPermReq) - if _, err := conn.ModifyVpcEndpointServicePermissions(modifyPermReq); err != nil { - return fmt.Errorf("error adding VPC Endpoint Service permissions: %s", err.Error()) + + if _, err := conn.ModifyVpcEndpointServicePermissions(input); err != nil { + return fmt.Errorf("modifying VPC Endpoint Service (%s) permissions: %w", d.Id(), err) } } From 3b67a5ac88b485c5cec05845a3133b884fbb8985 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 20 Jun 2022 17:45:41 -0400 Subject: [PATCH 11/22] r/aws_vpc_endpoint_service: Tidy up resource Delete. Acceptance test output: % make testacc TESTARGS='-run=TestAccVPCEndpointService_basic' PKG=ec2 ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 2 -run=TestAccVPCEndpointService_basic -timeout 180m === RUN TestAccVPCEndpointService_basic === PAUSE TestAccVPCEndpointService_basic === CONT TestAccVPCEndpointService_basic --- PASS: TestAccVPCEndpointService_basic (220.32s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 225.331s --- internal/service/ec2/status.go | 18 +++- internal/service/ec2/vpc_endpoint_service.go | 102 ++++++++----------- internal/service/ec2/wait.go | 4 +- 3 files changed, 57 insertions(+), 67 deletions(-) diff --git a/internal/service/ec2/status.go b/internal/service/ec2/status.go index 94b626615e13..b51391ff9d74 100644 --- a/internal/service/ec2/status.go +++ b/internal/service/ec2/status.go @@ -1103,7 +1103,7 @@ func StatusVPCEndpointState(conn *ec2.EC2, id string) resource.StateRefreshFunc } } -func StatusVPCEndpointServiceState(conn *ec2.EC2, id string) resource.StateRefreshFunc { +func StatusVPCEndpointServiceStateAvailable(conn *ec2.EC2, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { // Don't call FindVPCEndpointServiceByID as it maps useful status codes to NotFoundError. output, err := FindVPCEndpointService(conn, &ec2.DescribeVpcEndpointServiceConfigurationsInput{ @@ -1118,13 +1118,23 @@ func StatusVPCEndpointServiceState(conn *ec2.EC2, id string) resource.StateRefre return nil, "", err } - serviceState := aws.StringValue(output.ServiceState) + return output, aws.StringValue(output.ServiceState), nil + } +} - if serviceState == ec2.ServiceStateDeleted { +func StatusVPCEndpointServiceStateDeleted(conn *ec2.EC2, id string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindVPCEndpointServiceByID(conn, id) + + if tfresource.NotFound(err) { return nil, "", nil } - return output, serviceState, nil + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.ServiceState), nil } } diff --git a/internal/service/ec2/vpc_endpoint_service.go b/internal/service/ec2/vpc_endpoint_service.go index 303f7173dfb6..82b18e4aa6d7 100644 --- a/internal/service/ec2/vpc_endpoint_service.go +++ b/internal/service/ec2/vpc_endpoint_service.go @@ -167,17 +167,17 @@ func resourceVPCEndpointServiceCreate(d *schema.ResourceData, meta interface{}) input.SupportedIpAddressTypes = flex.ExpandStringSet(v.(*schema.Set)) } - log.Printf("[DEBUG] Creating VPC Endpoint Service: %s", input) + log.Printf("[DEBUG] Creating EC2 VPC Endpoint Service: %s", input) output, err := conn.CreateVpcEndpointServiceConfiguration(input) if err != nil { - return fmt.Errorf("creating VPC Endpoint Service: %w", err) + return fmt.Errorf("creating EC2 VPC Endpoint Service: %w", err) } d.SetId(aws.StringValue(output.ServiceConfiguration.ServiceId)) if _, err := WaitVPCEndpointServiceAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { - return fmt.Errorf("waiting for VPC Endpoint Service (%s) create: %w", d.Id(), err) + return fmt.Errorf("waiting for EC2 VPC Endpoint Service (%s) create: %w", d.Id(), err) } if v, ok := d.GetOk("allowed_principals"); ok && v.(*schema.Set).Len() > 0 { @@ -187,7 +187,7 @@ func resourceVPCEndpointServiceCreate(d *schema.ResourceData, meta interface{}) } if _, err := conn.ModifyVpcEndpointServicePermissions(input); err != nil { - return fmt.Errorf("modifying VPC Endpoint Service (%s) permissions: %w", d.Id(), err) + return fmt.Errorf("modifying EC2 VPC Endpoint Service (%s) permissions: %w", d.Id(), err) } } @@ -285,36 +285,6 @@ func resourceVPCEndpointServiceRead(d *schema.ResourceData, meta interface{}) er return nil } -func flattenPrivateDNSNameConfiguration(privateDnsNameConfiguration *ec2.PrivateDnsNameConfiguration) []interface{} { - if privateDnsNameConfiguration == nil { - return nil - } - tfMap := map[string]interface{}{} - - if v := privateDnsNameConfiguration.Name; v != nil { - tfMap["name"] = aws.StringValue(v) - } - - if v := privateDnsNameConfiguration.State; v != nil { - tfMap["state"] = aws.StringValue(v) - } - - if v := privateDnsNameConfiguration.Type; v != nil { - tfMap["type"] = aws.StringValue(v) - } - - if v := privateDnsNameConfiguration.Value; v != nil { - tfMap["value"] = aws.StringValue(v) - } - - // The EC2 API can return a XML structure with no elements - if len(tfMap) == 0 { - return nil - } - - return []interface{}{tfMap} -} - func resourceVPCEndpointServiceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn @@ -378,33 +348,58 @@ func resourceVPCEndpointServiceUpdate(d *schema.ResourceData, meta interface{}) func resourceVPCEndpointServiceDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - input := &ec2.DeleteVpcEndpointServiceConfigurationsInput{ + log.Printf("[INFO] Deleting EC2 VPC Endpoint Service: %s", d.Id()) + output, err := conn.DeleteVpcEndpointServiceConfigurations(&ec2.DeleteVpcEndpointServiceConfigurationsInput{ ServiceIds: aws.StringSlice([]string{d.Id()}), - } + }) - output, err := conn.DeleteVpcEndpointServiceConfigurations(input) + if err == nil && output != nil { + err = UnsuccessfulItemsError(output.Unsuccessful) + } if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIDNotFound) { return nil } if err != nil { - return fmt.Errorf("error deleting EC2 VPC Endpoint Service (%s): %w", d.Id(), err) + return fmt.Errorf("deleting EC2 VPC Endpoint Service (%s): %w", d.Id(), err) } - if output != nil && len(output.Unsuccessful) > 0 { - err := UnsuccessfulItemsError(output.Unsuccessful) + if _, err := WaitVPCEndpointServiceDeleted(conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return fmt.Errorf("waiting for EC2 VPC Endpoint Service (%s) delete: %w", d.Id(), err) + } - if err != nil { - return fmt.Errorf("error deleting EC2 VPC Endpoint Service (%s): %w", d.Id(), err) - } + return nil +} + +func flattenPrivateDNSNameConfiguration(privateDnsNameConfiguration *ec2.PrivateDnsNameConfiguration) []interface{} { + if privateDnsNameConfiguration == nil { + return nil } + tfMap := map[string]interface{}{} - if err := waitForVPCEndpointServiceDeletion(conn, d.Id()); err != nil { - return fmt.Errorf("error waiting for EC2 VPC Endpoint Service (%s) to delete: %w", d.Id(), err) + if v := privateDnsNameConfiguration.Name; v != nil { + tfMap["name"] = aws.StringValue(v) } - return nil + if v := privateDnsNameConfiguration.State; v != nil { + tfMap["state"] = aws.StringValue(v) + } + + if v := privateDnsNameConfiguration.Type; v != nil { + tfMap["type"] = aws.StringValue(v) + } + + if v := privateDnsNameConfiguration.Value; v != nil { + tfMap["value"] = aws.StringValue(v) + } + + // The EC2 API can return a XML structure with no elements + if len(tfMap) == 0 { + return nil + } + + return []interface{}{tfMap} } func vpcEndpointServiceStateRefresh(conn *ec2.EC2, svcId string) resource.StateRefreshFunc { @@ -447,21 +442,6 @@ func vpcEndpointServiceWaitUntilAvailable(d *schema.ResourceData, conn *ec2.EC2) return nil } -func waitForVPCEndpointServiceDeletion(conn *ec2.EC2, serviceID string) error { - stateConf := &resource.StateChangeConf{ - Pending: []string{ec2.ServiceStateAvailable, ec2.ServiceStateDeleting}, - Target: []string{ec2.ServiceStateDeleted}, - Refresh: vpcEndpointServiceStateRefresh(conn, serviceID), - Timeout: 10 * time.Minute, - Delay: 5 * time.Second, - MinTimeout: 5 * time.Second, - } - - _, err := stateConf.WaitForState() - - return err -} - func setVPCEndpointServiceUpdateLists(d *schema.ResourceData, key string, a, r *[]*string) { if d.HasChange(key) { o, n := d.GetChange(key) diff --git a/internal/service/ec2/wait.go b/internal/service/ec2/wait.go index 65ba6d254928..7e9c9c54535a 100644 --- a/internal/service/ec2/wait.go +++ b/internal/service/ec2/wait.go @@ -2285,7 +2285,7 @@ func WaitVPCEndpointServiceAvailable(conn *ec2.EC2, id string, timeout time.Dura stateConf := &resource.StateChangeConf{ Pending: []string{ec2.ServiceStatePending}, Target: []string{ec2.ServiceStateAvailable}, - Refresh: StatusVPCEndpointServiceState(conn, id), + Refresh: StatusVPCEndpointServiceStateAvailable(conn, id), Timeout: timeout, Delay: 5 * time.Second, MinTimeout: 5 * time.Second, @@ -2305,7 +2305,7 @@ func WaitVPCEndpointServiceDeleted(conn *ec2.EC2, id string, timeout time.Durati Pending: []string{ec2.ServiceStateAvailable, ec2.ServiceStateDeleting}, Target: []string{}, Timeout: timeout, - Refresh: StatusVPCEndpointServiceState(conn, id), + Refresh: StatusVPCEndpointServiceStateDeleted(conn, id), Delay: 5 * time.Second, MinTimeout: 5 * time.Second, } From be33e1043d72c0a46a656880e418733c6c5d00d9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 08:59:04 -0400 Subject: [PATCH 12/22] Additional error messages to skip. --- internal/service/ec2/ec2_instance_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/service/ec2/ec2_instance_test.go b/internal/service/ec2/ec2_instance_test.go index 4b7d880a2e74..599dc700a695 100644 --- a/internal/service/ec2/ec2_instance_test.go +++ b/internal/service/ec2/ec2_instance_test.go @@ -36,6 +36,8 @@ func testAccErrorCheckSkip(t *testing.T) resource.ErrorCheckFunc { "You have reached the maximum allowed number of license configurations created in one day", "specified zone does not support multi-attach-enabled volumes", "Unsupported volume type", + "HostLimitExceeded", + "ReservationCapacityExceeded", ) } From d6e0a94b0c5f28c2e60b8ef98dbdbcd245b909ea Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 10:10:58 -0400 Subject: [PATCH 13/22] r/aws_vpc_endpoint_service: Tidy up resource Read. Acceptance test output: % make testacc TESTARGS='-run=TestAccVPCEndpointService_basic' PKG=ec2 ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 2 -run=TestAccVPCEndpointService_basic -timeout 180m === RUN TestAccVPCEndpointService_basic === PAUSE TestAccVPCEndpointService_basic === CONT TestAccVPCEndpointService_basic --- PASS: TestAccVPCEndpointService_basic (267.36s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 272.126s --- internal/service/ec2/find.go | 49 +++++- internal/service/ec2/status.go | 6 +- internal/service/ec2/vpc_endpoint_service.go | 129 +++++++------- .../service/ec2/vpc_endpoint_service_test.go | 160 ++++++++++++------ 4 files changed, 212 insertions(+), 132 deletions(-) diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 012f05365c32..267f3a6de926 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -2522,8 +2522,8 @@ func FindVPCEndpointByID(conn *ec2.EC2, id string) (*ec2.VpcEndpoint, error) { return output, nil } -func FindVPCEndpointService(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServiceConfigurationsInput) (*ec2.ServiceConfiguration, error) { - output, err := FindVPCEndpointServices(conn, input) +func FindVPCEndpointServiceConfiguration(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServiceConfigurationsInput) (*ec2.ServiceConfiguration, error) { + output, err := FindVPCEndpointServiceConfigurations(conn, input) if err != nil { return nil, err @@ -2540,7 +2540,7 @@ func FindVPCEndpointService(conn *ec2.EC2, input *ec2.DescribeVpcEndpointService return output[0], nil } -func FindVPCEndpointServices(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServiceConfigurationsInput) ([]*ec2.ServiceConfiguration, error) { +func FindVPCEndpointServiceConfigurations(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServiceConfigurationsInput) ([]*ec2.ServiceConfiguration, error) { var output []*ec2.ServiceConfiguration err := conn.DescribeVpcEndpointServiceConfigurationsPages(input, func(page *ec2.DescribeVpcEndpointServiceConfigurationsOutput, lastPage bool) bool { @@ -2571,12 +2571,12 @@ func FindVPCEndpointServices(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServic return output, nil } -func FindVPCEndpointServiceByID(conn *ec2.EC2, id string) (*ec2.ServiceConfiguration, error) { +func FindVPCEndpointServiceConfigurationByID(conn *ec2.EC2, id string) (*ec2.ServiceConfiguration, error) { input := &ec2.DescribeVpcEndpointServiceConfigurationsInput{ ServiceIds: aws.StringSlice([]string{id}), } - output, err := FindVPCEndpointService(conn, input) + output, err := FindVPCEndpointServiceConfiguration(conn, input) if err != nil { return nil, err @@ -2599,6 +2599,45 @@ func FindVPCEndpointServiceByID(conn *ec2.EC2, id string) (*ec2.ServiceConfigura return output, nil } +func FindVPCEndpointServicePermissions(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServicePermissionsInput) ([]*ec2.AllowedPrincipal, error) { + var output []*ec2.AllowedPrincipal + + err := conn.DescribeVpcEndpointServicePermissionsPages(input, func(page *ec2.DescribeVpcEndpointServicePermissionsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.AllowedPrincipals { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIDNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindVPCEndpointServicePermissionsByID(conn *ec2.EC2, id string) ([]*ec2.AllowedPrincipal, error) { + input := &ec2.DescribeVpcEndpointServicePermissionsInput{ + ServiceId: aws.String(id), + } + + return FindVPCEndpointServicePermissions(conn, input) +} + // FindVPCEndpointRouteTableAssociationExists returns NotFoundError if no association for the specified VPC endpoint and route table IDs is found. func FindVPCEndpointRouteTableAssociationExists(conn *ec2.EC2, vpcEndpointID string, routeTableID string) error { vpcEndpoint, err := FindVPCEndpointByID(conn, vpcEndpointID) diff --git a/internal/service/ec2/status.go b/internal/service/ec2/status.go index b51391ff9d74..63517bf5e1a2 100644 --- a/internal/service/ec2/status.go +++ b/internal/service/ec2/status.go @@ -1105,8 +1105,8 @@ func StatusVPCEndpointState(conn *ec2.EC2, id string) resource.StateRefreshFunc func StatusVPCEndpointServiceStateAvailable(conn *ec2.EC2, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - // Don't call FindVPCEndpointServiceByID as it maps useful status codes to NotFoundError. - output, err := FindVPCEndpointService(conn, &ec2.DescribeVpcEndpointServiceConfigurationsInput{ + // Don't call FindVPCEndpointServiceConfigurationByID as it maps useful status codes to NotFoundError. + output, err := FindVPCEndpointServiceConfiguration(conn, &ec2.DescribeVpcEndpointServiceConfigurationsInput{ ServiceIds: aws.StringSlice([]string{id}), }) @@ -1124,7 +1124,7 @@ func StatusVPCEndpointServiceStateAvailable(conn *ec2.EC2, id string) resource.S func StatusVPCEndpointServiceStateDeleted(conn *ec2.EC2, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - output, err := FindVPCEndpointServiceByID(conn, id) + output, err := FindVPCEndpointServiceConfigurationByID(conn, id) if tfresource.NotFound(err) { return nil, "", nil diff --git a/internal/service/ec2/vpc_endpoint_service.go b/internal/service/ec2/vpc_endpoint_service.go index 82b18e4aa6d7..66da03c8173c 100644 --- a/internal/service/ec2/vpc_endpoint_service.go +++ b/internal/service/ec2/vpc_endpoint_service.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/flex" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" ) @@ -199,22 +200,19 @@ func resourceVPCEndpointServiceRead(d *schema.ResourceData, meta interface{}) er defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - svcCfgRaw, state, err := vpcEndpointServiceStateRefresh(conn, d.Id())() - if err != nil && state != ec2.ServiceStateFailed { - return fmt.Errorf("error reading VPC Endpoint Service (%s): %s", d.Id(), err.Error()) - } + svcCfg, err := FindVPCEndpointServiceConfigurationByID(conn, d.Id()) - terminalStates := map[string]bool{ - ec2.ServiceStateDeleted: true, - ec2.ServiceStateDeleting: true, - ec2.ServiceStateFailed: true, - } - if _, ok := terminalStates[state]; ok { - log.Printf("[WARN] VPC Endpoint Service (%s) not found, removing from state", d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] EC2 VPC Endpoint Service %s not found, removing from state", d.Id()) d.SetId("") return nil } + if err != nil { + return fmt.Errorf("reading EC2 VPC Endpoint Service (%s): %w", d.Id(), err) + } + + d.Set("acceptance_required", svcCfg.AcceptanceRequired) arn := arn.ARN{ Partition: meta.(*conns.AWSClient).Partition, Service: ec2.ServiceName, @@ -223,64 +221,47 @@ func resourceVPCEndpointServiceRead(d *schema.ResourceData, meta interface{}) er Resource: fmt.Sprintf("vpc-endpoint-service/%s", d.Id()), }.String() d.Set("arn", arn) - - svcCfg := svcCfgRaw.(*ec2.ServiceConfiguration) - d.Set("acceptance_required", svcCfg.AcceptanceRequired) - err = d.Set("availability_zones", flex.FlattenStringSet(svcCfg.AvailabilityZones)) - if err != nil { - return fmt.Errorf("error setting availability_zones: %s", err) - } - err = d.Set("base_endpoint_dns_names", flex.FlattenStringSet(svcCfg.BaseEndpointDnsNames)) - if err != nil { - return fmt.Errorf("error setting base_endpoint_dns_names: %s", err) - } - - if err := d.Set("gateway_load_balancer_arns", flex.FlattenStringSet(svcCfg.GatewayLoadBalancerArns)); err != nil { - return fmt.Errorf("error setting gateway_load_balancer_arns: %w", err) - } - - if err := d.Set("supported_ip_address_types", flex.FlattenStringSet(svcCfg.SupportedIpAddressTypes)); err != nil { - return fmt.Errorf("error setting supported_ip_address_types: %w", err) - } - + d.Set("availability_zones", aws.StringValueSlice(svcCfg.AvailabilityZones)) + d.Set("base_endpoint_dns_names", aws.StringValueSlice(svcCfg.BaseEndpointDnsNames)) + d.Set("gateway_load_balancer_arns", aws.StringValueSlice(svcCfg.GatewayLoadBalancerArns)) d.Set("manages_vpc_endpoints", svcCfg.ManagesVpcEndpoints) - - if err := d.Set("network_load_balancer_arns", flex.FlattenStringSet(svcCfg.NetworkLoadBalancerArns)); err != nil { - return fmt.Errorf("error setting network_load_balancer_arns: %w", err) - } - + d.Set("network_load_balancer_arns", aws.StringValueSlice(svcCfg.NetworkLoadBalancerArns)) d.Set("private_dns_name", svcCfg.PrivateDnsName) + // The EC2 API can return a XML structure with no elements. + if tfMap := flattenPrivateDNSNameConfiguration(svcCfg.PrivateDnsNameConfiguration); len(tfMap) > 0 { + if err := d.Set("private_dns_name_configuration", []interface{}{tfMap}); err != nil { + return fmt.Errorf("setting private_dns_name_configuration: %w", err) + } + } else { + d.Set("private_dns_name_configuration", nil) + } d.Set("service_name", svcCfg.ServiceName) - d.Set("service_type", svcCfg.ServiceType[0].ServiceType) + if len(svcCfg.ServiceType) > 0 { + d.Set("service_type", svcCfg.ServiceType[0].ServiceType) + } else { + d.Set("service_type", nil) + } d.Set("state", svcCfg.ServiceState) + d.Set("supported_ip_address_types", aws.StringValueSlice(svcCfg.SupportedIpAddressTypes)) tags := KeyValueTags(svcCfg.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) //lintignore:AWSR002 if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %w", err) + return fmt.Errorf("setting tags: %w", err) } if err := d.Set("tags_all", tags.Map()); err != nil { - return fmt.Errorf("error setting tags_all: %w", err) + return fmt.Errorf("setting tags_all: %w", 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()) - } + allowedPrincipals, err := FindVPCEndpointServicePermissionsByID(conn, d.Id()) - err = d.Set("allowed_principals", flattenVPCEndpointServiceAllowedPrincipals(resp.AllowedPrincipals)) if err != nil { - return fmt.Errorf("error setting allowed_principals: %s", err) + return fmt.Errorf("reading EC2 VPC Endpoint Service (%s) permissions: %w", d.Id(), err) } - err = d.Set("private_dns_name_configuration", flattenPrivateDNSNameConfiguration(svcCfg.PrivateDnsNameConfiguration)) - if err != nil { - return fmt.Errorf("error setting private_dns_name_configuration: %w", err) - } + d.Set("allowed_principals", flattenAllowedPrincipals(allowedPrincipals)) return nil } @@ -372,34 +353,30 @@ func resourceVPCEndpointServiceDelete(d *schema.ResourceData, meta interface{}) return nil } -func flattenPrivateDNSNameConfiguration(privateDnsNameConfiguration *ec2.PrivateDnsNameConfiguration) []interface{} { - if privateDnsNameConfiguration == nil { +func flattenPrivateDNSNameConfiguration(apiObject *ec2.PrivateDnsNameConfiguration) map[string]interface{} { + if apiObject == nil { return nil } + tfMap := map[string]interface{}{} - if v := privateDnsNameConfiguration.Name; v != nil { + if v := apiObject.Name; v != nil { tfMap["name"] = aws.StringValue(v) } - if v := privateDnsNameConfiguration.State; v != nil { + if v := apiObject.State; v != nil { tfMap["state"] = aws.StringValue(v) } - if v := privateDnsNameConfiguration.Type; v != nil { + if v := apiObject.Type; v != nil { tfMap["type"] = aws.StringValue(v) } - if v := privateDnsNameConfiguration.Value; v != nil { + if v := apiObject.Value; v != nil { tfMap["value"] = aws.StringValue(v) } - // The EC2 API can return a XML structure with no elements - if len(tfMap) == 0 { - return nil - } - - return []interface{}{tfMap} + return tfMap } func vpcEndpointServiceStateRefresh(conn *ec2.EC2, svcId string) resource.StateRefreshFunc { @@ -460,14 +437,28 @@ func setVPCEndpointServiceUpdateLists(d *schema.ResourceData, key string, a, r * } } -func flattenVPCEndpointServiceAllowedPrincipals(allowedPrincipals []*ec2.AllowedPrincipal) *schema.Set { - vPrincipals := []interface{}{} +func flattenAllowedPrincipal(apiObject *ec2.AllowedPrincipal) *string { + if apiObject == nil { + return nil + } + + return apiObject.Principal +} + +func flattenAllowedPrincipals(apiObjects []*ec2.AllowedPrincipal) []*string { + if len(apiObjects) == 0 { + return nil + } - for _, allowedPrincipal := range allowedPrincipals { - if allowedPrincipal.Principal != nil { - vPrincipals = append(vPrincipals, aws.StringValue(allowedPrincipal.Principal)) + var tfList []*string + + for _, apiObject := range apiObjects { + if apiObject == nil { + continue } + + tfList = append(tfList, flattenAllowedPrincipal(apiObject)) } - return schema.NewSet(schema.HashString, vPrincipals) + return tfList } diff --git a/internal/service/ec2/vpc_endpoint_service_test.go b/internal/service/ec2/vpc_endpoint_service_test.go index 32e058cf87ed..31a2ba051b96 100644 --- a/internal/service/ec2/vpc_endpoint_service_test.go +++ b/internal/service/ec2/vpc_endpoint_service_test.go @@ -5,22 +5,20 @@ import ( "regexp" "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func TestAccVPCEndpointService_basic(t *testing.T) { var svcCfg ec2.ServiceConfiguration resourceName := "aws_vpc_endpoint_service.test" - rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -29,18 +27,24 @@ func TestAccVPCEndpointService_basic(t *testing.T) { CheckDestroy: testAccCheckVPCEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVPCEndpointServiceConfig_networkLoadBalancerARNs(rName1, rName2), - Check: resource.ComposeTestCheckFunc( + Config: testAccVPCEndpointServiceConfig_basic(rName), + Check: resource.ComposeAggregateTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), resource.TestCheckResourceAttr(resourceName, "acceptance_required", "false"), - resource.TestCheckResourceAttr(resourceName, "network_load_balancer_arns.#", "1"), resource.TestCheckResourceAttr(resourceName, "allowed_principals.#", "0"), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), + acctest.CheckResourceAttrGreaterThanValue(resourceName, "availability_zones.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(resourceName, "base_endpoint_dns_names.#", "0"), + resource.TestCheckResourceAttr(resourceName, "gateway_load_balancer_arns.#", "0"), resource.TestCheckResourceAttr(resourceName, "manages_vpc_endpoints", "false"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "network_load_balancer_arns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "private_dns_name", ""), resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, "service_name"), + resource.TestCheckResourceAttr(resourceName, "service_type", "Interface"), resource.TestCheckResourceAttr(resourceName, "supported_ip_address_types.#", "1"), resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv4"), - acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { @@ -52,6 +56,29 @@ func TestAccVPCEndpointService_basic(t *testing.T) { }) } +func TestAccVPCEndpointService_disappears(t *testing.T) { + var svcCfg ec2.ServiceConfiguration + resourceName := "aws_vpc_endpoint_service.test" + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckVPCEndpointServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccVPCEndpointServiceConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), + acctest.CheckResourceDisappears(acctest.Provider, tfec2.ResourceVPCEndpointService(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func TestAccVPCEndpointService_ipTypes(t *testing.T) { var svcCfg ec2.ServiceConfiguration resourceName := "aws_vpc_endpoint_service.test" @@ -126,30 +153,6 @@ func TestAccVPCEndpointService_allowedPrincipals(t *testing.T) { }) } -func TestAccVPCEndpointService_disappears(t *testing.T) { - var svcCfg ec2.ServiceConfiguration - resourceName := "aws_vpc_endpoint_service.test" - rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, - ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), - ProviderFactories: acctest.ProviderFactories, - CheckDestroy: testAccCheckVPCEndpointServiceDestroy, - Steps: []resource.TestStep{ - { - Config: testAccVPCEndpointServiceConfig_networkLoadBalancerARNs(rName1, rName2), - Check: resource.ComposeTestCheckFunc( - testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - acctest.CheckResourceDisappears(acctest.Provider, tfec2.ResourceVPCEndpointService(), resourceName), - ), - ExpectNonEmptyPlan: true, - }, - }, - }) -} - func TestAccVPCEndpointService_gatewayLoadBalancerARNs(t *testing.T) { var svcCfg ec2.ServiceConfiguration resourceName := "aws_vpc_endpoint_service.test" @@ -277,27 +280,23 @@ func testAccCheckVPCEndpointServiceDestroy(s *terraform.State) error { continue } - resp, err := conn.DescribeVpcEndpointServiceConfigurations(&ec2.DescribeVpcEndpointServiceConfigurationsInput{ - ServiceIds: []*string{aws.String(rs.Primary.ID)}, - }) + _, err := tfec2.FindVPCEndpointServiceConfigurationByID(conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + if err != nil { - // Verify the error is what we want - if tfawserr.ErrCodeEquals(err, "InvalidVpcEndpointServiceId.NotFound") { - continue - } return err } - if len(resp.ServiceConfigurations) > 0 { - return fmt.Errorf("VPC Endpoint Services still exist.") - } - return err + return fmt.Errorf("EC2 VPC Endpoint Service %s still exists", rs.Primary.ID) } return nil } -func testAccCheckVPCEndpointServiceExists(n string, svcCfg *ec2.ServiceConfiguration) resource.TestCheckFunc { +func testAccCheckVPCEndpointServiceExists(n string, v *ec2.ServiceConfiguration) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -305,22 +304,18 @@ func testAccCheckVPCEndpointServiceExists(n string, svcCfg *ec2.ServiceConfigura } if rs.Primary.ID == "" { - return fmt.Errorf("No VPC Endpoint Service ID is set") + return fmt.Errorf("No EC2 VPC Endpoint Service ID is set") } conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn - resp, err := conn.DescribeVpcEndpointServiceConfigurations(&ec2.DescribeVpcEndpointServiceConfigurationsInput{ - ServiceIds: []*string{aws.String(rs.Primary.ID)}, - }) + output, err := tfec2.FindVPCEndpointServiceConfigurationByID(conn, rs.Primary.ID) + if err != nil { return err } - if len(resp.ServiceConfigurations) == 0 { - return fmt.Errorf("VPC Endpoint Service not found") - } - *svcCfg = *resp.ServiceConfigurations[0] + *v = *output return nil } @@ -405,6 +400,57 @@ data "aws_caller_identity" "current" {} `, rName1, rName2) } +func testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName string, count int) string { + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} + +resource "aws_subnet" "test" { + count = 2 + + vpc_id = aws_vpc.test.id + cidr_block = cidrsubnet(aws_vpc.test.cidr_block, 8, count.index) + availability_zone = data.aws_availability_zones.available.names[count.index] + + tags = { + Name = %[1]q + } +} + +resource "aws_lb" "test" { + count = %[2]d + + load_balancer_type = "network" + name = "%[1]s-${count.index}" + + subnets = aws_subnet.test[*].id + + internal = true + idle_timeout = 60 + enable_deletion_protection = false + + tags = { + Name = %[1]q + } +} +`, rName, count)) +} + +func testAccVPCEndpointServiceConfig_basic(rName string) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, 1), ` +resource "aws_vpc_endpoint_service" "test" { + acceptance_required = false + + network_load_balancer_arns = aws_lb.test[*].arn +} +`) +} + func testAccVPCEndpointServiceConfig_gatewayLoadBalancerARNs(rName string, count int) string { return acctest.ConfigCompose( acctest.ConfigAvailableAZsNoOptIn(), @@ -413,7 +459,7 @@ resource "aws_vpc" "test" { cidr_block = "10.10.10.0/25" tags = { - Name = "tf-acc-test-load-balancer" + Name = %[1]q } } @@ -423,7 +469,7 @@ resource "aws_subnet" "test" { vpc_id = aws_vpc.test.id tags = { - Name = "tf-acc-test-load-balancer" + Name = %[1]q } } @@ -441,6 +487,10 @@ resource "aws_lb" "test" { resource "aws_vpc_endpoint_service" "test" { acceptance_required = false gateway_load_balancer_arns = aws_lb.test[*].arn + + tags = { + Name = %[1]q + } } `, rName, count)) } From b7c5b619b561fee4c45bf7a52a2f25ed03998044 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 11:33:32 -0400 Subject: [PATCH 14/22] r/aws_vpc_endpoint_service: Tidy up resource Update. Acceptance test output: % make testacc TESTARGS='-run=TestAccVPCEndpointService_supportedIPAddressTypes' PKG=ec2 ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 2 -run=TestAccVPCEndpointService_supportedIPAddressTypes -timeout 180m === RUN TestAccVPCEndpointService_supportedIPAddressTypes === PAUSE TestAccVPCEndpointService_supportedIPAddressTypes === CONT TestAccVPCEndpointService_supportedIPAddressTypes --- PASS: TestAccVPCEndpointService_supportedIPAddressTypes (255.11s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 262.224s --- internal/service/ec2/vpc_endpoint_service.go | 167 ++++----- .../service/ec2/vpc_endpoint_service_test.go | 345 ++++++++---------- 2 files changed, 224 insertions(+), 288 deletions(-) diff --git a/internal/service/ec2/vpc_endpoint_service.go b/internal/service/ec2/vpc_endpoint_service.go index 66da03c8173c..8aa6f56b8b44 100644 --- a/internal/service/ec2/vpc_endpoint_service.go +++ b/internal/service/ec2/vpc_endpoint_service.go @@ -1,7 +1,6 @@ package ec2 import ( - "errors" "fmt" "log" "time" @@ -10,7 +9,6 @@ import ( "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" @@ -270,48 +268,55 @@ func resourceVPCEndpointServiceUpdate(d *schema.ResourceData, meta interface{}) conn := meta.(*conns.AWSClient).EC2Conn if d.HasChanges("acceptance_required", "gateway_load_balancer_arns", "network_load_balancer_arns", "private_dns_name", "supported_ip_address_types") { - modifyCfgReq := &ec2.ModifyVpcEndpointServiceConfigurationInput{ + input := &ec2.ModifyVpcEndpointServiceConfigurationInput{ ServiceId: aws.String(d.Id()), } - if d.HasChange("private_dns_name") { - modifyCfgReq.PrivateDnsName = aws.String(d.Get("private_dns_name").(string)) + if d.HasChange("acceptance_required") { + input.AcceptanceRequired = aws.Bool(d.Get("acceptance_required").(bool)) } - if d.HasChange("acceptance_required") { - modifyCfgReq.AcceptanceRequired = aws.Bool(d.Get("acceptance_required").(bool)) + if d.HasChange("gateway_load_balancer_arns") { + setVPCEndpointServiceUpdateLists(d, "gateway_load_balancer_arns", + &input.AddGatewayLoadBalancerArns, &input.RemoveGatewayLoadBalancerArns) + } + + if d.HasChange("network_load_balancer_arns") { + setVPCEndpointServiceUpdateLists(d, "network_load_balancer_arns", + &input.AddNetworkLoadBalancerArns, &input.RemoveNetworkLoadBalancerArns) } - setVPCEndpointServiceUpdateLists(d, "gateway_load_balancer_arns", - &modifyCfgReq.AddGatewayLoadBalancerArns, &modifyCfgReq.RemoveGatewayLoadBalancerArns) + if d.HasChange("private_dns_name") { + input.PrivateDnsName = aws.String(d.Get("private_dns_name").(string)) + } - setVPCEndpointServiceUpdateLists(d, "network_load_balancer_arns", - &modifyCfgReq.AddNetworkLoadBalancerArns, &modifyCfgReq.RemoveNetworkLoadBalancerArns) + if d.HasChange("supported_ip_address_types") { + setVPCEndpointServiceUpdateLists(d, "supported_ip_address_types", + &input.AddSupportedIpAddressTypes, &input.RemoveSupportedIpAddressTypes) + } - setVPCEndpointServiceUpdateLists(d, "supported_ip_address_types", - &modifyCfgReq.AddSupportedIpAddressTypes, &modifyCfgReq.RemoveSupportedIpAddressTypes) + log.Printf("[DEBUG] Updating EC2 VPC Endpoint Service: %s", input) + _, err := conn.ModifyVpcEndpointServiceConfiguration(input) - log.Printf("[DEBUG] Modifying VPC Endpoint Service configuration: %#v", modifyCfgReq) - if _, err := conn.ModifyVpcEndpointServiceConfiguration(modifyCfgReq); err != nil { - return fmt.Errorf("Error modifying VPC Endpoint Service configuration: %s", err.Error()) + if err != nil { + return fmt.Errorf("updating EC2 VPC Endpoint Service (%s): %w", d.Id(), err) } - if err := vpcEndpointServiceWaitUntilAvailable(d, conn); err != nil { - return err + if _, err := WaitVPCEndpointServiceAvailable(conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { + return fmt.Errorf("waiting for EC2 VPC Endpoint Service (%s) update: %w", d.Id(), err) } } if d.HasChange("allowed_principals") { - modifyPermReq := &ec2.ModifyVpcEndpointServicePermissionsInput{ + input := &ec2.ModifyVpcEndpointServicePermissionsInput{ ServiceId: aws.String(d.Id()), } setVPCEndpointServiceUpdateLists(d, "allowed_principals", - &modifyPermReq.AddAllowedPrincipals, &modifyPermReq.RemoveAllowedPrincipals) + &input.AddAllowedPrincipals, &input.RemoveAllowedPrincipals) - log.Printf("[DEBUG] Modifying VPC Endpoint Service permissions: %#v", modifyPermReq) - if _, err := conn.ModifyVpcEndpointServicePermissions(modifyPermReq); err != nil { - return fmt.Errorf("Error modifying VPC Endpoint Service permissions: %s", err.Error()) + if _, err := conn.ModifyVpcEndpointServicePermissions(input); err != nil { + return fmt.Errorf("modifying EC2 VPC Endpoint Service (%s) permissions: %w", d.Id(), err) } } @@ -319,7 +324,7 @@ func resourceVPCEndpointServiceUpdate(d *schema.ResourceData, meta interface{}) o, n := d.GetChange("tags_all") if err := UpdateTags(conn, d.Id(), o, n); err != nil { - return fmt.Errorf("error updating EC2 VPC Endpoint Service (%s) tags: %s", d.Id(), err) + return fmt.Errorf("updating EC2 VPC Endpoint Service (%s) tags: %s", d.Id(), err) } } @@ -353,87 +358,19 @@ func resourceVPCEndpointServiceDelete(d *schema.ResourceData, meta interface{}) return nil } -func flattenPrivateDNSNameConfiguration(apiObject *ec2.PrivateDnsNameConfiguration) map[string]interface{} { - if apiObject == nil { - return nil - } - - tfMap := map[string]interface{}{} - - if v := apiObject.Name; v != nil { - tfMap["name"] = aws.StringValue(v) - } - - if v := apiObject.State; v != nil { - tfMap["state"] = aws.StringValue(v) - } - - if v := apiObject.Type; v != nil { - tfMap["type"] = aws.StringValue(v) - } - - if v := apiObject.Value; v != nil { - tfMap["value"] = aws.StringValue(v) - } - - return tfMap -} - -func vpcEndpointServiceStateRefresh(conn *ec2.EC2, svcId string) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - log.Printf("[DEBUG] Reading VPC Endpoint Service Configuration: %s", svcId) - resp, err := conn.DescribeVpcEndpointServiceConfigurations(&ec2.DescribeVpcEndpointServiceConfigurationsInput{ - ServiceIds: aws.StringSlice([]string{svcId}), - }) - if err != nil { - if tfawserr.ErrCodeEquals(err, "InvalidVpcEndpointServiceId.NotFound") { - return false, ec2.ServiceStateDeleted, nil - } - - return nil, "", err - } - - svcCfg := resp.ServiceConfigurations[0] - state := aws.StringValue(svcCfg.ServiceState) - // No use in retrying if the endpoint service is in a failed state. - if state == ec2.ServiceStateFailed { - return nil, state, errors.New("VPC Endpoint Service is in a failed state") - } - return svcCfg, state, nil - } -} +func setVPCEndpointServiceUpdateLists(d *schema.ResourceData, key string, a, r *[]*string) { + o, n := d.GetChange(key) + os := o.(*schema.Set) + ns := n.(*schema.Set) -func vpcEndpointServiceWaitUntilAvailable(d *schema.ResourceData, conn *ec2.EC2) error { - stateConf := &resource.StateChangeConf{ - Pending: []string{ec2.ServiceStatePending}, - Target: []string{ec2.ServiceStateAvailable}, - Refresh: vpcEndpointServiceStateRefresh(conn, d.Id()), - Timeout: 10 * time.Minute, - Delay: 5 * time.Second, - MinTimeout: 5 * time.Second, - } - if _, err := stateConf.WaitForState(); err != nil { - return fmt.Errorf("Error waiting for VPC Endpoint Service %s to become available: %s", d.Id(), err.Error()) + add := flex.ExpandStringSet(ns.Difference(os)) + if len(add) > 0 { + *a = add } - return nil -} - -func setVPCEndpointServiceUpdateLists(d *schema.ResourceData, key string, a, r *[]*string) { - if d.HasChange(key) { - o, n := d.GetChange(key) - os := o.(*schema.Set) - ns := n.(*schema.Set) - - add := flex.ExpandStringSet(ns.Difference(os)) - if len(add) > 0 { - *a = add - } - - remove := flex.ExpandStringSet(os.Difference(ns)) - if len(remove) > 0 { - *r = remove - } + remove := flex.ExpandStringSet(os.Difference(ns)) + if len(remove) > 0 { + *r = remove } } @@ -462,3 +399,29 @@ func flattenAllowedPrincipals(apiObjects []*ec2.AllowedPrincipal) []*string { return tfList } + +func flattenPrivateDNSNameConfiguration(apiObject *ec2.PrivateDnsNameConfiguration) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.Name; v != nil { + tfMap["name"] = aws.StringValue(v) + } + + if v := apiObject.State; v != nil { + tfMap["state"] = aws.StringValue(v) + } + + if v := apiObject.Type; v != nil { + tfMap["type"] = aws.StringValue(v) + } + + if v := apiObject.Value; v != nil { + tfMap["value"] = aws.StringValue(v) + } + + return tfMap +} diff --git a/internal/service/ec2/vpc_endpoint_service_test.go b/internal/service/ec2/vpc_endpoint_service_test.go index 31a2ba051b96..1944242b38ec 100644 --- a/internal/service/ec2/vpc_endpoint_service_test.go +++ b/internal/service/ec2/vpc_endpoint_service_test.go @@ -79,11 +79,10 @@ func TestAccVPCEndpointService_disappears(t *testing.T) { }) } -func TestAccVPCEndpointService_ipTypes(t *testing.T) { +func TestAccVPCEndpointService_tags(t *testing.T) { var svcCfg ec2.ServiceConfiguration resourceName := "aws_vpc_endpoint_service.test" - rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -92,11 +91,11 @@ func TestAccVPCEndpointService_ipTypes(t *testing.T) { CheckDestroy: testAccCheckVPCEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVPCEndpointServiceConfig_ipTypes(rName1, rName2), + Config: testAccVPCEndpointServiceConfig_tags1(rName, "key1", "value1"), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "supported_ip_address_types.#", "1"), - resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv4"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), }, { @@ -104,15 +103,31 @@ func TestAccVPCEndpointService_ipTypes(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + Config: testAccVPCEndpointServiceConfig_tags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccVPCEndpointServiceConfig_tags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, }, }) } -func TestAccVPCEndpointService_allowedPrincipals(t *testing.T) { +func TestAccVPCEndpointService_networkLoadBalancerARNs(t *testing.T) { var svcCfg ec2.ServiceConfiguration resourceName := "aws_vpc_endpoint_service.test" - rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -121,16 +136,10 @@ func TestAccVPCEndpointService_allowedPrincipals(t *testing.T) { CheckDestroy: testAccCheckVPCEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVPCEndpointServiceConfig_allowedPrincipals(rName1, rName2), + Config: testAccVPCEndpointServiceConfig_networkLoadBalancerARNs(rName, 1), 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.#", "1"), - resource.TestCheckResourceAttr(resourceName, "manages_vpc_endpoints", "false"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.Name", rName1), - acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), + resource.TestCheckResourceAttr(resourceName, "gateway_load_balancer_arns.#", "1"), ), }, { @@ -139,36 +148,33 @@ func TestAccVPCEndpointService_allowedPrincipals(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccVPCEndpointServiceConfig_allowedPrincipalsUpdated(rName1, rName2), + Config: testAccVPCEndpointServiceConfig_networkLoadBalancerARNs(rName, 2), Check: resource.ComposeTestCheckFunc( 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.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.Name", rName1), + resource.TestCheckResourceAttr(resourceName, "gateway_load_balancer_arns.#", "2"), ), }, }, }) } -func TestAccVPCEndpointService_gatewayLoadBalancerARNs(t *testing.T) { +func TestAccVPCEndpointService_supportedIPAddressTypes(t *testing.T) { var svcCfg ec2.ServiceConfiguration resourceName := "aws_vpc_endpoint_service.test" rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckELBv2GatewayLoadBalancer(t) }, + PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), ProviderFactories: acctest.ProviderFactories, CheckDestroy: testAccCheckVPCEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVPCEndpointServiceConfig_gatewayLoadBalancerARNs(rName, 1), + Config: testAccVPCEndpointServiceConfig_supportedIPAddressTypesIPv4(rName), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "gateway_load_balancer_arns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "supported_ip_address_types.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv4"), ), }, { @@ -177,21 +183,22 @@ func TestAccVPCEndpointService_gatewayLoadBalancerARNs(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccVPCEndpointServiceConfig_gatewayLoadBalancerARNs(rName, 2), + Config: testAccVPCEndpointServiceConfig_supportedIPAddressTypesIPv4AndIPv6(rName), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "gateway_load_balancer_arns.#", "2"), + resource.TestCheckResourceAttr(resourceName, "supported_ip_address_types.#", "2"), + resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv4"), + resource.TestCheckTypeSetElemAttr(resourceName, "supported_ip_address_types.*", "ipv6"), ), }, }, }) } -func TestAccVPCEndpointService_tags(t *testing.T) { +func TestAccVPCEndpointService_allowedPrincipals(t *testing.T) { var svcCfg ec2.ServiceConfiguration resourceName := "aws_vpc_endpoint_service.test" - rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -200,11 +207,10 @@ func TestAccVPCEndpointService_tags(t *testing.T) { CheckDestroy: testAccCheckVPCEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVPCEndpointServiceConfig_tags1(rName1, rName2, "key1", "value1"), + Config: testAccVPCEndpointServiceConfig_allowedPrincipals(rName, 1), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + resource.TestCheckResourceAttr(resourceName, "allowed_principals.#", "1"), ), }, { @@ -213,31 +219,63 @@ func TestAccVPCEndpointService_tags(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccVPCEndpointServiceConfig_tags2(rName1, rName2, "key1", "value1updated", "key2", "value2"), + Config: testAccVPCEndpointServiceConfig_allowedPrincipals(rName, 0), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), - resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), - resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + resource.TestCheckResourceAttr(resourceName, "allowed_principals.#", "0"), ), }, { - Config: testAccVPCEndpointServiceConfig_tags1(rName1, rName2, "key2", "value2"), + Config: testAccVPCEndpointServiceConfig_allowedPrincipals(rName, 1), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + resource.TestCheckResourceAttr(resourceName, "allowed_principals.#", "1"), ), }, }, }) } -func TestAccVPCEndpointService_PrivateDNS_name(t *testing.T) { +func TestAccVPCEndpointService_gatewayLoadBalancerARNs(t *testing.T) { var svcCfg ec2.ServiceConfiguration resourceName := "aws_vpc_endpoint_service.test" - rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckELBv2GatewayLoadBalancer(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckVPCEndpointServiceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccVPCEndpointServiceConfig_gatewayLoadBalancerARNs(rName, 1), + Check: resource.ComposeTestCheckFunc( + testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), + resource.TestCheckResourceAttr(resourceName, "gateway_load_balancer_arns.#", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccVPCEndpointServiceConfig_gatewayLoadBalancerARNs(rName, 2), + Check: resource.ComposeTestCheckFunc( + testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), + resource.TestCheckResourceAttr(resourceName, "gateway_load_balancer_arns.#", "2"), + ), + }, + }, + }) +} + +func TestAccVPCEndpointService_privateDNSName(t *testing.T) { + var svcCfg ec2.ServiceConfiguration + resourceName := "aws_vpc_endpoint_service.test" + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit + domainName1 := acctest.RandomSubdomain() + domainName2 := acctest.RandomSubdomain() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -246,10 +284,10 @@ func TestAccVPCEndpointService_PrivateDNS_name(t *testing.T) { CheckDestroy: testAccCheckVPCEndpointServiceDestroy, Steps: []resource.TestStep{ { - Config: testAccVPCEndpointServiceConfig_privateDNSName(rName1, rName2, "example.com"), + Config: testAccVPCEndpointServiceConfig_privateDNSName(rName, domainName1), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "private_dns_name", "example.com"), + resource.TestCheckResourceAttr(resourceName, "private_dns_name", domainName1), resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.0.type", "TXT"), ), @@ -260,10 +298,10 @@ func TestAccVPCEndpointService_PrivateDNS_name(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccVPCEndpointServiceConfig_privateDNSName(rName1, rName2, "changed.example.com"), + Config: testAccVPCEndpointServiceConfig_privateDNSName(rName, domainName2), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "private_dns_name", "changed.example.com"), + resource.TestCheckResourceAttr(resourceName, "private_dns_name", domainName2), resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "private_dns_name_configuration.0.type", "TXT"), ), @@ -321,8 +359,8 @@ func testAccCheckVPCEndpointServiceExists(n string, v *ec2.ServiceConfiguration) } } -func testAccVPCEndpointServiceConfig_base(rName1, rName2 string) string { - return fmt.Sprintf(` +func testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName string, count int) string { + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" @@ -331,79 +369,42 @@ resource "aws_vpc" "test" { } } -resource "aws_lb" "test1" { - name = %[1]q - - subnets = [ - aws_subnet.test1.id, - aws_subnet.test2.id, - ] +resource "aws_subnet" "test" { + count = 2 - load_balancer_type = "network" - internal = true - idle_timeout = 60 - enable_deletion_protection = false + vpc_id = aws_vpc.test.id + cidr_block = cidrsubnet(aws_vpc.test.cidr_block, 8, count.index) + availability_zone = data.aws_availability_zones.available.names[count.index] tags = { Name = %[1]q } } -resource "aws_lb" "test2" { - name = %[2]q +resource "aws_lb" "test" { + count = %[2]d - subnets = [ - aws_subnet.test1.id, - aws_subnet.test2.id, - ] + load_balancer_type = "network" + name = "%[1]s-${count.index}" + + subnets = aws_subnet.test[*].id - load_balancer_type = "network" internal = true idle_timeout = 60 enable_deletion_protection = false - tags = { - Name = %[2]q - } -} - -data "aws_availability_zones" "available" { - state = "available" - - filter { - name = "opt-in-status" - values = ["opt-in-not-required"] - } -} - -resource "aws_subnet" "test1" { - vpc_id = aws_vpc.test.id - cidr_block = "10.0.1.0/24" - availability_zone = data.aws_availability_zones.available.names[0] - - tags = { - Name = %[1]q - } -} - -resource "aws_subnet" "test2" { - vpc_id = aws_vpc.test.id - cidr_block = "10.0.2.0/24" - availability_zone = data.aws_availability_zones.available.names[1] - tags = { Name = %[1]q } } - -data "aws_caller_identity" "current" {} -`, rName1, rName2) +`, rName, count)) } -func testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName string, count int) string { +func testAccVPCEndpointServiceConfig_supportedIPAddressTypesBase(rName string) string { return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` resource "aws_vpc" "test" { - cidr_block = "10.0.0.0/16" + cidr_block = "10.0.0.0/16" + assign_generated_ipv6_cidr_block = true tags = { Name = %[1]q @@ -416,6 +417,7 @@ resource "aws_subnet" "test" { vpc_id = aws_vpc.test.id cidr_block = cidrsubnet(aws_vpc.test.cidr_block, 8, count.index) availability_zone = data.aws_availability_zones.available.names[count.index] + ipv6_cidr_block = cidrsubnet(aws_vpc.test.ipv6_cidr_block, 8, count.index) tags = { Name = %[1]q @@ -423,10 +425,8 @@ resource "aws_subnet" "test" { } resource "aws_lb" "test" { - count = %[2]d - load_balancer_type = "network" - name = "%[1]s-${count.index}" + name = %[1]q subnets = aws_subnet.test[*].id @@ -434,27 +434,26 @@ resource "aws_lb" "test" { idle_timeout = 60 enable_deletion_protection = false + ip_address_type = "dualstack" + tags = { Name = %[1]q } } -`, rName, count)) +`, rName)) } func testAccVPCEndpointServiceConfig_basic(rName string) string { return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, 1), ` resource "aws_vpc_endpoint_service" "test" { - acceptance_required = false - + acceptance_required = false network_load_balancer_arns = aws_lb.test[*].arn } `) } func testAccVPCEndpointServiceConfig_gatewayLoadBalancerARNs(rName string, count int) string { - return acctest.ConfigCompose( - acctest.ConfigAvailableAZsNoOptIn(), - fmt.Sprintf(` + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` resource "aws_vpc" "test" { cidr_block = "10.10.10.0/25" @@ -495,89 +494,69 @@ resource "aws_vpc_endpoint_service" "test" { `, rName, count)) } -func testAccVPCEndpointServiceConfig_networkLoadBalancerARNs(rName1, rName2 string) string { - return acctest.ConfigCompose( - testAccVPCEndpointServiceConfig_base(rName1, rName2), - ` +func testAccVPCEndpointServiceConfig_networkLoadBalancerARNs(rName string, count int) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, count), fmt.Sprintf(` resource "aws_vpc_endpoint_service" "test" { - acceptance_required = false + acceptance_required = false + network_load_balancer_arns = aws_lb.test[*].arn - network_load_balancer_arns = [ - aws_lb.test1.arn, - ] + tags = { + Name = %[1]q + } } -`) +`, rName)) } -func testAccVPCEndpointServiceConfig_ipTypes(rName1, rName2 string) string { - return acctest.ConfigCompose( - testAccVPCEndpointServiceConfig_base(rName1, rName2), - ` +func testAccVPCEndpointServiceConfig_supportedIPAddressTypesIPv4(rName string) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_supportedIPAddressTypesBase(rName), fmt.Sprintf(` resource "aws_vpc_endpoint_service" "test" { - acceptance_required = false - - network_load_balancer_arns = [ - aws_lb.test1.arn, - ] - + acceptance_required = false + network_load_balancer_arns = aws_lb.test[*].arn supported_ip_address_types = ["ipv4"] + + tags = { + Name = %[1]q + } } -`) +`, rName)) } -func testAccVPCEndpointServiceConfig_allowedPrincipals(rName1, rName2 string) string { - return acctest.ConfigCompose( - testAccVPCEndpointServiceConfig_base(rName1, rName2), - fmt.Sprintf(` +func testAccVPCEndpointServiceConfig_supportedIPAddressTypesIPv4AndIPv6(rName string) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_supportedIPAddressTypesBase(rName), fmt.Sprintf(` resource "aws_vpc_endpoint_service" "test" { - acceptance_required = false - - network_load_balancer_arns = [ - aws_lb.test1.arn, - ] - - allowed_principals = [ - data.aws_caller_identity.current.arn, - ] + acceptance_required = false + network_load_balancer_arns = aws_lb.test[*].arn + supported_ip_address_types = ["ipv4", "ipv6"] tags = { Name = %[1]q } } -`, rName1)) +`, rName)) } -func testAccVPCEndpointServiceConfig_allowedPrincipalsUpdated(rName1, rName2 string) string { - return acctest.ConfigCompose( - testAccVPCEndpointServiceConfig_base(rName1, rName2), - fmt.Sprintf(` -resource "aws_vpc_endpoint_service" "test" { - acceptance_required = true +func testAccVPCEndpointServiceConfig_allowedPrincipals(rName string, count int) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, 1), fmt.Sprintf(` +data "aws_caller_identity" "current" {} - network_load_balancer_arns = [ - aws_lb.test1.arn, - aws_lb.test2.arn, - ] +resource "aws_vpc_endpoint_service" "test" { + acceptance_required = false + network_load_balancer_arns = aws_lb.test[*].arn - allowed_principals = [] + allowed_principals = (%[2]d == 0 ? [] : [data.aws_caller_identity.current.arn]) tags = { Name = %[1]q } } -`, rName1)) +`, rName, count)) } -func testAccVPCEndpointServiceConfig_tags1(rName1, rName2, tagKey1, tagValue1 string) string { - return acctest.ConfigCompose( - testAccVPCEndpointServiceConfig_base(rName1, rName2), - fmt.Sprintf(` +func testAccVPCEndpointServiceConfig_tags1(rName, tagKey1, tagValue1 string) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, 1), fmt.Sprintf(` resource "aws_vpc_endpoint_service" "test" { - acceptance_required = false - - network_load_balancer_arns = [ - aws_lb.test1.arn, - ] + acceptance_required = false + network_load_balancer_arns = aws_lb.test[*].arn tags = { %[1]q = %[2]q @@ -586,16 +565,11 @@ resource "aws_vpc_endpoint_service" "test" { `, tagKey1, tagValue1)) } -func testAccVPCEndpointServiceConfig_tags2(rName1, rName2, tagKey1, tagValue1, tagKey2, tagValue2 string) string { - return acctest.ConfigCompose( - testAccVPCEndpointServiceConfig_base(rName1, rName2), - fmt.Sprintf(` +func testAccVPCEndpointServiceConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, 1), fmt.Sprintf(` resource "aws_vpc_endpoint_service" "test" { - acceptance_required = false - - network_load_balancer_arns = [ - aws_lb.test1.arn, - ] + acceptance_required = false + network_load_balancer_arns = aws_lb.test[*].arn tags = { %[1]q = %[2]q @@ -605,17 +579,16 @@ resource "aws_vpc_endpoint_service" "test" { `, tagKey1, tagValue1, tagKey2, tagValue2)) } -func testAccVPCEndpointServiceConfig_privateDNSName(rName1, rName2, dnsName string) string { - return acctest.ConfigCompose( - testAccVPCEndpointServiceConfig_base(rName1, rName2), - fmt.Sprintf(` +func testAccVPCEndpointServiceConfig_privateDNSName(rName, dnsName string) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, 1), fmt.Sprintf(` resource "aws_vpc_endpoint_service" "test" { - acceptance_required = false - private_dns_name = "%s" + acceptance_required = false + network_load_balancer_arns = aws_lb.test[*].arn + private_dns_name = %[2]q - network_load_balancer_arns = [ - aws_lb.test1.arn, - ] + tags = { + Name = %[1]q + } } -`, dnsName)) +`, rName, dnsName)) } From 97582a91f28d829de2b33c8faf45ce68ddffd1fb Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 12:08:12 -0400 Subject: [PATCH 15/22] Fix typos in 'TestAccVPCEndpointService_networkLoadBalancerARNs'. --- internal/service/ec2/vpc_endpoint_service_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/ec2/vpc_endpoint_service_test.go b/internal/service/ec2/vpc_endpoint_service_test.go index 1944242b38ec..67a22ac70198 100644 --- a/internal/service/ec2/vpc_endpoint_service_test.go +++ b/internal/service/ec2/vpc_endpoint_service_test.go @@ -139,7 +139,7 @@ func TestAccVPCEndpointService_networkLoadBalancerARNs(t *testing.T) { Config: testAccVPCEndpointServiceConfig_networkLoadBalancerARNs(rName, 1), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "gateway_load_balancer_arns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "network_load_balancer_arns.#", "1"), ), }, { @@ -151,7 +151,7 @@ func TestAccVPCEndpointService_networkLoadBalancerARNs(t *testing.T) { Config: testAccVPCEndpointServiceConfig_networkLoadBalancerARNs(rName, 2), Check: resource.ComposeTestCheckFunc( testAccCheckVPCEndpointServiceExists(resourceName, &svcCfg), - resource.TestCheckResourceAttr(resourceName, "gateway_load_balancer_arns.#", "2"), + resource.TestCheckResourceAttr(resourceName, "network_load_balancer_arns.#", "2"), ), }, }, From ba703a7401f4d535b7d56235fb939061f451b5d5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 12:43:53 -0400 Subject: [PATCH 16/22] Generate paginator for 'DescribeVpcEndpointServices'. --- internal/service/ec2/generate.go | 2 +- internal/service/ec2/list_pages_gen.go | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/internal/service/ec2/generate.go b/internal/service/ec2/generate.go index f85c6ad795a7..987c7c0e0ace 100644 --- a/internal/service/ec2/generate.go +++ b/internal/service/ec2/generate.go @@ -1,7 +1,7 @@ //go:generate go run ../../generate/tagresource/main.go -IDAttribName=resource_id //go:generate go run ../../generate/tags/main.go -GetTag -ListTags -ListTagsOp=DescribeTags -ListTagsInFiltIDName=resource-id -ListTagsInIDElem=Resources -ServiceTagsSlice -TagOp=CreateTags -TagInIDElem=Resources -TagInIDNeedSlice=yes -TagType2=TagDescription -UntagOp=DeleteTags -UntagInNeedTagType -UntagInTagsElem=Tags -UpdateTags //go:generate go run generate/createtags/main.go -//go:generate go run ../../generate/listpages/main.go -ListOps=DescribeSpotFleetInstances,DescribeSpotFleetRequestHistory +//go:generate go run ../../generate/listpages/main.go -ListOps=DescribeSpotFleetInstances,DescribeSpotFleetRequestHistory,DescribeVpcEndpointServices // ONLY generate directives and package declaration! Do not add anything else to this file. package ec2 diff --git a/internal/service/ec2/list_pages_gen.go b/internal/service/ec2/list_pages_gen.go index d8acffa16bed..c19d4b5bc723 100644 --- a/internal/service/ec2/list_pages_gen.go +++ b/internal/service/ec2/list_pages_gen.go @@ -1,4 +1,4 @@ -// Code generated by "internal/generate/listpages/main.go -ListOps=DescribeSpotFleetInstances,DescribeSpotFleetRequestHistory"; DO NOT EDIT. +// Code generated by "internal/generate/listpages/main.go -ListOps=DescribeSpotFleetInstances,DescribeSpotFleetRequestHistory,DescribeVpcEndpointServices"; DO NOT EDIT. package ec2 @@ -50,3 +50,24 @@ func describeSpotFleetRequestHistoryPagesWithContext(ctx context.Context, conn * } return nil } + +func describeVPCEndpointServicesPages(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServicesInput, fn func(*ec2.DescribeVpcEndpointServicesOutput, bool) bool) error { + return describeVPCEndpointServicesPagesWithContext(context.Background(), conn, input, fn) +} + +func describeVPCEndpointServicesPagesWithContext(ctx context.Context, conn *ec2.EC2, input *ec2.DescribeVpcEndpointServicesInput, fn func(*ec2.DescribeVpcEndpointServicesOutput, bool) bool) error { + for { + output, err := conn.DescribeVpcEndpointServicesWithContext(ctx, input) + if err != nil { + return err + } + + lastPage := aws.StringValue(output.NextToken) == "" + if !fn(output, lastPage) || lastPage { + break + } + + input.NextToken = output.NextToken + } + return nil +} From 07cba859f98cbbcd37a2f513c6bb33ea283e8b6f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 12:47:33 -0400 Subject: [PATCH 17/22] Revert "Use 'aws_iam_session_context' to obtain issuer ARN." This reverts commit 419e077adcc1d2d3d57d1e7b3beed1a9a886cabe. --- ...ource_aws_vpc_endpoint_service_allowed_principal_test.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go b/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go index 521a1dacabb2..eb0981714cdd 100644 --- a/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go +++ b/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go @@ -138,10 +138,6 @@ resource "aws_subnet" "test" { data "aws_caller_identity" "current" {} -data "aws_iam_session_context" "current" { - arn = data.aws_caller_identity.current.arn -} - resource "aws_vpc_endpoint_service" "test" { acceptance_required = false @@ -157,7 +153,7 @@ resource "aws_vpc_endpoint_service" "test" { resource "aws_vpc_endpoint_service_allowed_principal" "test" { vpc_endpoint_service_id = aws_vpc_endpoint_service.test.id - principal_arn = data.aws_iam_session_context.current.issuer_arn + principal_arn = data.aws_caller_identity.current.arn } `, rName)) } From 62d841a48506e61cb51e81af36b05f5518d4d7d6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 12:47:43 -0400 Subject: [PATCH 18/22] Revert "r/aws_vpc_endpoint_service_allowed_principal: Tidy up acceptance test." This reverts commit 561c22f3012b102c46243091f64ac694f68c0102. --- ...endpoint_service_allowed_principal_test.go | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go b/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go index eb0981714cdd..cf07c24a8b37 100644 --- a/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go +++ b/aws/resource_aws_vpc_endpoint_service_allowed_principal_test.go @@ -13,8 +13,7 @@ import ( ) func TestAccAWSVpcEndpointServiceAllowedPrincipal_basic(t *testing.T) { - resourceName := "aws_vpc_endpoint_service_allowed_principal.test" - rName := acctest.RandomWithPrefix("tf-acc-test") + lbName := fmt.Sprintf("testaccawsnlb-basic-%s", acctest.RandString(10)) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -23,9 +22,9 @@ func TestAccAWSVpcEndpointServiceAllowedPrincipal_basic(t *testing.T) { CheckDestroy: testAccCheckVpcEndpointServiceAllowedPrincipalDestroy, Steps: []resource.TestStep{ { - Config: testAccVpcEndpointServiceAllowedPrincipalConfig(rName), + Config: testAccVpcEndpointServiceAllowedPrincipalBasicConfig(lbName), Check: resource.ComposeTestCheckFunc( - testAccCheckVpcEndpointServiceAllowedPrincipalExists(resourceName), + testAccCheckVpcEndpointServiceAllowedPrincipalExists("aws_vpc_endpoint_service_allowed_principal.foo"), ), }, }, @@ -95,23 +94,23 @@ func testAccCheckVpcEndpointServiceAllowedPrincipalExists(n string) resource.Tes } } -func testAccVpcEndpointServiceAllowedPrincipalConfig(rName string) string { +func testAccVpcEndpointServiceAllowedPrincipalBasicConfig(lbName string) string { return composeConfig(testAccAvailableAZsNoOptInConfig(), fmt.Sprintf( ` -resource "aws_vpc" "test" { +resource "aws_vpc" "nlb_test" { cidr_block = "10.0.0.0/16" tags = { - Name = %[1]q + Name = "terraform-testacc-vpc-endpoint-service-allowed-principal" } } -resource "aws_lb" "test" { - name = %[1]q +resource "aws_lb" "nlb_test_1" { + name = "%s" subnets = [ - aws_subnet.test[0].id, - aws_subnet.test[1].id, + aws_subnet.nlb_test_1.id, + aws_subnet.nlb_test_2.id, ] load_balancer_type = "network" @@ -120,40 +119,44 @@ resource "aws_lb" "test" { enable_deletion_protection = false tags = { - Name = %[1]q + Name = "testAccVpcEndpointServiceBasicConfig_nlb1" } } -resource "aws_subnet" "test" { - count = 2 +resource "aws_subnet" "nlb_test_1" { + vpc_id = aws_vpc.nlb_test.id + cidr_block = "10.0.1.0/24" + availability_zone = data.aws_availability_zones.available.names[0] - vpc_id = aws_vpc.test.id - cidr_block = cidrsubnet(aws_vpc.test.cidr_block, 2, count.index) - availability_zone = data.aws_availability_zones.available.names[count.index] + tags = { + Name = "tf-acc-vpc-endpoint-service-allowed-principal-1" + } +} + +resource "aws_subnet" "nlb_test_2" { + vpc_id = aws_vpc.nlb_test.id + cidr_block = "10.0.2.0/24" + availability_zone = data.aws_availability_zones.available.names[1] tags = { - Name = %[1]q + Name = "tf-acc-vpc-endpoint-service-allowed-principal-2" } } data "aws_caller_identity" "current" {} -resource "aws_vpc_endpoint_service" "test" { +resource "aws_vpc_endpoint_service" "foo" { acceptance_required = false network_load_balancer_arns = [ - aws_lb.test.arn, + aws_lb.nlb_test_1.id, ] - - tags = { - Name = %[1]q - } } -resource "aws_vpc_endpoint_service_allowed_principal" "test" { - vpc_endpoint_service_id = aws_vpc_endpoint_service.test.id +resource "aws_vpc_endpoint_service_allowed_principal" "foo" { + vpc_endpoint_service_id = aws_vpc_endpoint_service.foo.id principal_arn = data.aws_caller_identity.current.arn } -`, rName)) +`, lbName)) } From 039202ff5f56925da7f9d2413fc2c74a60d41a0f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 13:17:36 -0400 Subject: [PATCH 19/22] Use 'aws_iam_session_context' to obtain issuer ARN. --- internal/service/ec2/vpc_endpoint_service_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/service/ec2/vpc_endpoint_service_test.go b/internal/service/ec2/vpc_endpoint_service_test.go index 67a22ac70198..d509127c98ad 100644 --- a/internal/service/ec2/vpc_endpoint_service_test.go +++ b/internal/service/ec2/vpc_endpoint_service_test.go @@ -539,11 +539,15 @@ func testAccVPCEndpointServiceConfig_allowedPrincipals(rName string, count int) return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, 1), fmt.Sprintf(` data "aws_caller_identity" "current" {} +data "aws_iam_session_context" "current" { + arn = data.aws_caller_identity.current.arn +} + resource "aws_vpc_endpoint_service" "test" { acceptance_required = false network_load_balancer_arns = aws_lb.test[*].arn - allowed_principals = (%[2]d == 0 ? [] : [data.aws_caller_identity.current.arn]) + allowed_principals = (%[2]d == 0 ? [] : [data.aws_iam_session_context.current.issuer_arn]) tags = { Name = %[1]q From 30f2af6a2b3cf6c6377ee3628d08bd7409f43f16 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 13:48:33 -0400 Subject: [PATCH 20/22] r/aws_vpc_endpoint_service_allowed_principal: Tidy up. Acceptance test output: % make testacc TESTARGS='-run=TestAccVPCEndpointServiceAllowedPrincipal_basic' PKG=ec2 ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 2 -run=TestAccVPCEndpointServiceAllowedPrincipal_basic -timeout 180m === RUN TestAccVPCEndpointServiceAllowedPrincipal_basic === PAUSE TestAccVPCEndpointServiceAllowedPrincipal_basic === CONT TestAccVPCEndpointServiceAllowedPrincipal_basic --- PASS: TestAccVPCEndpointServiceAllowedPrincipal_basic (238.55s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 246.202s --- internal/service/ec2/find.go | 18 +++ .../vpc_endpoint_service_allowed_principal.go | 85 +++++------- ...endpoint_service_allowed_principal_test.go | 121 +++++------------- 3 files changed, 76 insertions(+), 148 deletions(-) diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 339f3bd7e4ab..0fcdf7cbe953 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -2718,6 +2718,24 @@ func FindVPCEndpointServicePermissionsByID(conn *ec2.EC2, id string) ([]*ec2.All return FindVPCEndpointServicePermissions(conn, input) } +func FindVPCEndpointServicePermissionExists(conn *ec2.EC2, serviceID, principalARN string) error { + allowedPrincipals, err := FindVPCEndpointServicePermissionsByID(conn, serviceID) + + if err != nil { + return err + } + + for _, v := range allowedPrincipals { + if aws.StringValue(v.Principal) == principalARN { + return nil + } + } + + return &resource.NotFoundError{ + LastError: fmt.Errorf("VPC Endpoint Service (%s) Principal (%s) not found", serviceID, principalARN), + } +} + // FindVPCEndpointRouteTableAssociationExists returns NotFoundError if no association for the specified VPC endpoint and route table IDs is found. func FindVPCEndpointRouteTableAssociationExists(conn *ec2.EC2, vpcEndpointID string, routeTableID string) error { vpcEndpoint, err := FindVPCEndpointByID(conn, vpcEndpointID) diff --git a/internal/service/ec2/vpc_endpoint_service_allowed_principal.go b/internal/service/ec2/vpc_endpoint_service_allowed_principal.go index f82f4bf1bea5..0a12a4d9c092 100644 --- a/internal/service/ec2/vpc_endpoint_service_allowed_principal.go +++ b/internal/service/ec2/vpc_endpoint_service_allowed_principal.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func ResourceVPCEndpointServiceAllowedPrincipal() *schema.Resource { @@ -19,12 +20,12 @@ func ResourceVPCEndpointServiceAllowedPrincipal() *schema.Resource { Delete: resourceVPCEndpointServiceAllowedPrincipalDelete, Schema: map[string]*schema.Schema{ - "vpc_endpoint_service_id": { + "principal_arn": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "principal_arn": { + "vpc_endpoint_service_id": { Type: schema.TypeString, Required: true, ForceNew: true, @@ -36,23 +37,19 @@ func ResourceVPCEndpointServiceAllowedPrincipal() *schema.Resource { func resourceVPCEndpointServiceAllowedPrincipalCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - svcId := d.Get("vpc_endpoint_service_id").(string) - arn := d.Get("principal_arn").(string) - - _, err := findResourceVPCEndpointServiceAllowedPrincipals(conn, svcId) - if err != nil { - return err - } + serviceID := d.Get("vpc_endpoint_service_id").(string) + principalARN := d.Get("principal_arn").(string) - _, err = conn.ModifyVpcEndpointServicePermissions(&ec2.ModifyVpcEndpointServicePermissionsInput{ - ServiceId: aws.String(svcId), - AddAllowedPrincipals: aws.StringSlice([]string{arn}), + _, err := conn.ModifyVpcEndpointServicePermissions(&ec2.ModifyVpcEndpointServicePermissionsInput{ + AddAllowedPrincipals: aws.StringSlice([]string{principalARN}), + ServiceId: aws.String(serviceID), }) + if err != nil { - return fmt.Errorf("Error creating VPC Endpoint Service allowed principal: %s", err.Error()) + return fmt.Errorf("modifying EC2 VPC Endpoint Service (%s) permissions: %w", serviceID, err) } - d.SetId(vpcEndpointServiceIdPrincipalARNHash(svcId, arn)) + d.SetId(fmt.Sprintf("a-%s%d", serviceID, create.StringHashcode(principalARN))) return resourceVPCEndpointServiceAllowedPrincipalRead(d, meta) } @@ -60,66 +57,42 @@ func resourceVPCEndpointServiceAllowedPrincipalCreate(d *schema.ResourceData, me func resourceVPCEndpointServiceAllowedPrincipalRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - svcId := d.Get("vpc_endpoint_service_id").(string) - arn := d.Get("principal_arn").(string) - - principals, err := findResourceVPCEndpointServiceAllowedPrincipals(conn, svcId) - if err != nil { - if tfawserr.ErrCodeEquals(err, "InvalidVpcEndpointServiceId.NotFound") { - log.Printf("[WARN]VPC Endpoint Service (%s) not found, removing VPC Endpoint Service allowed principal (%s) from state", svcId, d.Id()) - d.SetId("") - return nil - } + serviceID := d.Get("vpc_endpoint_service_id").(string) + principalARN := d.Get("principal_arn").(string) - return err - } + err := FindVPCEndpointServicePermissionExists(conn, serviceID, principalARN) - found := false - for _, principal := range principals { - if aws.StringValue(principal.Principal) == arn { - found = true - break - } - } - if !found { - log.Printf("[WARN] VPC Endpoint Service allowed principal (%s) not found, removing from state", d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] EC2 VPC Endpoint Service Allowed Principal %s not found, removing from state", d.Id()) d.SetId("") return nil } + if err != nil { + return fmt.Errorf("reading EC2 VPC Endpoint Service (%s) Allowed Principal (%s): %w", serviceID, principalARN, err) + } + return nil } func resourceVPCEndpointServiceAllowedPrincipalDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - svcId := d.Get("vpc_endpoint_service_id").(string) - arn := d.Get("principal_arn").(string) + serviceID := d.Get("vpc_endpoint_service_id").(string) + principalARN := d.Get("principal_arn").(string) _, err := conn.ModifyVpcEndpointServicePermissions(&ec2.ModifyVpcEndpointServicePermissionsInput{ - ServiceId: aws.String(svcId), - RemoveAllowedPrincipals: aws.StringSlice([]string{arn}), + RemoveAllowedPrincipals: aws.StringSlice([]string{principalARN}), + ServiceId: aws.String(serviceID), }) - if err != nil { - if !tfawserr.ErrCodeEquals(err, "InvalidVpcEndpointServiceId.NotFound") { - return fmt.Errorf("Error deleting VPC Endpoint Service allowed principal: %s", err.Error()) - } - } - return nil -} + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIDNotFound) { + return nil + } -func findResourceVPCEndpointServiceAllowedPrincipals(conn *ec2.EC2, id string) ([]*ec2.AllowedPrincipal, error) { - resp, err := conn.DescribeVpcEndpointServicePermissions(&ec2.DescribeVpcEndpointServicePermissionsInput{ - ServiceId: aws.String(id), - }) if err != nil { - return nil, err + return fmt.Errorf("modifying EC2 VPC Endpoint Service (%s) permissions: %w", serviceID, err) } - return resp.AllowedPrincipals, nil -} - -func vpcEndpointServiceIdPrincipalARNHash(svcId, arn string) string { - return fmt.Sprintf("a-%s%d", svcId, create.StringHashcode(arn)) + return nil } diff --git a/internal/service/ec2/vpc_endpoint_service_allowed_principal_test.go b/internal/service/ec2/vpc_endpoint_service_allowed_principal_test.go index a6934db58f74..3b26c860b0d3 100644 --- a/internal/service/ec2/vpc_endpoint_service_allowed_principal_test.go +++ b/internal/service/ec2/vpc_endpoint_service_allowed_principal_test.go @@ -4,18 +4,19 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func TestAccVPCEndpointServiceAllowedPrincipal_basic(t *testing.T) { - lbName := fmt.Sprintf("testAccNLB-basic-%s", sdkacctest.RandString(10)) + resourceName := "aws_vpc_endpoint_service_allowed_principal.test" + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -24,9 +25,9 @@ func TestAccVPCEndpointServiceAllowedPrincipal_basic(t *testing.T) { CheckDestroy: testAccCheckVPCEndpointServiceAllowedPrincipalDestroy, Steps: []resource.TestStep{ { - Config: testAccVPCEndpointServiceAllowedPrincipalConfig_basic(lbName), + Config: testAccVPCEndpointServiceAllowedPrincipalConfig_basic(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVPCEndpointServiceAllowedPrincipalExists("aws_vpc_endpoint_service_allowed_principal.foo"), + testAccCheckVPCEndpointServiceAllowedPrincipalExists(resourceName), ), }, }, @@ -41,26 +42,17 @@ func testAccCheckVPCEndpointServiceAllowedPrincipalDestroy(s *terraform.State) e continue } - // Try to find the resource - resp, err := conn.DescribeVpcEndpointServicePermissions(&ec2.DescribeVpcEndpointServicePermissionsInput{ - ServiceId: aws.String(rs.Primary.Attributes["vpc_endpoint_service_id"]), - }) - if err != nil { - // Verify the error is what we want - ec2err, ok := err.(awserr.Error) - if !ok { - return err - } - if ec2err.Code() != "InvalidVpcEndpointServiceId.NotFound" { - return err - } - return nil + err := tfec2.FindVPCEndpointServicePermissionExists(conn, rs.Primary.Attributes["vpc_endpoint_service_id"], rs.Primary.Attributes["principal_arn"]) + + if tfresource.NotFound(err) { + continue } - if len(resp.AllowedPrincipals) > 0 { - return fmt.Errorf( - "VCP Endpoint Service %s has allowed principals", rs.Primary.Attributes["vpc_endpoint_service_id"]) + if err != nil { + return err } + + return fmt.Errorf("EC2 VPC Endpoint Service Allowed Principal %s still exists", rs.Primary.ID) } return nil @@ -74,91 +66,36 @@ func testAccCheckVPCEndpointServiceAllowedPrincipalExists(n string) resource.Tes } if rs.Primary.ID == "" { - return fmt.Errorf("No VPC Endpoint Service ID is set") + return fmt.Errorf("No EC2 VPC Endpoint Service Allowed Principal ID is set") } conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn - resp, err := conn.DescribeVpcEndpointServicePermissions(&ec2.DescribeVpcEndpointServicePermissionsInput{ - ServiceId: aws.String(rs.Primary.Attributes["vpc_endpoint_service_id"]), - }) - if err != nil { - return err - } - - for _, principal := range resp.AllowedPrincipals { - if aws.StringValue(principal.Principal) == rs.Primary.Attributes["principal_arn"] { - return nil - } - } - - return fmt.Errorf("VPC Endpoint Service allowed principal not found") + return tfec2.FindVPCEndpointServicePermissionExists(conn, rs.Primary.Attributes["vpc_endpoint_service_id"], rs.Primary.Attributes["principal_arn"]) } } -func testAccVPCEndpointServiceAllowedPrincipalConfig_basic(lbName string) string { - return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf( - ` -resource "aws_vpc" "nlb_test" { - cidr_block = "10.0.0.0/16" - - tags = { - Name = "terraform-testacc-vpc-endpoint-service-allowed-principal" - } -} - -resource "aws_lb" "nlb_test_1" { - 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_nlb1" - } -} - -resource "aws_subnet" "nlb_test_1" { - vpc_id = aws_vpc.nlb_test.id - cidr_block = "10.0.1.0/24" - availability_zone = data.aws_availability_zones.available.names[0] +func testAccVPCEndpointServiceAllowedPrincipalConfig_basic(rName string) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, 1), fmt.Sprintf(` +data "aws_caller_identity" "current" {} - tags = { - Name = "tf-acc-vpc-endpoint-service-allowed-principal-1" - } +data "aws_iam_session_context" "current" { + arn = data.aws_caller_identity.current.arn } -resource "aws_subnet" "nlb_test_2" { - vpc_id = aws_vpc.nlb_test.id - cidr_block = "10.0.2.0/24" - availability_zone = data.aws_availability_zones.available.names[1] +resource "aws_vpc_endpoint_service" "test" { + acceptance_required = false + network_load_balancer_arns = aws_lb.test[*].arn tags = { - Name = "tf-acc-vpc-endpoint-service-allowed-principal-2" + Name = %[1]q } } -data "aws_caller_identity" "current" {} - -resource "aws_vpc_endpoint_service" "foo" { - acceptance_required = false - - network_load_balancer_arns = [ - aws_lb.nlb_test_1.id, - ] -} - -resource "aws_vpc_endpoint_service_allowed_principal" "foo" { - vpc_endpoint_service_id = aws_vpc_endpoint_service.foo.id +resource "aws_vpc_endpoint_service_allowed_principal" "test" { + vpc_endpoint_service_id = aws_vpc_endpoint_service.test.id - principal_arn = data.aws_caller_identity.current.arn + principal_arn = data.aws_iam_session_context.current.issuer_arn } -`, lbName)) +`, rName)) } From 6f8080e2e2b68ac2e96bd458f05b77ad85307035 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 14:59:44 -0400 Subject: [PATCH 21/22] d/aws_vpc_endpoint_service: Add 'supported_ip_address_types' attribute. Acceptance test output: % make testacc TESTARGS='-run=TestAccVPCEndpointServiceDataSource_' PKG=ec2 ACCTEST_PARALLELISM=2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 2 -run=TestAccVPCEndpointServiceDataSource_ -timeout 180m === RUN TestAccVPCEndpointServiceDataSource_gateway === PAUSE TestAccVPCEndpointServiceDataSource_gateway === RUN TestAccVPCEndpointServiceDataSource_interface === PAUSE TestAccVPCEndpointServiceDataSource_interface === RUN TestAccVPCEndpointServiceDataSource_custom === PAUSE TestAccVPCEndpointServiceDataSource_custom === RUN TestAccVPCEndpointServiceDataSource_Custom_filter === PAUSE TestAccVPCEndpointServiceDataSource_Custom_filter === RUN TestAccVPCEndpointServiceDataSource_CustomFilter_tags === PAUSE TestAccVPCEndpointServiceDataSource_CustomFilter_tags === RUN TestAccVPCEndpointServiceDataSource_ServiceType_gateway === PAUSE TestAccVPCEndpointServiceDataSource_ServiceType_gateway === RUN TestAccVPCEndpointServiceDataSource_ServiceType_interface === PAUSE TestAccVPCEndpointServiceDataSource_ServiceType_interface === CONT TestAccVPCEndpointServiceDataSource_gateway === CONT TestAccVPCEndpointServiceDataSource_CustomFilter_tags === CONT TestAccVPCEndpointServiceDataSource_custom --- PASS: TestAccVPCEndpointServiceDataSource_gateway (13.29s) --- PASS: TestAccVPCEndpointServiceDataSource_CustomFilter_tags (241.21s) === CONT TestAccVPCEndpointServiceDataSource_Custom_filter --- PASS: TestAccVPCEndpointServiceDataSource_custom (243.18s) === CONT TestAccVPCEndpointServiceDataSource_interface --- PASS: TestAccVPCEndpointServiceDataSource_interface (12.97s) === CONT TestAccVPCEndpointServiceDataSource_ServiceType_interface --- PASS: TestAccVPCEndpointServiceDataSource_ServiceType_interface (11.03s) === CONT TestAccVPCEndpointServiceDataSource_ServiceType_gateway --- PASS: TestAccVPCEndpointServiceDataSource_ServiceType_gateway (11.02s) --- PASS: TestAccVPCEndpointServiceDataSource_Custom_filter (249.41s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 494.769s --- .changelog/25189.txt | 4 + internal/service/ec2/errors.go | 1 + internal/service/ec2/find.go | 36 ++++ .../ec2/vpc_endpoint_service_data_source.go | 104 ++++++------ .../vpc_endpoint_service_data_source_test.go | 156 ++++++------------ .../docs/d/vpc_endpoint_service.html.markdown | 1 + 6 files changed, 150 insertions(+), 152 deletions(-) diff --git a/.changelog/25189.txt b/.changelog/25189.txt index 44ccbad1cee7..21dc12068b0d 100644 --- a/.changelog/25189.txt +++ b/.changelog/25189.txt @@ -1,3 +1,7 @@ ```release-note:enhancement resource/aws_vpc_endpoint_service: Add `supported_ip_address_types` argument +``` + +```release-note:enhancement +data-source/aws_vpc_endpoint_service: Add `supported_ip_address_types` attribute ``` \ No newline at end of file diff --git a/internal/service/ec2/errors.go b/internal/service/ec2/errors.go index 6cafce44adb2..d3620d99da79 100644 --- a/internal/service/ec2/errors.go +++ b/internal/service/ec2/errors.go @@ -61,6 +61,7 @@ const ( errCodeInvalidRouteTableIDNotFound = "InvalidRouteTableID.NotFound" errCodeInvalidRouteTableIdNotFound = "InvalidRouteTableId.NotFound" errCodeInvalidSecurityGroupIDNotFound = "InvalidSecurityGroupID.NotFound" + errCodeInvalidServiceName = "InvalidServiceName" errCodeInvalidSnapshotInUse = "InvalidSnapshot.InUse" errCodeInvalidSnapshotNotFound = "InvalidSnapshot.NotFound" ErrCodeInvalidSpotDatafeedNotFound = "InvalidSpotDatafeed.NotFound" diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 0fcdf7cbe953..5289d3c400b7 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -2651,6 +2651,42 @@ func FindVPCEndpointServiceConfigurations(conn *ec2.EC2, input *ec2.DescribeVpcE return output, nil } +func FindVPCEndpointServices(conn *ec2.EC2, input *ec2.DescribeVpcEndpointServicesInput) ([]*ec2.ServiceDetail, []string, error) { + var serviceDetails []*ec2.ServiceDetail + var serviceNames []string + + err := describeVPCEndpointServicesPages(conn, input, func(page *ec2.DescribeVpcEndpointServicesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.ServiceDetails { + if v != nil { + serviceDetails = append(serviceDetails, v) + } + } + + for _, v := range page.ServiceNames { + serviceNames = append(serviceNames, aws.StringValue(v)) + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, errCodeInvalidServiceName) { + return nil, nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, nil, err + } + + return serviceDetails, serviceNames, nil +} + func FindVPCEndpointServiceConfigurationByID(conn *ec2.EC2, id string) (*ec2.ServiceConfiguration, error) { input := &ec2.DescribeVpcEndpointServiceConfigurationsInput{ ServiceIds: aws.StringSlice([]string{id}), diff --git a/internal/service/ec2/vpc_endpoint_service_data_source.go b/internal/service/ec2/vpc_endpoint_service_data_source.go index 1f29b50cfa69..c331c86682b2 100644 --- a/internal/service/ec2/vpc_endpoint_service_data_source.go +++ b/internal/service/ec2/vpc_endpoint_service_data_source.go @@ -2,7 +2,6 @@ package ec2 import ( "fmt" - "log" "strconv" "github.com/aws/aws-sdk-go/aws" @@ -12,7 +11,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" - "github.com/hashicorp/terraform-provider-aws/internal/flex" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" ) @@ -33,14 +31,13 @@ func DataSourceVPCEndpointService() *schema.Resource { 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, }, + "filter": CustomFiltersSchema(), "manages_vpc_endpoints": { Type: schema.TypeBool, Computed: true, @@ -74,12 +71,16 @@ func DataSourceVPCEndpointService() *schema.Resource { Computed: true, ValidateFunc: validation.StringInSlice(ec2.ServiceType_Values(), false), }, + "supported_ip_address_types": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + }, "tags": tftags.TagsSchemaComputed(), "vpc_endpoint_policy_supported": { Type: schema.TypeBool, Computed: true, }, - "filter": DataSourceFiltersSchema(), }, } } @@ -88,54 +89,56 @@ func dataSourceVPCEndpointServiceRead(d *schema.ResourceData, meta interface{}) conn := meta.(*conns.AWSClient).EC2Conn ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - filters, filtersOk := d.GetOk("filter") - tags, tagsOk := d.GetOk("tags") + input := &ec2.DescribeVpcEndpointServicesInput{ + Filters: BuildAttributeFilterList( + map[string]string{ + "service-type": d.Get("service_type").(string), + }, + ), + } var serviceName string - serviceNameOk := false + if v, ok := d.GetOk("service_name"); ok { serviceName = v.(string) - serviceNameOk = true } else if v, ok := d.GetOk("service"); ok { serviceName = fmt.Sprintf("com.amazonaws.%s.%s", meta.(*conns.AWSClient).Region, v.(string)) - serviceNameOk = true } - req := &ec2.DescribeVpcEndpointServicesInput{} - if filtersOk { - req.Filters = BuildFiltersDataSource(filters.(*schema.Set)) - } - if serviceNameOk { - req.ServiceNames = aws.StringSlice([]string{serviceName}) + if serviceName != "" { + input.ServiceNames = aws.StringSlice([]string{serviceName}) } - if v, ok := d.GetOk("service_type"); ok { - req.Filters = append(req.Filters, &ec2.Filter{ - Name: aws.String("service-type"), - Values: aws.StringSlice([]string{v.(string)}), - }) + if v, ok := d.GetOk("tags"); ok { + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(v.(map[string]interface{}))), + )...) } - if tagsOk { - req.Filters = append(req.Filters, tagFiltersFromMap(tags.(map[string]interface{}))...) + input.Filters = append(input.Filters, BuildCustomFilterList( + d.Get("filter").(*schema.Set), + )...) + + if len(input.Filters) == 0 { + // Don't send an empty filters list; the EC2 API won't accept it. + input.Filters = nil } - log.Printf("[DEBUG] Reading VPC Endpoint Service: %s", req) - resp, err := conn.DescribeVpcEndpointServices(req) + serviceDetails, serviceNames, err := FindVPCEndpointServices(conn, input) + if err != nil { - return fmt.Errorf("error reading VPC Endpoint Service (%s): %w", serviceName, err) + return fmt.Errorf("reading EC2 VPC Endpoint Services: %w", err) } - if resp == nil || (len(resp.ServiceNames) == 0 && len(resp.ServiceDetails) == 0) { - return fmt.Errorf("no matching VPC Endpoint Service found") + if len(serviceDetails) == 0 && len(serviceNames) == 0 { + return fmt.Errorf("no matching EC2 VPC Endpoint Service found") } // Note: AWS Commercial now returns a response with `ServiceNames` and // `ServiceDetails`, but GovCloud responses only include `ServiceNames` - if len(resp.ServiceDetails) == 0 { + if len(serviceDetails) == 0 { // GovCloud doesn't respect the filter. - names := aws.StringValueSlice(resp.ServiceNames) - for _, name := range names { + for _, name := range serviceNames { if name == serviceName { d.SetId(strconv.Itoa(create.StringHashcode(name))) d.Set("service_name", name) @@ -143,48 +146,49 @@ func dataSourceVPCEndpointServiceRead(d *schema.ResourceData, meta interface{}) } } - return fmt.Errorf("no matching VPC Endpoint Service found") + return fmt.Errorf("no matching EC2 VPC Endpoint Service found") } - if len(resp.ServiceDetails) > 1 { - return fmt.Errorf("multiple VPC Endpoint Services matched; use additional constraints to reduce matches to a single VPC Endpoint Service") + if len(serviceDetails) > 1 { + return fmt.Errorf("multiple EC2 VPC Endpoint Services matched; use additional constraints to reduce matches to a single EC2 VPC Endpoint Service") } - sd := resp.ServiceDetails[0] - serviceId := aws.StringValue(sd.ServiceId) + sd := serviceDetails[0] + serviceID := aws.StringValue(sd.ServiceId) serviceName = aws.StringValue(sd.ServiceName) d.SetId(strconv.Itoa(create.StringHashcode(serviceName))) + d.Set("acceptance_required", sd.AcceptanceRequired) arn := arn.ARN{ Partition: meta.(*conns.AWSClient).Partition, Service: ec2.ServiceName, Region: meta.(*conns.AWSClient).Region, AccountID: meta.(*conns.AWSClient).AccountID, - Resource: fmt.Sprintf("vpc-endpoint-service/%s", serviceId), + Resource: fmt.Sprintf("vpc-endpoint-service/%s", serviceID), }.String() d.Set("arn", arn) - d.Set("acceptance_required", sd.AcceptanceRequired) - err = d.Set("availability_zones", flex.FlattenStringSet(sd.AvailabilityZones)) - if err != nil { - return fmt.Errorf("error setting availability_zones: %w", err) - } - err = d.Set("base_endpoint_dns_names", flex.FlattenStringSet(sd.BaseEndpointDnsNames)) - if err != nil { - return fmt.Errorf("error setting base_endpoint_dns_names: %w", err) - } + d.Set("availability_zones", aws.StringValueSlice(sd.AvailabilityZones)) + d.Set("base_endpoint_dns_names", aws.StringValueSlice(sd.BaseEndpointDnsNames)) d.Set("manages_vpc_endpoints", sd.ManagesVpcEndpoints) d.Set("owner", sd.Owner) d.Set("private_dns_name", sd.PrivateDnsName) - d.Set("service_id", serviceId) + d.Set("service_id", serviceID) d.Set("service_name", serviceName) - d.Set("service_type", sd.ServiceType[0].ServiceType) + if len(sd.ServiceType) > 0 { + d.Set("service_type", sd.ServiceType[0].ServiceType) + } else { + d.Set("service_type", nil) + } + d.Set("supported_ip_address_types", aws.StringValueSlice(sd.SupportedIpAddressTypes)) + d.Set("vpc_endpoint_policy_supported", sd.VpcEndpointPolicySupported) + err = d.Set("tags", KeyValueTags(sd.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()) + if err != nil { - return fmt.Errorf("error setting tags: %w", err) + return fmt.Errorf("setting tags: %w", err) } - d.Set("vpc_endpoint_policy_supported", sd.VpcEndpointPolicySupported) return nil } diff --git a/internal/service/ec2/vpc_endpoint_service_data_source_test.go b/internal/service/ec2/vpc_endpoint_service_data_source_test.go index 269248e7df93..a284420f426a 100644 --- a/internal/service/ec2/vpc_endpoint_service_data_source_test.go +++ b/internal/service/ec2/vpc_endpoint_service_data_source_test.go @@ -23,17 +23,18 @@ func TestAccVPCEndpointServiceDataSource_gateway(t *testing.T) { { Config: testAccVPCEndpointServiceDataSourceConfig_gateway, Check: resource.ComposeTestCheckFunc( - testAccCheckResourceAttrRegionalReverseDNSService(datasourceName, "service_name", "dynamodb"), resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "false"), - resource.TestCheckResourceAttrPair(datasourceName, "availability_zones.#", "data.aws_availability_zones.available", "names.#"), + acctest.MatchResourceAttrRegionalARN(datasourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), + acctest.CheckResourceAttrGreaterThanValue(datasourceName, "availability_zones.#", "0"), 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", ""), + testAccCheckResourceAttrRegionalReverseDNSService(datasourceName, "service_name", "dynamodb"), resource.TestCheckResourceAttr(datasourceName, "service_type", "Gateway"), - resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "true"), + acctest.CheckResourceAttrGreaterThanValue(datasourceName, "supported_ip_address_types.#", "0"), resource.TestCheckResourceAttr(datasourceName, "tags.%", "0"), - acctest.MatchResourceAttrRegionalARN(datasourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "true"), ), }, }, @@ -51,16 +52,18 @@ func TestAccVPCEndpointServiceDataSource_interface(t *testing.T) { { Config: testAccVPCEndpointServiceDataSourceConfig_interface, Check: resource.ComposeTestCheckFunc( - testAccCheckResourceAttrRegionalReverseDNSService(datasourceName, "service_name", "ec2"), resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "false"), + acctest.MatchResourceAttrRegionalARN(datasourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), + acctest.CheckResourceAttrGreaterThanValue(datasourceName, "availability_zones.#", "0"), resource.TestCheckResourceAttr(datasourceName, "base_endpoint_dns_names.#", "1"), resource.TestCheckResourceAttr(datasourceName, "manages_vpc_endpoints", "false"), resource.TestCheckResourceAttr(datasourceName, "owner", "amazon"), acctest.CheckResourceAttrRegionalHostnameService(datasourceName, "private_dns_name", "ec2"), + testAccCheckResourceAttrRegionalReverseDNSService(datasourceName, "service_name", "ec2"), resource.TestCheckResourceAttr(datasourceName, "service_type", "Interface"), - resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "true"), + acctest.CheckResourceAttrGreaterThanValue(datasourceName, "supported_ip_address_types.#", "0"), resource.TestCheckResourceAttr(datasourceName, "tags.%", "0"), - acctest.MatchResourceAttrRegionalARN(datasourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), + resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "true"), ), }, }, @@ -68,8 +71,9 @@ func TestAccVPCEndpointServiceDataSource_interface(t *testing.T) { } func TestAccVPCEndpointServiceDataSource_custom(t *testing.T) { + resourceName := "aws_vpc_endpoint_service.test" datasourceName := "data.aws_vpc_endpoint_service.test" - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -78,16 +82,18 @@ func TestAccVPCEndpointServiceDataSource_custom(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccVPCEndpointServiceDataSourceConfig_custom(rName), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "true"), - resource.TestCheckResourceAttr(datasourceName, "availability_zones.#", "2"), - resource.TestCheckResourceAttr(datasourceName, "manages_vpc_endpoints", "false"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(datasourceName, "acceptance_required", resourceName, "acceptance_required"), + resource.TestCheckResourceAttrPair(datasourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(datasourceName, "availability_zones.#", resourceName, "availability_zones.#"), + resource.TestCheckResourceAttrPair(datasourceName, "base_endpoint_dns_names.#", resourceName, "base_endpoint_dns_names.#"), + resource.TestCheckResourceAttrPair(datasourceName, "manages_vpc_endpoints", resourceName, "manages_vpc_endpoints"), acctest.CheckResourceAttrAccountID(datasourceName, "owner"), + resource.TestCheckResourceAttrPair(datasourceName, "private_dns_name", resourceName, "private_dns_name"), resource.TestCheckResourceAttr(datasourceName, "service_type", "Interface"), + resource.TestCheckResourceAttrPair(datasourceName, "supported_ip_address_types.#", resourceName, "supported_ip_address_types.#"), + resource.TestCheckResourceAttrPair(datasourceName, "tags.%", resourceName, "tags.%"), resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "false"), - resource.TestCheckResourceAttr(datasourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(datasourceName, "tags.Name", rName), - acctest.MatchResourceAttrRegionalARN(datasourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), ), }, }, @@ -95,8 +101,9 @@ func TestAccVPCEndpointServiceDataSource_custom(t *testing.T) { } func TestAccVPCEndpointServiceDataSource_Custom_filter(t *testing.T) { + resourceName := "aws_vpc_endpoint_service.test" datasourceName := "data.aws_vpc_endpoint_service.test" - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -105,16 +112,18 @@ func TestAccVPCEndpointServiceDataSource_Custom_filter(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccVPCEndpointServiceDataSourceConfig_customFilter(rName), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "true"), - resource.TestCheckResourceAttr(datasourceName, "availability_zones.#", "2"), - resource.TestCheckResourceAttr(datasourceName, "manages_vpc_endpoints", "false"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(datasourceName, "acceptance_required", resourceName, "acceptance_required"), + resource.TestCheckResourceAttrPair(datasourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(datasourceName, "availability_zones.#", resourceName, "availability_zones.#"), + resource.TestCheckResourceAttrPair(datasourceName, "base_endpoint_dns_names.#", resourceName, "base_endpoint_dns_names.#"), + resource.TestCheckResourceAttrPair(datasourceName, "manages_vpc_endpoints", resourceName, "manages_vpc_endpoints"), acctest.CheckResourceAttrAccountID(datasourceName, "owner"), + resource.TestCheckResourceAttrPair(datasourceName, "private_dns_name", resourceName, "private_dns_name"), resource.TestCheckResourceAttr(datasourceName, "service_type", "Interface"), + resource.TestCheckResourceAttrPair(datasourceName, "supported_ip_address_types.#", resourceName, "supported_ip_address_types.#"), + resource.TestCheckResourceAttrPair(datasourceName, "tags.%", resourceName, "tags.%"), resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "false"), - resource.TestCheckResourceAttr(datasourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(datasourceName, "tags.Name", rName), - acctest.MatchResourceAttrRegionalARN(datasourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), ), }, }, @@ -122,8 +131,9 @@ func TestAccVPCEndpointServiceDataSource_Custom_filter(t *testing.T) { } func TestAccVPCEndpointServiceDataSource_CustomFilter_tags(t *testing.T) { + resourceName := "aws_vpc_endpoint_service.test" datasourceName := "data.aws_vpc_endpoint_service.test" - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix("tfacctest") // 32 character limit resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -132,16 +142,18 @@ func TestAccVPCEndpointServiceDataSource_CustomFilter_tags(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccVPCEndpointServiceDataSourceConfig_customFilterTags(rName), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(datasourceName, "acceptance_required", "true"), - resource.TestCheckResourceAttr(datasourceName, "availability_zones.#", "2"), - resource.TestCheckResourceAttr(datasourceName, "manages_vpc_endpoints", "false"), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(datasourceName, "acceptance_required", resourceName, "acceptance_required"), + resource.TestCheckResourceAttrPair(datasourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(datasourceName, "availability_zones.#", resourceName, "availability_zones.#"), + resource.TestCheckResourceAttrPair(datasourceName, "base_endpoint_dns_names.#", resourceName, "base_endpoint_dns_names.#"), + resource.TestCheckResourceAttrPair(datasourceName, "manages_vpc_endpoints", resourceName, "manages_vpc_endpoints"), acctest.CheckResourceAttrAccountID(datasourceName, "owner"), + resource.TestCheckResourceAttrPair(datasourceName, "private_dns_name", resourceName, "private_dns_name"), resource.TestCheckResourceAttr(datasourceName, "service_type", "Interface"), + resource.TestCheckResourceAttrPair(datasourceName, "supported_ip_address_types.#", resourceName, "supported_ip_address_types.#"), + resource.TestCheckResourceAttrPair(datasourceName, "tags.%", resourceName, "tags.%"), resource.TestCheckResourceAttr(datasourceName, "vpc_endpoint_policy_supported", "false"), - resource.TestCheckResourceAttr(datasourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(datasourceName, "tags.Name", rName), - acctest.MatchResourceAttrRegionalARN(datasourceName, "arn", "ec2", regexp.MustCompile(`vpc-endpoint-service/vpce-svc-.+`)), ), }, }, @@ -198,8 +210,6 @@ func testAccCheckResourceAttrRegionalReverseDNSService(resourceName, attributeNa } const testAccVPCEndpointServiceDataSourceConfig_gateway = ` -data "aws_availability_zones" "available" {} - data "aws_vpc_endpoint_service" "test" { service = "dynamodb" } @@ -220,102 +230,44 @@ data "aws_vpc_endpoint_service" "test" { `, service, serviceType) } -func testAccVPCEndpointServiceCustomBaseDataSourceConfig(rName string) string { - return fmt.Sprintf(` -resource "aws_vpc" "test" { - cidr_block = "10.0.0.0/16" - - tags = { - Name = %[1]q - } -} - -resource "aws_lb" "test" { - name = %[1]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 = %[1]q - } -} - -data "aws_availability_zones" "available" { - state = "available" - - filter { - name = "opt-in-status" - values = ["opt-in-not-required"] - } -} - -resource "aws_subnet" "test1" { - vpc_id = aws_vpc.test.id - cidr_block = "10.0.1.0/24" - availability_zone = data.aws_availability_zones.available.names[0] - - tags = { - Name = %[1]q - } -} - -resource "aws_subnet" "test2" { - vpc_id = aws_vpc.test.id - cidr_block = "10.0.2.0/24" - availability_zone = data.aws_availability_zones.available.names[1] - - tags = { - Name = %[1]q - } -} - +func testAccVPCEndpointServiceDataSourceConfig_customBase(rName string) string { + return acctest.ConfigCompose(testAccVPCEndpointServiceConfig_networkLoadBalancerBase(rName, 1), fmt.Sprintf(` resource "aws_vpc_endpoint_service" "test" { - acceptance_required = true - - network_load_balancer_arns = [ - aws_lb.test.id, - ] + acceptance_required = false + network_load_balancer_arns = aws_lb.test[*].arn tags = { Name = %[1]q } } -`, rName) +`, rName)) } func testAccVPCEndpointServiceDataSourceConfig_custom(rName string) string { - return testAccVPCEndpointServiceCustomBaseDataSourceConfig(rName) + ` + return acctest.ConfigCompose(testAccVPCEndpointServiceDataSourceConfig_customBase(rName), ` data "aws_vpc_endpoint_service" "test" { service_name = aws_vpc_endpoint_service.test.service_name } -` +`) } func testAccVPCEndpointServiceDataSourceConfig_customFilter(rName string) string { - return testAccVPCEndpointServiceCustomBaseDataSourceConfig(rName) + ` + return acctest.ConfigCompose(testAccVPCEndpointServiceDataSourceConfig_customBase(rName), ` data "aws_vpc_endpoint_service" "test" { filter { name = "service-name" values = [aws_vpc_endpoint_service.test.service_name] } } -` +`) } func testAccVPCEndpointServiceDataSourceConfig_customFilterTags(rName string) string { - return testAccVPCEndpointServiceCustomBaseDataSourceConfig(rName) + ` + return acctest.ConfigCompose(testAccVPCEndpointServiceDataSourceConfig_customBase(rName), ` data "aws_vpc_endpoint_service" "test" { tags = { Name = aws_vpc_endpoint_service.test.tags["Name"] } } -` +`) } diff --git a/website/docs/d/vpc_endpoint_service.html.markdown b/website/docs/d/vpc_endpoint_service.html.markdown index c50811477c94..51fea7d274ee 100644 --- a/website/docs/d/vpc_endpoint_service.html.markdown +++ b/website/docs/d/vpc_endpoint_service.html.markdown @@ -85,5 +85,6 @@ In addition to all arguments above, the following attributes are exported: * `owner` - The AWS account ID of the service owner or `amazon`. * `private_dns_name` - The private DNS name for the service. * `service_id` - The ID of the endpoint service. +* `supported_ip_address_types` - The supported IP address types. * `tags` - A map of tags assigned to the resource. * `vpc_endpoint_policy_supported` - Whether or not the service supports endpoint policies - `true` or `false`. From 190a06143be6c75ad7a1a590434a13ae51de3d18 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 21 Jun 2022 15:03:53 -0400 Subject: [PATCH 22/22] Rename EC2 error code constants to match API's capitalization. --- internal/service/ec2/errors.go | 8 ++++---- internal/service/ec2/find.go | 14 +++++++------- .../ec2/vpc_endpoint_connection_accepter.go | 2 +- .../ec2/vpc_endpoint_route_table_association.go | 2 +- .../ec2/vpc_endpoint_security_group_association.go | 2 +- internal/service/ec2/vpc_endpoint_service.go | 2 +- .../ec2/vpc_endpoint_service_allowed_principal.go | 2 +- .../service/ec2/vpc_endpoint_subnet_association.go | 2 +- .../service/ec2/vpnclient_authorization_rule.go | 2 +- internal/service/ec2/vpnclient_endpoint.go | 2 +- .../service/ec2/vpnclient_network_association.go | 2 +- internal/service/ec2/vpnclient_route.go | 2 +- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/internal/service/ec2/errors.go b/internal/service/ec2/errors.go index d3620d99da79..dc04318edfbc 100644 --- a/internal/service/ec2/errors.go +++ b/internal/service/ec2/errors.go @@ -25,9 +25,9 @@ const ( errCodeInvalidCapacityReservationIdNotFound = "InvalidCapacityReservationId.NotFound'" ErrCodeInvalidCarrierGatewayIDNotFound = "InvalidCarrierGatewayID.NotFound" errCodeInvalidClientVPNActiveAssociationNotFound = "InvalidClientVpnActiveAssociationNotFound" - errCodeInvalidClientVPNAssociationIDNotFound = "InvalidClientVpnAssociationIdNotFound" + errCodeInvalidClientVPNAssociationIdNotFound = "InvalidClientVpnAssociationIdNotFound" errCodeInvalidClientVPNAuthorizationRuleNotFound = "InvalidClientVpnEndpointAuthorizationRuleNotFound" - errCodeInvalidClientVPNEndpointIDNotFound = "InvalidClientVpnEndpointId.NotFound" + errCodeInvalidClientVPNEndpointIdNotFound = "InvalidClientVpnEndpointId.NotFound" errCodeInvalidClientVPNRouteNotFound = "InvalidClientVpnRouteNotFound" ErrCodeInvalidConnectionNotification = "InvalidConnectionNotification" errCodeInvalidConversionTaskIdMalformed = "InvalidConversionTaskId.Malformed" @@ -77,9 +77,9 @@ const ( errCodeInvalidTransitGatewayMulticastDomainIdNotFound = "InvalidTransitGatewayMulticastDomainId.NotFound" errCodeInvalidVolumeNotFound = "InvalidVolume.NotFound" errCodeInvalidVPCCIDRBlockAssociationIDNotFound = "InvalidVpcCidrBlockAssociationID.NotFound" - errCodeInvalidVPCEndpointIDNotFound = "InvalidVpcEndpointId.NotFound" + errCodeInvalidVPCEndpointIdNotFound = "InvalidVpcEndpointId.NotFound" errCodeInvalidVPCEndpointNotFound = "InvalidVpcEndpoint.NotFound" - errCodeInvalidVPCEndpointServiceIDNotFound = "InvalidVpcEndpointServiceId.NotFound" + errCodeInvalidVPCEndpointServiceIdNotFound = "InvalidVpcEndpointServiceId.NotFound" errCodeInvalidVPCIDNotFound = "InvalidVpcID.NotFound" errCodeInvalidVPCPeeringConnectionIDNotFound = "InvalidVpcPeeringConnectionID.NotFound" errCodeInvalidVPNConnectionIDNotFound = "InvalidVpnConnectionID.NotFound" diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 5289d3c400b7..339fe690d83a 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -210,7 +210,7 @@ func FindClientVPNEndpoints(conn *ec2.EC2, input *ec2.DescribeClientVpnEndpoints return !lastPage }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIdNotFound) { return nil, &resource.NotFoundError{ LastError: err, LastRequest: input, @@ -303,7 +303,7 @@ func FindClientVPNAuthorizationRules(conn *ec2.EC2, input *ec2.DescribeClientVpn return !lastPage }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIdNotFound) { return nil, &resource.NotFoundError{ LastError: err, LastRequest: input, @@ -369,7 +369,7 @@ func FindClientVPNNetworkAssociations(conn *ec2.EC2, input *ec2.DescribeClientVp return !lastPage }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIDNotFound, errCodeInvalidClientVPNAssociationIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIdNotFound, errCodeInvalidClientVPNAssociationIdNotFound) { return nil, &resource.NotFoundError{ LastError: err, LastRequest: input, @@ -449,7 +449,7 @@ func FindClientVPNRoutes(conn *ec2.EC2, input *ec2.DescribeClientVpnRoutesInput) return !lastPage }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIdNotFound) { return nil, &resource.NotFoundError{ LastError: err, LastRequest: input, @@ -2560,7 +2560,7 @@ func FindVPCEndpoints(conn *ec2.EC2, input *ec2.DescribeVpcEndpointsInput) ([]*e return !lastPage }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointIdNotFound) { return nil, &resource.NotFoundError{ LastError: err, LastRequest: input, @@ -2637,7 +2637,7 @@ func FindVPCEndpointServiceConfigurations(conn *ec2.EC2, input *ec2.DescribeVpcE return !lastPage }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIdNotFound) { return nil, &resource.NotFoundError{ LastError: err, LastRequest: input, @@ -2732,7 +2732,7 @@ func FindVPCEndpointServicePermissions(conn *ec2.EC2, input *ec2.DescribeVpcEndp return !lastPage }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIdNotFound) { return nil, &resource.NotFoundError{ LastError: err, LastRequest: input, diff --git a/internal/service/ec2/vpc_endpoint_connection_accepter.go b/internal/service/ec2/vpc_endpoint_connection_accepter.go index 0f4e7a891071..52ff607eb0a9 100644 --- a/internal/service/ec2/vpc_endpoint_connection_accepter.go +++ b/internal/service/ec2/vpc_endpoint_connection_accepter.go @@ -115,7 +115,7 @@ func resourceVPCEndpointConnectionAccepterDelete(d *schema.ResourceData, meta in _, err = conn.RejectVpcEndpointConnections(input) - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIdNotFound) { return nil } diff --git a/internal/service/ec2/vpc_endpoint_route_table_association.go b/internal/service/ec2/vpc_endpoint_route_table_association.go index 9c0aaa3594bf..f7c2d88dd321 100644 --- a/internal/service/ec2/vpc_endpoint_route_table_association.go +++ b/internal/service/ec2/vpc_endpoint_route_table_association.go @@ -107,7 +107,7 @@ func resourceVPCEndpointRouteTableAssociationDelete(d *schema.ResourceData, meta log.Printf("[DEBUG] Deleting VPC Endpoint Route Table Association: %s", id) _, err := conn.ModifyVpcEndpoint(input) - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointIDNotFound) || tfawserr.ErrCodeEquals(err, errCodeInvalidRouteTableIdNotFound) || tfawserr.ErrCodeEquals(err, errCodeInvalidParameter) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointIdNotFound) || tfawserr.ErrCodeEquals(err, errCodeInvalidRouteTableIdNotFound) || tfawserr.ErrCodeEquals(err, errCodeInvalidParameter) { return nil } diff --git a/internal/service/ec2/vpc_endpoint_security_group_association.go b/internal/service/ec2/vpc_endpoint_security_group_association.go index 93aededc84c3..9ae8db53c469 100644 --- a/internal/service/ec2/vpc_endpoint_security_group_association.go +++ b/internal/service/ec2/vpc_endpoint_security_group_association.go @@ -183,7 +183,7 @@ func deleteVPCEndpointSecurityGroupAssociation(conn *ec2.EC2, vpcEndpointID, sec log.Printf("[DEBUG] Deleting VPC Endpoint Security Group Association: %s", input) _, err := conn.ModifyVpcEndpoint(input) - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointIDNotFound, errCodeInvalidGroupNotFound, errCodeInvalidParameter) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointIdNotFound, errCodeInvalidGroupNotFound, errCodeInvalidParameter) { return nil } diff --git a/internal/service/ec2/vpc_endpoint_service.go b/internal/service/ec2/vpc_endpoint_service.go index 8aa6f56b8b44..7f2fca6f5380 100644 --- a/internal/service/ec2/vpc_endpoint_service.go +++ b/internal/service/ec2/vpc_endpoint_service.go @@ -343,7 +343,7 @@ func resourceVPCEndpointServiceDelete(d *schema.ResourceData, meta interface{}) err = UnsuccessfulItemsError(output.Unsuccessful) } - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIdNotFound) { return nil } diff --git a/internal/service/ec2/vpc_endpoint_service_allowed_principal.go b/internal/service/ec2/vpc_endpoint_service_allowed_principal.go index 0a12a4d9c092..4de0daa78210 100644 --- a/internal/service/ec2/vpc_endpoint_service_allowed_principal.go +++ b/internal/service/ec2/vpc_endpoint_service_allowed_principal.go @@ -86,7 +86,7 @@ func resourceVPCEndpointServiceAllowedPrincipalDelete(d *schema.ResourceData, me ServiceId: aws.String(serviceID), }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointServiceIdNotFound) { return nil } diff --git a/internal/service/ec2/vpc_endpoint_subnet_association.go b/internal/service/ec2/vpc_endpoint_subnet_association.go index 793eea6ef27c..f28e4631310d 100644 --- a/internal/service/ec2/vpc_endpoint_subnet_association.go +++ b/internal/service/ec2/vpc_endpoint_subnet_association.go @@ -131,7 +131,7 @@ func resourceVPCEndpointSubnetAssociationDelete(d *schema.ResourceData, meta int log.Printf("[DEBUG] Deleting VPC Endpoint Subnet Association: %s", id) _, err := conn.ModifyVpcEndpoint(input) - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointIDNotFound) || tfawserr.ErrCodeEquals(err, errCodeInvalidSubnetIdNotFound) || tfawserr.ErrCodeEquals(err, errCodeInvalidParameter) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCEndpointIdNotFound) || tfawserr.ErrCodeEquals(err, errCodeInvalidSubnetIdNotFound) || tfawserr.ErrCodeEquals(err, errCodeInvalidParameter) { return nil } diff --git a/internal/service/ec2/vpnclient_authorization_rule.go b/internal/service/ec2/vpnclient_authorization_rule.go index 402b8b6379ac..93c7356de68b 100644 --- a/internal/service/ec2/vpnclient_authorization_rule.go +++ b/internal/service/ec2/vpnclient_authorization_rule.go @@ -157,7 +157,7 @@ func resourceClientVPNAuthorizationRuleDelete(d *schema.ResourceData, meta inter log.Printf("[DEBUG] Deleting EC2 Client VPN Authorization Rule: %s", d.Id()) _, err = conn.RevokeClientVpnIngress(input) - if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIDNotFound, errCodeInvalidClientVPNAuthorizationRuleNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIdNotFound, errCodeInvalidClientVPNAuthorizationRuleNotFound) { return nil } diff --git a/internal/service/ec2/vpnclient_endpoint.go b/internal/service/ec2/vpnclient_endpoint.go index b38f33268ba7..4394da1e2e57 100644 --- a/internal/service/ec2/vpnclient_endpoint.go +++ b/internal/service/ec2/vpnclient_endpoint.go @@ -470,7 +470,7 @@ func resourceClientVPNEndpointDelete(d *schema.ResourceData, meta interface{}) e ClientVpnEndpointId: aws.String(d.Id()), }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIdNotFound) { return nil } diff --git a/internal/service/ec2/vpnclient_network_association.go b/internal/service/ec2/vpnclient_network_association.go index 3d3c1413c70e..0f02b33d558d 100644 --- a/internal/service/ec2/vpnclient_network_association.go +++ b/internal/service/ec2/vpnclient_network_association.go @@ -165,7 +165,7 @@ func resourceClientVPNNetworkAssociationDelete(d *schema.ResourceData, meta inte AssociationId: aws.String(d.Id()), }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNAssociationIDNotFound, errCodeInvalidClientVPNEndpointIDNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNAssociationIdNotFound, errCodeInvalidClientVPNEndpointIdNotFound) { return nil } diff --git a/internal/service/ec2/vpnclient_route.go b/internal/service/ec2/vpnclient_route.go index 94d8405a0d44..5105d14c9e93 100644 --- a/internal/service/ec2/vpnclient_route.go +++ b/internal/service/ec2/vpnclient_route.go @@ -144,7 +144,7 @@ func resourceClientVPNRouteDelete(d *schema.ResourceData, meta interface{}) erro TargetVpcSubnetId: aws.String(targetSubnetID), }) - if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIDNotFound, errCodeInvalidClientVPNRouteNotFound) { + if tfawserr.ErrCodeEquals(err, errCodeInvalidClientVPNEndpointIdNotFound, errCodeInvalidClientVPNRouteNotFound) { return nil }