From f073afff217d4a972d52fb150125ff310984f5c0 Mon Sep 17 00:00:00 2001 From: Naman Jain Date: Sat, 5 Oct 2024 00:37:44 +0530 Subject: [PATCH 01/10] fix(ipam): set publicly_advertisable only if public_ip_source = byoip and address_family = ipv6 --- internal/service/ec2/ipam_pool.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/ec2/ipam_pool.go b/internal/service/ec2/ipam_pool.go index 3266ea2fc83..9cdb8b23d8b 100644 --- a/internal/service/ec2/ipam_pool.go +++ b/internal/service/ec2/ipam_pool.go @@ -201,7 +201,7 @@ func resourceIPAMPoolCreate(ctx context.Context, d *schema.ResourceData, meta in // PubliclyAdvertisable must be set if if the AddressFamily is IPv6 and PublicIpSource is byoip. // The request can only contain PubliclyAdvertisable if the AddressFamily is IPv6 and PublicIpSource is byoip. - if addressFamily == awstypes.AddressFamilyIpv6 && publicIpSource != awstypes.IpamPoolPublicIpSourceAmazon { + if addressFamily == awstypes.AddressFamilyIpv6 && publicIpSource == awstypes.IpamPoolPublicIpSourceByoip { input.PubliclyAdvertisable = aws.Bool(d.Get("publicly_advertisable").(bool)) } From 329e9a3cd6d769c623df819274a068e7549df746 Mon Sep 17 00:00:00 2001 From: Naman Jain Date: Sat, 5 Oct 2024 00:54:27 +0530 Subject: [PATCH 02/10] add changelog --- .changelog/39600.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/39600.txt diff --git a/.changelog/39600.txt b/.changelog/39600.txt new file mode 100644 index 00000000000..b68e3f5a4bc --- /dev/null +++ b/.changelog/39600.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_vpc_ipam_pool: Allow creation of ipv6 pool in private scope +``` From 0be1037c0012fae7f94c386a2f0133365864bfee Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 7 Oct 2024 10:36:21 -0400 Subject: [PATCH 03/10] Add 'TestAccIPAMPool_ipv6PrivateScope'. --- internal/service/ec2/ipam_pool_test.go | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/internal/service/ec2/ipam_pool_test.go b/internal/service/ec2/ipam_pool_test.go index 3ce9531917c..749ba3be707 100644 --- a/internal/service/ec2/ipam_pool_test.go +++ b/internal/service/ec2/ipam_pool_test.go @@ -234,6 +234,27 @@ func TestAccIPAMPool_tags(t *testing.T) { }) } +func TestAccIPAMPool_ipv6PrivateScope(t *testing.T) { + ctx := acctest.Context(t) + var pool awstypes.IpamPool + resourceName := "aws_vpc_ipam_pool.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.EC2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckIPAMPoolDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccIPAMPoolConfig_ipv6PrivateScope, + Check: resource.ComposeTestCheckFunc( + testAccCheckIPAMPoolExists(ctx, resourceName, &pool), + ), + }, + }, + }) +} + func testAccCheckIPAMPoolExists(ctx context.Context, n string, v *awstypes.IpamPool) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -384,3 +405,15 @@ resource "aws_vpc_ipam_pool" "test" { } `, tagKey1, tagValue1, tagKey2, tagValue2)) } + +var testAccIPAMPoolConfig_ipv6PrivateScope = acctest.ConfigCompose(testAccIPAMScopeConfig_base, ` +resource "aws_vpc_ipam_scope" "test" { + ipam_id = aws_vpc_ipam.test.id +} + +resource "aws_vpc_ipam_pool" "test" { + address_family = "ipv6" + ipam_scope_id = aws_vpc_ipam_scope.test.id + locale = data.aws_region.current.name +} +`) From 179edced4767686f3e313a3d8fdc107b5c67da3a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 7 Oct 2024 12:01:05 -0400 Subject: [PATCH 04/10] Update 39600.txt --- .changelog/39600.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/39600.txt b/.changelog/39600.txt index b68e3f5a4bc..9a0987a05e2 100644 --- a/.changelog/39600.txt +++ b/.changelog/39600.txt @@ -1,3 +1,3 @@ ```release-note:bug -resource/aws_vpc_ipam_pool: Allow creation of ipv6 pool in private scope +resource/aws_vpc_ipam_pool: Fix `InvalidParameterCombination: The request can only contain PubliclyAdvertisable if the AddressFamily is IPv6 and PublicIpSource is byoip` errors ``` From b47ab4cb5f4997713813366c999cb8dade005027 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 7 Oct 2024 14:28:33 -0400 Subject: [PATCH 05/10] r/aws_vpc_ipam_pool: Always set PubliclyAdvertisable for IPv6. --- internal/service/ec2/ipam_pool.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/internal/service/ec2/ipam_pool.go b/internal/service/ec2/ipam_pool.go index 9cdb8b23d8b..106a124359d 100644 --- a/internal/service/ec2/ipam_pool.go +++ b/internal/service/ec2/ipam_pool.go @@ -193,18 +193,16 @@ func resourceIPAMPoolCreate(ctx context.Context, d *schema.ResourceData, meta in input.AwsService = awstypes.IpamPoolAwsService(v.(string)) } - var publicIpSource awstypes.IpamPoolPublicIpSource - if v, ok := d.GetOk("public_ip_source"); ok { - publicIpSource = awstypes.IpamPoolPublicIpSource(v.(string)) - input.PublicIpSource = publicIpSource - } - // PubliclyAdvertisable must be set if if the AddressFamily is IPv6 and PublicIpSource is byoip. // The request can only contain PubliclyAdvertisable if the AddressFamily is IPv6 and PublicIpSource is byoip. - if addressFamily == awstypes.AddressFamilyIpv6 && publicIpSource == awstypes.IpamPoolPublicIpSourceByoip { + if addressFamily == awstypes.AddressFamilyIpv6 { input.PubliclyAdvertisable = aws.Bool(d.Get("publicly_advertisable").(bool)) } + if v, ok := d.GetOk("public_ip_source"); ok { + input.PublicIpSource = awstypes.IpamPoolPublicIpSource(v.(string)) + } + if v, ok := d.GetOk("source_ipam_pool_id"); ok { input.SourceIpamPoolId = aws.String(v.(string)) } From 5b36b78df56532a1c652418701124e2f2fabab0f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 8 Oct 2024 11:37:48 -0400 Subject: [PATCH 06/10] r/aws_vpc_ipam_pool: Old logic. --- internal/service/ec2/ipam_pool.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/service/ec2/ipam_pool.go b/internal/service/ec2/ipam_pool.go index 106a124359d..08e9d8fb30a 100644 --- a/internal/service/ec2/ipam_pool.go +++ b/internal/service/ec2/ipam_pool.go @@ -193,16 +193,17 @@ func resourceIPAMPoolCreate(ctx context.Context, d *schema.ResourceData, meta in input.AwsService = awstypes.IpamPoolAwsService(v.(string)) } + var publicIPSource awstypes.IpamPoolPublicIpSource + if v, ok := d.GetOk("public_ip_source"); ok { + publicIPSource = awstypes.IpamPoolPublicIpSource(v.(string)) + input.PublicIpSource = publicIPSource + } // PubliclyAdvertisable must be set if if the AddressFamily is IPv6 and PublicIpSource is byoip. // The request can only contain PubliclyAdvertisable if the AddressFamily is IPv6 and PublicIpSource is byoip. - if addressFamily == awstypes.AddressFamilyIpv6 { + if addressFamily == awstypes.AddressFamilyIpv6 && publicIPSource != awstypes.IpamPoolPublicIpSourceAmazon { input.PubliclyAdvertisable = aws.Bool(d.Get("publicly_advertisable").(bool)) } - if v, ok := d.GetOk("public_ip_source"); ok { - input.PublicIpSource = awstypes.IpamPoolPublicIpSource(v.(string)) - } - if v, ok := d.GetOk("source_ipam_pool_id"); ok { input.SourceIpamPoolId = aws.String(v.(string)) } From 9b9874ef6bfdf1efa24a009ef5169df5ae409df9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 8 Oct 2024 15:28:37 -0400 Subject: [PATCH 07/10] r/aws_vpc_ipam: Add `enable_private_gua` argument. --- .changelog/39600.txt | 4 ++ internal/service/ec2/ipam_.go | 14 +++++++ internal/service/ec2/ipam_test.go | 53 +++++++++++++++++++++++++-- website/docs/r/vpc_ipam.html.markdown | 1 + 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/.changelog/39600.txt b/.changelog/39600.txt index 9a0987a05e2..956c11f48d1 100644 --- a/.changelog/39600.txt +++ b/.changelog/39600.txt @@ -1,3 +1,7 @@ ```release-note:bug resource/aws_vpc_ipam_pool: Fix `InvalidParameterCombination: The request can only contain PubliclyAdvertisable if the AddressFamily is IPv6 and PublicIpSource is byoip` errors ``` + +```release-note:enhancement +resource/aws_vpc_ipam: Add `enable_private_gua` argument +``` diff --git a/internal/service/ec2/ipam_.go b/internal/service/ec2/ipam_.go index 3bb1ea5aeb7..5f1afabeab4 100644 --- a/internal/service/ec2/ipam_.go +++ b/internal/service/ec2/ipam_.go @@ -67,6 +67,11 @@ func resourceIPAM() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "enable_private_gua": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "operating_regions": { Type: schema.TypeSet, Required: true, @@ -137,6 +142,10 @@ func resourceIPAMCreate(ctx context.Context, d *schema.ResourceData, meta interf input.Description = aws.String(v.(string)) } + if v, ok := d.GetOk("enable_private_gua"); ok { + input.EnablePrivateGua = aws.Bool(v.(bool)) + } + if v, ok := d.GetOk("tier"); ok { input.Tier = awstypes.IpamTier(v.(string)) } @@ -176,6 +185,7 @@ func resourceIPAMRead(ctx context.Context, d *schema.ResourceData, meta interfac d.Set("default_resource_discovery_association_id", ipam.DefaultResourceDiscoveryAssociationId) d.Set("default_resource_discovery_id", ipam.DefaultResourceDiscoveryId) d.Set(names.AttrDescription, ipam.Description) + d.Set("enable_private_gua", ipam.EnablePrivateGua) if err := d.Set("operating_regions", flattenIPAMOperatingRegions(ipam.OperatingRegions)); err != nil { return sdkdiag.AppendErrorf(diags, "setting operating_regions: %s", err) } @@ -202,6 +212,10 @@ func resourceIPAMUpdate(ctx context.Context, d *schema.ResourceData, meta interf input.Description = aws.String(d.Get(names.AttrDescription).(string)) } + if d.HasChange("enable_private_gua") { + input.EnablePrivateGua = aws.Bool(d.Get("enable_private_gua").(bool)) + } + if d.HasChange("operating_regions") { o, n := d.GetChange("operating_regions") if o == nil { diff --git a/internal/service/ec2/ipam_test.go b/internal/service/ec2/ipam_test.go index 655847cced9..d14b8d92a9d 100644 --- a/internal/service/ec2/ipam_test.go +++ b/internal/service/ec2/ipam_test.go @@ -39,6 +39,7 @@ func TestAccIPAM_basic(t *testing.T) { testAccCheckIPAMExists(ctx, resourceName, &ipam), resource.TestCheckResourceAttrSet(resourceName, names.AttrARN), resource.TestCheckResourceAttr(resourceName, names.AttrDescription, ""), + resource.TestCheckResourceAttr(resourceName, "enable_private_gua", acctest.CtFalse), resource.TestCheckResourceAttr(resourceName, "operating_regions.#", acctest.Ct1), resource.TestCheckResourceAttr(resourceName, "scope_count", acctest.Ct2), resource.TestMatchResourceAttr(resourceName, "private_default_scope_id", regexache.MustCompile(`^ipam-scope-[0-9a-f]+`)), @@ -262,6 +263,40 @@ func TestAccIPAM_tags(t *testing.T) { }) } +func TestAccIPAM_enablePrivateGUA(t *testing.T) { + ctx := acctest.Context(t) + var ipam awstypes.Ipam + resourceName := "aws_vpc_ipam.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.EC2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckIPAMDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccIPAMConfig_enablePrivateGUA(true), + Check: resource.ComposeTestCheckFunc( + testAccCheckIPAMExists(ctx, resourceName, &ipam), + resource.TestCheckResourceAttr(resourceName, "enable_private_gua", acctest.CtTrue), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccIPAMConfig_enablePrivateGUA(false), + Check: resource.ComposeTestCheckFunc( + testAccCheckIPAMExists(ctx, resourceName, &ipam), + resource.TestCheckResourceAttr(resourceName, "enable_private_gua", acctest.CtFalse), + ), + }, + }, + }) +} + func testAccCheckIPAMExists(ctx context.Context, n string, v *awstypes.Ipam) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -269,10 +304,6 @@ func testAccCheckIPAMExists(ctx context.Context, n string, v *awstypes.Ipam) res return fmt.Errorf("Not found: %s", n) } - if rs.Primary.ID == "" { - return fmt.Errorf("No IPAM ID is set") - } - conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Client(ctx) output, err := tfec2.FindIPAMByID(ctx, conn, rs.Primary.ID) @@ -426,3 +457,17 @@ resource "aws_vpc_ipam" "test" { } `, tier) } + +func testAccIPAMConfig_enablePrivateGUA(enablePrivateGUA bool) string { + return fmt.Sprintf(` +data "aws_region" "current" {} + +resource "aws_vpc_ipam" "test" { + enable_private_gua = %[1]t + + operating_regions { + region_name = data.aws_region.current.name + } +} +`, enablePrivateGUA) +} diff --git a/website/docs/r/vpc_ipam.html.markdown b/website/docs/r/vpc_ipam.html.markdown index 72723ed0f5a..cf87b2aa0e9 100644 --- a/website/docs/r/vpc_ipam.html.markdown +++ b/website/docs/r/vpc_ipam.html.markdown @@ -61,6 +61,7 @@ This resource supports the following arguments: * `cascade` - (Optional) Enables you to quickly delete an IPAM, private scopes, pools in private scopes, and any allocations in the pools in private scopes. * `description` - (Optional) A description for the IPAM. +* `enable_private_gua` - (Optional) Enable this option to use your own GUA ranges as private IPv6 addresses. Default: `false`. * `operating_regions` - (Required) Determines which locales can be chosen when you create pools. Locale is the Region where you want to make an IPAM pool available for allocations. You can only create pools with locales that match the operating Regions of the IPAM. You can only create VPCs from a pool whose locale matches the VPC's Region. You specify a region using the [region_name](#operating_regions) parameter. You **must** set your provider block region as an operating_region. * `tier` - (Optional) specifies the IPAM tier. Valid options include `free` and `advanced`. Default is `advanced`. * `tags` - (Optional) A map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. From 8dbd50ecca088473cdd26f0c608d165542f15df1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 8 Oct 2024 16:07:39 -0400 Subject: [PATCH 08/10] r/aws_vpc_ipv6_cidr_block_association: Add `ip_source` and `ipv6_address_attribute` attributes. --- .changelog/39600.txt | 5 +++++ .../service/ec2/vpc_ipv6_cidr_block_association.go | 10 ++++++++++ .../ec2/vpc_ipv6_cidr_block_association_test.go | 4 ++++ .../r/vpc_ipv6_cidr_block_association.html.markdown | 4 +++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/.changelog/39600.txt b/.changelog/39600.txt index 956c11f48d1..2188a286318 100644 --- a/.changelog/39600.txt +++ b/.changelog/39600.txt @@ -5,3 +5,8 @@ resource/aws_vpc_ipam_pool: Fix `InvalidParameterCombination: The request can on ```release-note:enhancement resource/aws_vpc_ipam: Add `enable_private_gua` argument ``` + + +```release-note:enhancement +resource/aws_vpc_ipv6_cidr_block_association: Add `ip_source` and `ipv6_address_attribute` attributes +``` \ No newline at end of file diff --git a/internal/service/ec2/vpc_ipv6_cidr_block_association.go b/internal/service/ec2/vpc_ipv6_cidr_block_association.go index 916684e69a2..5920af6bd6d 100644 --- a/internal/service/ec2/vpc_ipv6_cidr_block_association.go +++ b/internal/service/ec2/vpc_ipv6_cidr_block_association.go @@ -49,6 +49,14 @@ func resourceVPCIPv6CIDRBlockAssociation() *schema.Resource { ForceNew: true, ConflictsWith: []string{"ipv6_pool", "ipv6_ipam_pool_id", "ipv6_cidr_block", "ipv6_netmask_length"}, }, + "ip_source": { + Type: schema.TypeString, + Computed: true, + }, + "ipv6_address_attribute": { + Type: schema.TypeString, + Computed: true, + }, "ipv6_cidr_block": { Type: schema.TypeString, Optional: true, @@ -154,6 +162,8 @@ func resourceVPCIPv6CIDRBlockAssociationRead(ctx context.Context, d *schema.Reso isAmazonIPv6Pool := ipv6PoolID == amazonIPv6PoolID d.Set("assign_generated_ipv6_cidr_block", isAmazonIPv6Pool) + d.Set("ip_source", vpcIpv6CidrBlockAssociation.IpSource) + d.Set("ipv6_address_attribute", vpcIpv6CidrBlockAssociation.Ipv6AddressAttribute) d.Set("ipv6_cidr_block", vpcIpv6CidrBlockAssociation.Ipv6CidrBlock) d.Set("ipv6_pool", ipv6PoolID) d.Set(names.AttrVPCID, vpc.VpcId) diff --git a/internal/service/ec2/vpc_ipv6_cidr_block_association_test.go b/internal/service/ec2/vpc_ipv6_cidr_block_association_test.go index be53c000c7d..34722918a21 100644 --- a/internal/service/ec2/vpc_ipv6_cidr_block_association_test.go +++ b/internal/service/ec2/vpc_ipv6_cidr_block_association_test.go @@ -39,6 +39,10 @@ func TestAccVPCIPv6CIDRBlockAssociation_basic(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( testAccCheckVPCIPv6CIDRBlockAssociationExists(ctx, resource1Name, &associationSecondary), testAccCheckVPCIPv6CIDRBlockAssociationExists(ctx, resource2Name, &associationTertiary), + resource.TestCheckResourceAttr(resource1Name, "ip_source", "amazon"), + resource.TestCheckResourceAttr(resource2Name, "ip_source", "amazon"), + resource.TestCheckResourceAttr(resource1Name, "ipv6_address_attribute", "public"), + resource.TestCheckResourceAttr(resource2Name, "ipv6_address_attribute", "public"), resource.TestCheckResourceAttr(resource1Name, "ipv6_pool", "Amazon"), resource.TestCheckResourceAttr(resource2Name, "ipv6_pool", "Amazon"), ), diff --git a/website/docs/r/vpc_ipv6_cidr_block_association.html.markdown b/website/docs/r/vpc_ipv6_cidr_block_association.html.markdown index b4a4275de59..e696bf26615 100644 --- a/website/docs/r/vpc_ipv6_cidr_block_association.html.markdown +++ b/website/docs/r/vpc_ipv6_cidr_block_association.html.markdown @@ -47,7 +47,9 @@ This resource supports the following arguments: This resource exports the following attributes in addition to the arguments above: -* `id` - The ID of the VPC CIDR association +* `id` - The ID of the VPC CIDR association. +* `ip_source` - The source that allocated the IP address space. Values: `amazon`, `byoip`, `none`. +* `ipv6_address_attribute` - Public IPv6 addresses are those advertised on the internet from AWS. Private IP addresses are not and cannot be advertised on the internet from AWS. Values: `public`, `private`. ## Import From ab054c237e0685b326629bd23de7230b7cd8de03 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 8 Oct 2024 17:10:09 -0400 Subject: [PATCH 09/10] r/aws_vpc_ipam_pool: Use IpamScopeType to determine whether to send PubliclyAdvertisable. --- internal/service/ec2/ipam_pool.go | 15 ++++++++++----- internal/service/ec2/ipam_pool_test.go | 26 +++++++++++++------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/internal/service/ec2/ipam_pool.go b/internal/service/ec2/ipam_pool.go index 08e9d8fb30a..290f5453923 100644 --- a/internal/service/ec2/ipam_pool.go +++ b/internal/service/ec2/ipam_pool.go @@ -153,11 +153,18 @@ func resourceIPAMPoolCreate(ctx context.Context, d *schema.ResourceData, meta in var diags diag.Diagnostics conn := meta.(*conns.AWSClient).EC2Client(ctx) + scopeID := d.Get("ipam_scope_id").(string) + scope, err := findIPAMScopeByID(ctx, conn, scopeID) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "reading IPAM Scope (%s): %s", scopeID, err) + } + addressFamily := awstypes.AddressFamily(d.Get("address_family").(string)) input := &ec2.CreateIpamPoolInput{ AddressFamily: addressFamily, ClientToken: aws.String(id.UniqueId()), - IpamScopeId: aws.String(d.Get("ipam_scope_id").(string)), + IpamScopeId: aws.String(scopeID), TagSpecifications: getTagSpecificationsIn(ctx, awstypes.ResourceTypeIpamPool), } @@ -193,14 +200,12 @@ func resourceIPAMPoolCreate(ctx context.Context, d *schema.ResourceData, meta in input.AwsService = awstypes.IpamPoolAwsService(v.(string)) } - var publicIPSource awstypes.IpamPoolPublicIpSource if v, ok := d.GetOk("public_ip_source"); ok { - publicIPSource = awstypes.IpamPoolPublicIpSource(v.(string)) - input.PublicIpSource = publicIPSource + input.PublicIpSource = awstypes.IpamPoolPublicIpSource(v.(string)) } // PubliclyAdvertisable must be set if if the AddressFamily is IPv6 and PublicIpSource is byoip. // The request can only contain PubliclyAdvertisable if the AddressFamily is IPv6 and PublicIpSource is byoip. - if addressFamily == awstypes.AddressFamilyIpv6 && publicIPSource != awstypes.IpamPoolPublicIpSourceAmazon { + if addressFamily == awstypes.AddressFamilyIpv6 && scope.IpamScopeType == awstypes.IpamScopeTypePublic { input.PubliclyAdvertisable = aws.Bool(d.Get("publicly_advertisable").(bool)) } diff --git a/internal/service/ec2/ipam_pool_test.go b/internal/service/ec2/ipam_pool_test.go index 749ba3be707..ca3ff469ade 100644 --- a/internal/service/ec2/ipam_pool_test.go +++ b/internal/service/ec2/ipam_pool_test.go @@ -306,6 +306,19 @@ func testAccCheckIPAMPoolDestroy(ctx context.Context) resource.TestCheckFunc { } } +func testAccCheckIPAMPoolCIDRCreate(ctx context.Context, ipampool *awstypes.IpamPool) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Client(ctx) + + _, err := conn.ProvisionIpamPoolCidr(ctx, &ec2.ProvisionIpamPoolCidrInput{ + IpamPoolId: ipampool.IpamPoolId, + Cidr: aws.String("10.0.0.0/16"), + }) + + return err + } +} + const testAccIPAMPoolConfig_base = ` data "aws_region" "current" {} @@ -366,19 +379,6 @@ resource "aws_vpc_ipam_pool" "test" { } `) -func testAccCheckIPAMPoolCIDRCreate(ctx context.Context, ipampool *awstypes.IpamPool) resource.TestCheckFunc { - return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Client(ctx) - - _, err := conn.ProvisionIpamPoolCidr(ctx, &ec2.ProvisionIpamPoolCidrInput{ - IpamPoolId: ipampool.IpamPoolId, - Cidr: aws.String("10.0.0.0/16"), - }) - - return err - } -} - func testAccIPAMPoolConfig_tags(tagKey1, tagValue1 string) string { return acctest.ConfigCompose(testAccIPAMPoolConfig_base, fmt.Sprintf(` resource "aws_vpc_ipam_pool" "test" { From 749e16dd98666a5d6b08e407101996f8fdf0da58 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 8 Oct 2024 17:13:18 -0400 Subject: [PATCH 10/10] r/aws_vpc_ipam_pool: Change `publicly_advertisable` to ForceNew. --- .changelog/39600.txt | 4 ++++ internal/service/ec2/ipam_pool.go | 1 + 2 files changed, 5 insertions(+) diff --git a/.changelog/39600.txt b/.changelog/39600.txt index 2188a286318..796358090c7 100644 --- a/.changelog/39600.txt +++ b/.changelog/39600.txt @@ -2,6 +2,10 @@ resource/aws_vpc_ipam_pool: Fix `InvalidParameterCombination: The request can only contain PubliclyAdvertisable if the AddressFamily is IPv6 and PublicIpSource is byoip` errors ``` +```release-note:bug +resource/aws_vpc_ipam_pool: Change `publicly_advertisable` to [ForceNew](https://developer.hashicorp.com/terraform/plugin/sdkv2/schemas/schema-behaviors#forcenew) +``` + ```release-note:enhancement resource/aws_vpc_ipam: Add `enable_private_gua` argument ``` diff --git a/internal/service/ec2/ipam_pool.go b/internal/service/ec2/ipam_pool.go index 290f5453923..6f674203e0a 100644 --- a/internal/service/ec2/ipam_pool.go +++ b/internal/service/ec2/ipam_pool.go @@ -131,6 +131,7 @@ func resourceIPAMPool() *schema.Resource { "publicly_advertisable": { Type: schema.TypeBool, Optional: true, + ForceNew: true, }, "source_ipam_pool_id": { Type: schema.TypeString,