From ed32795310bd278bb1fa0d2f72dcc5b5ce657f5b Mon Sep 17 00:00:00 2001 From: Nicolas Moutschen Date: Mon, 24 Jul 2023 11:19:52 +0200 Subject: [PATCH 01/12] fix: fix 31896 --- .../service_network_vpc_association.go | 8 +++ .../service_network_vpc_association_test.go | 51 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/internal/service/vpclattice/service_network_vpc_association.go b/internal/service/vpclattice/service_network_vpc_association.go index 6df39ad6a46c..30f7af1ef3c8 100644 --- a/internal/service/vpclattice/service_network_vpc_association.go +++ b/internal/service/vpclattice/service_network_vpc_association.go @@ -4,6 +4,7 @@ import ( "context" "errors" "log" + "strings" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -61,6 +62,13 @@ func ResourceServiceNetworkVPCAssociation() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // Users can provide both IDs or ARNs, while the API returns the ID + old_id := old[strings.LastIndex(old, "/")+1:] + new_id := new[strings.LastIndex(new, "/")+1:] + + return old_id == new_id + }, }, "status": { Type: schema.TypeString, diff --git a/internal/service/vpclattice/service_network_vpc_association_test.go b/internal/service/vpclattice/service_network_vpc_association_test.go index 6565c04d53e5..05b68ab67d67 100644 --- a/internal/service/vpclattice/service_network_vpc_association_test.go +++ b/internal/service/vpclattice/service_network_vpc_association_test.go @@ -53,6 +53,40 @@ func TestAccVPCLatticeServiceNetworkVPCAssociation_basic(t *testing.T) { }) } +func TestAccVPCLatticeServiceNetworkVPCAssociation_arn(t *testing.T) { + ctx := acctest.Context(t) + + var servicenetworkvpcasc vpclattice.GetServiceNetworkVpcAssociationOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_vpclattice_service_network_vpc_association.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.VPCLatticeEndpointID) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.VPCLatticeEndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckServiceNetworkVPCAssociationDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccServiceNetworkVPCAssociationConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckServiceNetworkVPCAssociationExists(ctx, resourceName, &servicenetworkvpcasc), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "vpc-lattice", regexp.MustCompile("servicenetworkvpcassociation/.+$")), + resource.TestCheckResourceAttrSet(resourceName, "service_network_identifier"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccVPCLatticeServiceNetworkVPCAssociation_disappears(t *testing.T) { ctx := acctest.Context(t) @@ -238,6 +272,23 @@ resource "aws_vpclattice_service_network_vpc_association" "test" { `, rName) } +func testAccServiceNetworkVPCAssociationConfig_arn(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_vpclattice_service_network" "test" { + name = %[1]q +} + +resource "aws_vpclattice_service_network_vpc_association" "test" { + vpc_identifier = aws_vpc.test.id + service_network_identifier = aws_vpclattice_service_network.test.arn +} +`, rName) +} + func testAccServiceNetworkVPCAssociationConfig_full(rName string) string { return fmt.Sprintf(` resource "aws_vpc" "test" { From 958e272da6c2dc79027123c2458b00b77bb828f6 Mon Sep 17 00:00:00 2001 From: Nicolas Moutschen Date: Mon, 24 Jul 2023 16:37:40 +0200 Subject: [PATCH 02/12] chore: add changelog entry --- .changelog/32658.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/32658.txt diff --git a/.changelog/32658.txt b/.changelog/32658.txt new file mode 100644 index 000000000000..86b03b9f2aae --- /dev/null +++ b/.changelog/32658.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_vpclattice_service_network_vpc_association: Avoid recreating resource when passing ARNS as service_network_identifiers +``` From dd56abd68b6d553f0d0e9d17648f05621f282c69 Mon Sep 17 00:00:00 2001 From: Nicolas Moutschen Date: Tue, 25 Jul 2023 21:37:33 +0200 Subject: [PATCH 03/12] fix: fix test case --- .../service/vpclattice/service_network_vpc_association_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/vpclattice/service_network_vpc_association_test.go b/internal/service/vpclattice/service_network_vpc_association_test.go index 05b68ab67d67..431c7012550c 100644 --- a/internal/service/vpclattice/service_network_vpc_association_test.go +++ b/internal/service/vpclattice/service_network_vpc_association_test.go @@ -71,7 +71,7 @@ func TestAccVPCLatticeServiceNetworkVPCAssociation_arn(t *testing.T) { CheckDestroy: testAccCheckServiceNetworkVPCAssociationDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccServiceNetworkVPCAssociationConfig_basic(rName), + Config: testAccServiceNetworkVPCAssociationConfig_arn(rName), Check: resource.ComposeTestCheckFunc( testAccCheckServiceNetworkVPCAssociationExists(ctx, resourceName, &servicenetworkvpcasc), acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "vpc-lattice", regexp.MustCompile("servicenetworkvpcassociation/.+$")), From 3082c4d04005906a7201c09554b0b42273dbbbdc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jul 2023 14:05:23 -0400 Subject: [PATCH 04/12] vpclattice: Add 'idFromIDOrARN'. --- internal/service/vpclattice/exports_test.go | 1 + .../service/vpclattice/service_network.go | 8 ++++++ .../vpclattice/service_network_test.go | 27 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/internal/service/vpclattice/exports_test.go b/internal/service/vpclattice/exports_test.go index de5ad314c184..3a1e21f4386c 100644 --- a/internal/service/vpclattice/exports_test.go +++ b/internal/service/vpclattice/exports_test.go @@ -3,6 +3,7 @@ package vpclattice // Exports for use in tests only. var ( FindTargetByThreePartKey = findTargetByThreePartKey + IDFromIDOrARN = idFromIDOrARN ResourceTargetGroupAttachment = resourceTargetGroupAttachment ) diff --git a/internal/service/vpclattice/service_network.go b/internal/service/vpclattice/service_network.go index 9a97b84d07fc..cab5a8150141 100644 --- a/internal/service/vpclattice/service_network.go +++ b/internal/service/vpclattice/service_network.go @@ -4,6 +4,7 @@ import ( "context" "errors" "log" + "strings" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/vpclattice" @@ -178,3 +179,10 @@ func findServiceNetworkByID(ctx context.Context, conn *vpclattice.Client, id str return out, nil } + +// idFromIDOrARN return a resource ID from an ID or ARN. +func idFromIDOrARN(idOrARN string) string { + // e.g. "sn-1234567890abcdefg" or + // "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg". + return idOrARN[strings.LastIndex(idOrARN, "/")+1:] +} diff --git a/internal/service/vpclattice/service_network_test.go b/internal/service/vpclattice/service_network_test.go index f8d4faebe7da..53a570be26b3 100644 --- a/internal/service/vpclattice/service_network_test.go +++ b/internal/service/vpclattice/service_network_test.go @@ -20,6 +20,33 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) +func TestIDFromIDOrARN(t *testing.T) { + t.Parallel() + + testCases := []struct { + idOrARN string + want string + }{ + { + idOrARN: "", + want: "", + }, + { + idOrARN: "sn-1234567890abcdefg", + want: "sn-1234567890abcdefg", + }, + { + idOrARN: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", + want: "sn-1234567890abcdefg", + }, + } + for _, testCase := range testCases { + if got, want := tfvpclattice.IDFromIDOrARN(testCase.idOrARN), testCase.want; got != want { + t.Errorf("IDFromIDOrARN(%q) = %v, want %v", testCase.idOrARN, got, want) + } + } +} + func TestAccVPCLatticeServiceNetwork_basic(t *testing.T) { ctx := acctest.Context(t) From ed579609567ddf388ad80761948a08949a3344fe Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jul 2023 14:06:35 -0400 Subject: [PATCH 05/12] Tweak CHANGELOG entry. --- .changelog/32658.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/32658.txt b/.changelog/32658.txt index 86b03b9f2aae..ab3889b20c3b 100644 --- a/.changelog/32658.txt +++ b/.changelog/32658.txt @@ -1,3 +1,3 @@ ```release-note:bug -resource/aws_vpclattice_service_network_vpc_association: Avoid recreating resource when passing ARNS as service_network_identifiers +resource/aws_vpclattice_service_network_vpc_association: Avoid recreating resource when passing an ARN as `service_network_identifier` ``` From c69caf8e74241cebdee5c4ac55f4a1acd0a91d1b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jul 2023 14:13:39 -0400 Subject: [PATCH 06/12] vpclattice: Add 'suppressEquivalentIDOrARN'. --- internal/service/vpclattice/exports_test.go | 5 ++- .../service/vpclattice/service_network.go | 6 +++ .../vpclattice/service_network_test.go | 41 +++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/internal/service/vpclattice/exports_test.go b/internal/service/vpclattice/exports_test.go index 3a1e21f4386c..b1acdbbcdd3f 100644 --- a/internal/service/vpclattice/exports_test.go +++ b/internal/service/vpclattice/exports_test.go @@ -2,8 +2,9 @@ package vpclattice // Exports for use in tests only. var ( - FindTargetByThreePartKey = findTargetByThreePartKey - IDFromIDOrARN = idFromIDOrARN + FindTargetByThreePartKey = findTargetByThreePartKey + IDFromIDOrARN = idFromIDOrARN + SuppressEquivalentIDOrARN = suppressEquivalentIDOrARN ResourceTargetGroupAttachment = resourceTargetGroupAttachment ) diff --git a/internal/service/vpclattice/service_network.go b/internal/service/vpclattice/service_network.go index cab5a8150141..f9e4731f8fc0 100644 --- a/internal/service/vpclattice/service_network.go +++ b/internal/service/vpclattice/service_network.go @@ -186,3 +186,9 @@ func idFromIDOrARN(idOrARN string) string { // "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg". return idOrARN[strings.LastIndex(idOrARN, "/")+1:] } + +// suppressEquivalentIDOrARN provides custom difference suppression +// for strings that represent equal resource IDs or ARNs. +func suppressEquivalentIDOrARN(_, old, new string, _ *schema.ResourceData) bool { + return idFromIDOrARN(old) == idFromIDOrARN(new) +} diff --git a/internal/service/vpclattice/service_network_test.go b/internal/service/vpclattice/service_network_test.go index 53a570be26b3..963c58fd2fde 100644 --- a/internal/service/vpclattice/service_network_test.go +++ b/internal/service/vpclattice/service_network_test.go @@ -47,6 +47,47 @@ func TestIDFromIDOrARN(t *testing.T) { } } +func TestSuppressEquivalentIDOrARN(t *testing.T) { + t.Parallel() + + testCases := []struct { + old string + new string + want bool + }{ + { + old: "sn-1234567890abcdefg", + new: "sn-1234567890abcdefg", + want: true, + }, + { + old: "sn-1234567890abcdefg", + new: "sn-1234567890abcdefh", + want: false, + }, + { + old: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", + new: "sn-1234567890abcdefg", + want: true, + }, + { + old: "sn-1234567890abcdefg", + new: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", + want: true, + }, + { + old: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", + new: "sn-1234567890abcdefh", + want: false, + }, + } + for _, testCase := range testCases { + if got, want := tfvpclattice.SuppressEquivalentIDOrARN("test_property", testCase.old, testCase.new, nil), testCase.want; got != want { + t.Errorf("SuppressEquivalentIDOrARN(%q, %q) = %v, want %v", testCase.old, testCase.new, got, want) + } + } +} + func TestAccVPCLatticeServiceNetwork_basic(t *testing.T) { ctx := acctest.Context(t) From e46a6d9c04cedf5f311f8fccf599bb3bae4f9cf8 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jul 2023 14:17:11 -0400 Subject: [PATCH 07/12] Add 'lintignore:AWSAT003,AWSAT005'. --- internal/service/vpclattice/service_network_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/service/vpclattice/service_network_test.go b/internal/service/vpclattice/service_network_test.go index 963c58fd2fde..323579ebe24e 100644 --- a/internal/service/vpclattice/service_network_test.go +++ b/internal/service/vpclattice/service_network_test.go @@ -36,7 +36,7 @@ func TestIDFromIDOrARN(t *testing.T) { want: "sn-1234567890abcdefg", }, { - idOrARN: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", + idOrARN: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", //lintignore:AWSAT003,AWSAT005 want: "sn-1234567890abcdefg", }, } @@ -66,17 +66,17 @@ func TestSuppressEquivalentIDOrARN(t *testing.T) { want: false, }, { - old: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", + old: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", //lintignore:AWSAT003,AWSAT005 new: "sn-1234567890abcdefg", want: true, }, { old: "sn-1234567890abcdefg", - new: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", + new: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", //lintignore:AWSAT003,AWSAT005 want: true, }, { - old: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", + old: "arn:aws:vpc-lattice:us-east-1:123456789012:servicenetwork/sn-1234567890abcdefg", //lintignore:AWSAT003,AWSAT005 new: "sn-1234567890abcdefh", want: false, }, From 666cb913e0c490c34b70b930b8acef840621efb3 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jul 2023 14:22:49 -0400 Subject: [PATCH 08/12] r/aws_vpclattice_service_network_vpc_association: Use 'suppressEquivalentIDOrARN'. --- .../service_network_vpc_association.go | 15 ++-- .../service_network_vpc_association_test.go | 71 ++++++------------- 2 files changed, 26 insertions(+), 60 deletions(-) diff --git a/internal/service/vpclattice/service_network_vpc_association.go b/internal/service/vpclattice/service_network_vpc_association.go index 30f7af1ef3c8..a4fda82a2040 100644 --- a/internal/service/vpclattice/service_network_vpc_association.go +++ b/internal/service/vpclattice/service_network_vpc_association.go @@ -4,7 +4,6 @@ import ( "context" "errors" "log" - "strings" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -59,16 +58,10 @@ func ResourceServiceNetworkVPCAssociation() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, "service_network_identifier": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // Users can provide both IDs or ARNs, while the API returns the ID - old_id := old[strings.LastIndex(old, "/")+1:] - new_id := new[strings.LastIndex(new, "/")+1:] - - return old_id == new_id - }, + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: suppressEquivalentIDOrARN, }, "status": { Type: schema.TypeString, diff --git a/internal/service/vpclattice/service_network_vpc_association_test.go b/internal/service/vpclattice/service_network_vpc_association_test.go index 431c7012550c..8dd31f84d65c 100644 --- a/internal/service/vpclattice/service_network_vpc_association_test.go +++ b/internal/service/vpclattice/service_network_vpc_association_test.go @@ -255,52 +255,41 @@ func testAccCheckServiceNetworkVPCAssociationExists(ctx context.Context, name st } } -func testAccServiceNetworkVPCAssociationConfig_basic(rName string) string { - return fmt.Sprintf(` -resource "aws_vpc" "test" { - cidr_block = "10.0.0.0/16" -} - +func testAccServiceNetworkVPCAssociationConfig_base(rName string) string { + return acctest.ConfigCompose(acctest.ConfigVPCWithSubnets(rName, 0), fmt.Sprintf(` resource "aws_vpclattice_service_network" "test" { name = %[1]q } +`, rName)) +} +func testAccServiceNetworkVPCAssociationConfig_basic(rName string) string { + return acctest.ConfigCompose(testAccServiceNetworkVPCAssociationConfig_base(rName), ` resource "aws_vpclattice_service_network_vpc_association" "test" { vpc_identifier = aws_vpc.test.id service_network_identifier = aws_vpclattice_service_network.test.id } -`, rName) +`) } func testAccServiceNetworkVPCAssociationConfig_arn(rName string) string { - return fmt.Sprintf(` -resource "aws_vpc" "test" { - cidr_block = "10.0.0.0/16" -} - -resource "aws_vpclattice_service_network" "test" { - name = %[1]q -} - + return acctest.ConfigCompose(testAccServiceNetworkVPCAssociationConfig_base(rName), ` resource "aws_vpclattice_service_network_vpc_association" "test" { vpc_identifier = aws_vpc.test.id service_network_identifier = aws_vpclattice_service_network.test.arn } -`, rName) +`) } func testAccServiceNetworkVPCAssociationConfig_full(rName string) string { - return fmt.Sprintf(` -resource "aws_vpc" "test" { - cidr_block = "10.0.0.0/16" -} - + return acctest.ConfigCompose(testAccServiceNetworkVPCAssociationConfig_base(rName), fmt.Sprintf(` resource "aws_security_group" "test" { + name = %[1]q vpc_id = aws_vpc.test.id -} -resource "aws_vpclattice_service_network" "test" { - name = %[1]q + tags = { + Name = %[1]q + } } resource "aws_vpclattice_service_network_vpc_association" "test" { @@ -308,48 +297,32 @@ resource "aws_vpclattice_service_network_vpc_association" "test" { security_group_ids = [aws_security_group.test.id] service_network_identifier = aws_vpclattice_service_network.test.id } -`, rName) +`, rName)) } func testAccServiceNetworkVPCAssociationConfig_tags1(rName, tagKey1, tagValue1 string) string { - return fmt.Sprintf(` -resource "aws_vpc" "test" { - cidr_block = "10.0.0.0/16" -} - -resource "aws_vpclattice_service_network" "test" { - name = %[1]q -} - + return acctest.ConfigCompose(testAccServiceNetworkVPCAssociationConfig_base(rName), fmt.Sprintf(` resource "aws_vpclattice_service_network_vpc_association" "test" { vpc_identifier = aws_vpc.test.id service_network_identifier = aws_vpclattice_service_network.test.id tags = { - %[2]q = %[3]q + %[1]q = %[2]q } } -`, rName, tagKey1, tagValue1) +`, tagKey1, tagValue1)) } func testAccServiceNetworkVPCAssociationConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { - return fmt.Sprintf(` -resource "aws_vpc" "test" { - cidr_block = "10.0.0.0/16" -} - -resource "aws_vpclattice_service_network" "test" { - name = %[1]q -} - + return acctest.ConfigCompose(testAccServiceNetworkVPCAssociationConfig_base(rName), fmt.Sprintf(` resource "aws_vpclattice_service_network_vpc_association" "test" { vpc_identifier = aws_vpc.test.id service_network_identifier = aws_vpclattice_service_network.test.id tags = { - %[2]q = %[3]q - %[4]q = %[5]q + %[1]q = %[2]q + %[3]q = %[4]q } } -`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +`, tagKey1, tagValue1, tagKey2, tagValue2)) } From f904728b115d15ee0496fe61b016c9cf7e000371 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jul 2023 16:29:22 -0400 Subject: [PATCH 09/12] r/aws_vpclattice_service_network_vpc_association: Use 'FindServiceNetworkVPCAssociationByID' in acceptance tests. --- internal/service/vpclattice/exports_test.go | 7 +++-- .../service_network_vpc_association.go | 26 +++++++++---------- .../service_network_vpc_association_test.go | 24 +++++++---------- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/internal/service/vpclattice/exports_test.go b/internal/service/vpclattice/exports_test.go index b1acdbbcdd3f..259b8017c091 100644 --- a/internal/service/vpclattice/exports_test.go +++ b/internal/service/vpclattice/exports_test.go @@ -2,9 +2,12 @@ package vpclattice // Exports for use in tests only. var ( - FindTargetByThreePartKey = findTargetByThreePartKey + FindServiceNetworkVPCAssociationByID = findServiceNetworkVPCAssociationByID + FindTargetByThreePartKey = findTargetByThreePartKey + IDFromIDOrARN = idFromIDOrARN SuppressEquivalentIDOrARN = suppressEquivalentIDOrARN - ResourceTargetGroupAttachment = resourceTargetGroupAttachment + ResourceServiceNetworkVPCAssociation = resourceServiceNetworkVPCAssociation + ResourceTargetGroupAttachment = resourceTargetGroupAttachment ) diff --git a/internal/service/vpclattice/service_network_vpc_association.go b/internal/service/vpclattice/service_network_vpc_association.go index a4fda82a2040..bd86d55ccf54 100644 --- a/internal/service/vpclattice/service_network_vpc_association.go +++ b/internal/service/vpclattice/service_network_vpc_association.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "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" @@ -25,7 +26,7 @@ import ( // @SDKResource("aws_vpclattice_service_network_vpc_association", name="Service Network VPC Association") // @Tags(identifierAttribute="arn") -func ResourceServiceNetworkVPCAssociation() *schema.Resource { +func resourceServiceNetworkVPCAssociation() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceServiceNetworkVPCAssociationCreate, ReadWithoutTimeout: resourceServiceNetworkVPCAssociationRead, @@ -171,12 +172,11 @@ func resourceServiceNetworkVPCAssociationDelete(ctx context.Context, d *schema.R ServiceNetworkVpcAssociationIdentifier: aws.String(d.Id()), }) - if err != nil { - var nfe *types.ResourceNotFoundException - if errors.As(err, &nfe) { - return nil - } + if errs.IsA[*types.ResourceNotFoundException](err) { + return nil + } + if err != nil { return create.DiagError(names.VPCLattice, create.ErrActionDeleting, ResNameServiceNetworkVPCAssociation, d.Id(), err) } @@ -192,15 +192,15 @@ func findServiceNetworkVPCAssociationByID(ctx context.Context, conn *vpclattice. ServiceNetworkVpcAssociationIdentifier: aws.String(id), } out, err := conn.GetServiceNetworkVpcAssociation(ctx, in) - if err != nil { - var nfe *types.ResourceNotFoundException - if errors.As(err, &nfe) { - return nil, &retry.NotFoundError{ - LastError: err, - LastRequest: in, - } + + if errs.IsA[*types.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: in, } + } + if err != nil { return nil, err } diff --git a/internal/service/vpclattice/service_network_vpc_association_test.go b/internal/service/vpclattice/service_network_vpc_association_test.go index 8dd31f84d65c..5ce7ae2b5afe 100644 --- a/internal/service/vpclattice/service_network_vpc_association_test.go +++ b/internal/service/vpclattice/service_network_vpc_association_test.go @@ -7,9 +7,7 @@ import ( "regexp" "testing" - "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/vpclattice" - "github.com/aws/aws-sdk-go-v2/service/vpclattice/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -17,6 +15,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" tfvpclattice "github.com/hashicorp/terraform-provider-aws/internal/service/vpclattice" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -211,18 +210,17 @@ func testAccCheckServiceNetworkVPCAssociationDestroy(ctx context.Context) resour continue } - _, err := conn.GetServiceNetworkVpcAssociation(ctx, &vpclattice.GetServiceNetworkVpcAssociationInput{ - ServiceNetworkVpcAssociationIdentifier: aws.String(rs.Primary.ID), - }) + _, err := tfvpclattice.FindServiceNetworkVPCAssociationByID(ctx, conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + if err != nil { - var nfe *types.ResourceNotFoundException - if errors.As(err, &nfe) { - return nil - } return err } - return create.Error(names.VPCLattice, create.ErrActionCheckingDestroyed, tfvpclattice.ResNameService, rs.Primary.ID, errors.New("not destroyed")) + return fmt.Errorf("VPC Lattice Service Network VPC Association %s still exists", rs.Primary.ID) } return nil @@ -241,12 +239,10 @@ func testAccCheckServiceNetworkVPCAssociationExists(ctx context.Context, name st } conn := acctest.Provider.Meta().(*conns.AWSClient).VPCLatticeClient() - resp, err := conn.GetServiceNetworkVpcAssociation(ctx, &vpclattice.GetServiceNetworkVpcAssociationInput{ - ServiceNetworkVpcAssociationIdentifier: aws.String(rs.Primary.ID), - }) + resp, err := tfvpclattice.FindServiceNetworkVPCAssociationByID(ctx, conn, rs.Primary.ID) if err != nil { - return create.Error(names.VPCLattice, create.ErrActionCheckingExistence, tfvpclattice.ResNameService, rs.Primary.ID, err) + return err } *service = *resp From f45af32752789497994e5527c086a947f8ae5cca Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jul 2023 16:53:28 -0400 Subject: [PATCH 10/12] Add 'tfresource.RetryWhenAWSErrCodeEqualsV2' and 'tfresource.RetryWhenAWSErrMessageContainsV2'. --- internal/tfresource/retry.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/internal/tfresource/retry.go b/internal/tfresource/retry.go index fe2aabd9b2a0..f8e1f5bd65d9 100644 --- a/internal/tfresource/retry.go +++ b/internal/tfresource/retry.go @@ -11,6 +11,7 @@ import ( "time" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + tfawserr_sdkv2 "github.com/hashicorp/aws-sdk-go-base/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-provider-aws/internal/errs" ) @@ -66,6 +67,17 @@ func RetryWhenAWSErrCodeEquals(ctx context.Context, timeout time.Duration, f fun }) } +// RetryWhenAWSErrCodeEqualsV2 retries the specified function when it returns one of the specified AWS SDK for Go v2 error code. +func RetryWhenAWSErrCodeEqualsV2(ctx context.Context, timeout time.Duration, f func() (interface{}, error), codes ...string) (interface{}, error) { // nosemgrep:ci.aws-in-func-name + return RetryWhen(ctx, timeout, f, func(err error) (bool, error) { + if tfawserr_sdkv2.ErrCodeEquals(err, codes...) { + return true, err + } + + return false, err + }) +} + // RetryWhenAWSErrMessageContains retries the specified function when it returns an AWS error containing the specified message. func RetryWhenAWSErrMessageContains(ctx context.Context, timeout time.Duration, f func() (interface{}, error), code, message string) (interface{}, error) { // nosemgrep:ci.aws-in-func-name return RetryWhen(ctx, timeout, f, func(err error) (bool, error) { @@ -77,6 +89,17 @@ func RetryWhenAWSErrMessageContains(ctx context.Context, timeout time.Duration, }) } +// RetryWhenAWSErrMessageContainsV2 retries the specified function when it returns an AWS SDK for Go v2 error containing the specified message. +func RetryWhenAWSErrMessageContainsV2(ctx context.Context, timeout time.Duration, f func() (interface{}, error), code, message string) (interface{}, error) { // nosemgrep:ci.aws-in-func-name + return RetryWhen(ctx, timeout, f, func(err error) (bool, error) { + if tfawserr_sdkv2.ErrMessageContains(err, code, message) { + return true, err + } + + return false, err + }) +} + func RetryWhenIsA[T error](ctx context.Context, timeout time.Duration, f func() (interface{}, error)) (interface{}, error) { return RetryWhen(ctx, timeout, f, func(err error) (bool, error) { if errs.IsA[T](err) { From 57edf02127a378e0e448f59a65b6703d8e732350 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jul 2023 16:53:59 -0400 Subject: [PATCH 11/12] r/aws_vpc: Use 'tfresource.RetryWhenAWSErrCodeEqualsV2' and 'tfresource.RetryWhenAWSErrMessageContainsV2'. --- internal/service/ec2/vpc_.go | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/internal/service/ec2/vpc_.go b/internal/service/ec2/vpc_.go index 8aaa044f5cb1..8b0270842c31 100644 --- a/internal/service/ec2/vpc_.go +++ b/internal/service/ec2/vpc_.go @@ -15,7 +15,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/service/ec2/types" - "github.com/hashicorp/aws-sdk-go-base/v2/tfawserr" + tfawserr_sdkv2 "github.com/hashicorp/aws-sdk-go-base/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" @@ -213,18 +213,10 @@ func resourceVPCCreate(ctx context.Context, d *schema.ResourceData, meta interfa input.Ipv6NetmaskLength = aws.Int32(int32(v.(int))) } - outputRaw, err := tfresource.RetryWhen(ctx, ec2PropagationTimeout, - func() (interface{}, error) { - return conn.CreateVpc(ctx, input) - }, - func(err error) (bool, error) { - // "UnsupportedOperation: The operation AllocateIpamPoolCidr is not supported. Account 123456789012 is not monitored by IPAM ipam-07b079e3392782a55." - if tfawserr.ErrMessageContains(err, errCodeUnsupportedOperation, "is not monitored by IPAM") { - return true, err - } - return false, err - }, - ) + // "UnsupportedOperation: The operation AllocateIpamPoolCidr is not supported. Account 123456789012 is not monitored by IPAM ipam-07b079e3392782a55." + outputRaw, err := tfresource.RetryWhenAWSErrMessageContainsV2(ctx, ec2PropagationTimeout, func() (interface{}, error) { + return conn.CreateVpc(ctx, input) + }, errCodeUnsupportedOperation, "is not monitored by IPAM") if err != nil { return sdkdiag.AppendErrorf(diags, "creating EC2 VPC: %s", err) @@ -458,11 +450,11 @@ func resourceVPCDelete(ctx context.Context, d *schema.ResourceData, meta interfa } log.Printf("[INFO] Deleting EC2 VPC: %s", d.Id()) - _, err := tfresource.RetryWhenAWSErrCodeEquals(ctx, vpcDeletedTimeout, func() (interface{}, error) { + _, err := tfresource.RetryWhenAWSErrCodeEqualsV2(ctx, vpcDeletedTimeout, func() (interface{}, error) { return conn.DeleteVpc(ctx, input) }, errCodeDependencyViolation) - if tfawserr.ErrCodeEquals(err, errCodeInvalidVPCIDNotFound) { + if tfawserr_sdkv2.ErrCodeEquals(err, errCodeInvalidVPCIDNotFound) { return diags } From b292a2874c699b5f7819b6bbd4e353d5c7b9e30b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jul 2023 17:09:22 -0400 Subject: [PATCH 12/12] r/aws_vpclattice_service_network_service_association: Avoid recreating resource when passing an ARN as 'service_identifier' or 'service_network_identifier'. --- .changelog/32658.txt | 4 + internal/service/vpclattice/exports_test.go | 10 +- .../service_network_service_association.go | 40 +++---- ...ervice_network_service_association_test.go | 100 +++++++++++------- .../service/vpclattice/service_package_gen.go | 2 +- 5 files changed, 95 insertions(+), 61 deletions(-) diff --git a/.changelog/32658.txt b/.changelog/32658.txt index ab3889b20c3b..f58717ce93d7 100644 --- a/.changelog/32658.txt +++ b/.changelog/32658.txt @@ -1,3 +1,7 @@ ```release-note:bug resource/aws_vpclattice_service_network_vpc_association: Avoid recreating resource when passing an ARN as `service_network_identifier` ``` + +```release-note:bug +resource/aws_vpclattice_service_network_service_association: Avoid recreating resource when passing an ARN as `service_identifier` or `service_network_identifier` +``` \ No newline at end of file diff --git a/internal/service/vpclattice/exports_test.go b/internal/service/vpclattice/exports_test.go index a14c21bc6a64..6b11ba97ca3f 100644 --- a/internal/service/vpclattice/exports_test.go +++ b/internal/service/vpclattice/exports_test.go @@ -5,12 +5,14 @@ package vpclattice // Exports for use in tests only. var ( - FindServiceNetworkVPCAssociationByID = findServiceNetworkVPCAssociationByID - FindTargetByThreePartKey = findTargetByThreePartKey + FindServiceNetworkServiceAssociationByID = findServiceNetworkServiceAssociationByID + FindServiceNetworkVPCAssociationByID = findServiceNetworkVPCAssociationByID + FindTargetByThreePartKey = findTargetByThreePartKey IDFromIDOrARN = idFromIDOrARN SuppressEquivalentIDOrARN = suppressEquivalentIDOrARN - ResourceServiceNetworkVPCAssociation = resourceServiceNetworkVPCAssociation - ResourceTargetGroupAttachment = resourceTargetGroupAttachment + ResourceServiceNetworkServiceAssociation = resourceServiceNetworkServiceAssociation + ResourceServiceNetworkVPCAssociation = resourceServiceNetworkVPCAssociation + ResourceTargetGroupAttachment = resourceTargetGroupAttachment ) diff --git a/internal/service/vpclattice/service_network_service_association.go b/internal/service/vpclattice/service_network_service_association.go index b3c0498d9350..4e07c7568f2b 100644 --- a/internal/service/vpclattice/service_network_service_association.go +++ b/internal/service/vpclattice/service_network_service_association.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" "github.com/hashicorp/terraform-provider-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/errs" 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" @@ -27,7 +28,7 @@ import ( // @SDKResource("aws_vpclattice_service_network_service_association", name="Service Network Service Association") // @Tags(identifierAttribute="arn") -func ResourceServiceNetworkServiceAssociation() *schema.Resource { +func resourceServiceNetworkServiceAssociation() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceServiceNetworkServiceAssociationCreate, ReadWithoutTimeout: resourceServiceNetworkServiceAssociationRead, @@ -74,14 +75,16 @@ func ResourceServiceNetworkServiceAssociation() *schema.Resource { }, }, "service_identifier": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: suppressEquivalentIDOrARN, }, "service_network_identifier": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: suppressEquivalentIDOrARN, }, "status": { Type: schema.TypeString, @@ -173,12 +176,11 @@ func resourceServiceNetworkServiceAssociationDelete(ctx context.Context, d *sche ServiceNetworkServiceAssociationIdentifier: aws.String(d.Id()), }) - if err != nil { - var nfe *types.ResourceNotFoundException - if errors.As(err, &nfe) { - return nil - } + if errs.IsA[*types.ResourceNotFoundException](err) { + return nil + } + if err != nil { return create.DiagError(names.VPCLattice, create.ErrActionDeleting, ResNameServiceNetworkAssociation, d.Id(), err) } @@ -194,15 +196,15 @@ func findServiceNetworkServiceAssociationByID(ctx context.Context, conn *vpclatt ServiceNetworkServiceAssociationIdentifier: aws.String(id), } out, err := conn.GetServiceNetworkServiceAssociation(ctx, in) - if err != nil { - var nfe *types.ResourceNotFoundException - if errors.As(err, &nfe) { - return nil, &retry.NotFoundError{ - LastError: err, - LastRequest: in, - } + + if errs.IsA[*types.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: in, } + } + if err != nil { return nil, err } diff --git a/internal/service/vpclattice/service_network_service_association_test.go b/internal/service/vpclattice/service_network_service_association_test.go index 4e903ee821c4..bf1016ae27cd 100644 --- a/internal/service/vpclattice/service_network_service_association_test.go +++ b/internal/service/vpclattice/service_network_service_association_test.go @@ -10,9 +10,7 @@ import ( "regexp" "testing" - "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/vpclattice" - "github.com/aws/aws-sdk-go-v2/service/vpclattice/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -20,6 +18,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" tfvpclattice "github.com/hashicorp/terraform-provider-aws/internal/service/vpclattice" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -56,6 +55,39 @@ func TestAccVPCLatticeServiceNetworkServiceAssociation_basic(t *testing.T) { }) } +func TestAccVPCLatticeServiceNetworkServiceAssociation_arn(t *testing.T) { + ctx := acctest.Context(t) + + var servicenetworkasc vpclattice.GetServiceNetworkServiceAssociationOutput + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_vpclattice_service_network_service_association.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.VPCLatticeEndpointID) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.VPCLatticeEndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckServiceNetworkServiceAssociationDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccServiceNetworkServiceAssociationConfig_arn(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckServiceNetworkServiceAssociationExists(ctx, resourceName, &servicenetworkasc), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "vpc-lattice", regexp.MustCompile("servicenetworkserviceassociation/.+$")), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccVPCLatticeServiceNetworkServiceAssociation_disappears(t *testing.T) { ctx := acctest.Context(t) @@ -144,18 +176,17 @@ func testAccCheckServiceNetworkServiceAssociationDestroy(ctx context.Context) re continue } - _, err := conn.GetServiceNetworkServiceAssociation(ctx, &vpclattice.GetServiceNetworkServiceAssociationInput{ - ServiceNetworkServiceAssociationIdentifier: aws.String(rs.Primary.ID), - }) + _, err := tfvpclattice.FindServiceNetworkServiceAssociationByID(ctx, conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + if err != nil { - var nfe *types.ResourceNotFoundException - if errors.As(err, &nfe) { - return nil - } return err } - return create.Error(names.VPCLattice, create.ErrActionCheckingDestroyed, tfvpclattice.ResNameService, rs.Primary.ID, errors.New("not destroyed")) + return fmt.Errorf("VPC Lattice Service Network Service Association %s still exists", rs.Primary.ID) } return nil @@ -174,12 +205,10 @@ func testAccCheckServiceNetworkServiceAssociationExists(ctx context.Context, nam } conn := acctest.Provider.Meta().(*conns.AWSClient).VPCLatticeClient(ctx) - resp, err := conn.GetServiceNetworkServiceAssociation(ctx, &vpclattice.GetServiceNetworkServiceAssociationInput{ - ServiceNetworkServiceAssociationIdentifier: aws.String(rs.Primary.ID), - }) + resp, err := tfvpclattice.FindServiceNetworkServiceAssociationByID(ctx, conn, rs.Primary.ID) if err != nil { - return create.Error(names.VPCLattice, create.ErrActionCheckingExistence, tfvpclattice.ResNameService, rs.Primary.ID, err) + return err } *service = *resp @@ -188,7 +217,7 @@ func testAccCheckServiceNetworkServiceAssociationExists(ctx context.Context, nam } } -func testAccServiceNetworkServiceAssociationConfig_basic(rName string) string { +func testAccServiceNetworkServiceAssociationConfig_base(rName string) string { return fmt.Sprintf(` resource "aws_vpclattice_service" "test" { name = %[1]q @@ -197,53 +226,50 @@ resource "aws_vpclattice_service" "test" { resource "aws_vpclattice_service_network" "test" { name = %[1]q } +`, rName) +} +func testAccServiceNetworkServiceAssociationConfig_basic(rName string) string { + return acctest.ConfigCompose(testAccServiceNetworkServiceAssociationConfig_base(rName), ` resource "aws_vpclattice_service_network_service_association" "test" { service_identifier = aws_vpclattice_service.test.id service_network_identifier = aws_vpclattice_service_network.test.id } -`, rName) +`) } -func testAccServiceNetworkServiceAssociationConfig_tags1(rName, tagKey1, tagValue1 string) string { - return fmt.Sprintf(` -resource "aws_vpclattice_service" "test" { - name = %[1]q +func testAccServiceNetworkServiceAssociationConfig_arn(rName string) string { + return acctest.ConfigCompose(testAccServiceNetworkServiceAssociationConfig_base(rName), ` +resource "aws_vpclattice_service_network_service_association" "test" { + service_identifier = aws_vpclattice_service.test.arn + service_network_identifier = aws_vpclattice_service_network.test.arn } - -resource "aws_vpclattice_service_network" "test" { - name = %[1]q +`) } +func testAccServiceNetworkServiceAssociationConfig_tags1(rName, tagKey1, tagValue1 string) string { + return acctest.ConfigCompose(testAccServiceNetworkServiceAssociationConfig_base(rName), fmt.Sprintf(` resource "aws_vpclattice_service_network_service_association" "test" { service_identifier = aws_vpclattice_service.test.id service_network_identifier = aws_vpclattice_service_network.test.id tags = { - %[2]q = %[3]q + %[1]q = %[2]q } } -`, rName, tagKey1, tagValue1) +`, tagKey1, tagValue1)) } func testAccServiceNetworkServiceAssociationConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { - return fmt.Sprintf(` -resource "aws_vpclattice_service" "test" { - name = %[1]q -} - -resource "aws_vpclattice_service_network" "test" { - name = %[1]q -} - + return acctest.ConfigCompose(testAccServiceNetworkServiceAssociationConfig_base(rName), fmt.Sprintf(` resource "aws_vpclattice_service_network_service_association" "test" { service_identifier = aws_vpclattice_service.test.id service_network_identifier = aws_vpclattice_service_network.test.id tags = { - %[2]q = %[3]q - %[4]q = %[5]q + %[1]q = %[2]q + %[3]q = %[4]q } } -`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +`, tagKey1, tagValue1, tagKey2, tagValue2)) } diff --git a/internal/service/vpclattice/service_package_gen.go b/internal/service/vpclattice/service_package_gen.go index 859dfec595bf..26e1ab516d40 100644 --- a/internal/service/vpclattice/service_package_gen.go +++ b/internal/service/vpclattice/service_package_gen.go @@ -102,7 +102,7 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka }, }, { - Factory: ResourceServiceNetworkServiceAssociation, + Factory: resourceServiceNetworkServiceAssociation, TypeName: "aws_vpclattice_service_network_service_association", Name: "Service Network Service Association", Tags: &types.ServicePackageResourceTags{