Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vpc): Enable addition amazon provided ipv6 cidr #27274

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/27274.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_vpc_ipv6_cidr_block_association: Add `assign_generated_ipv6_cidr_block` and `ipv6_pool` arguments
```
1 change: 1 addition & 0 deletions internal/service/ec2/exports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ var (
ResourceVPCEndpointService = resourceVPCEndpointService
ResourceVPCEndpointSubnetAssociation = resourceVPCEndpointSubnetAssociation
ResourceVPCIPv4CIDRBlockAssociation = resourceVPCIPv4CIDRBlockAssociation
ResourceVPCIPv6CIDRBlockAssociation = resourceVPCIPv6CIDRBlockAssociation
ResourceVPCPeeringConnection = resourceVPCPeeringConnection
ResourceVPNConnection = resourceVPNConnection
ResourceVPNConnectionRoute = resourceVPNConnectionRoute
Expand Down
48 changes: 33 additions & 15 deletions internal/service/ec2/vpc_ipv6_cidr_block_association.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,39 @@ func resourceVPCIPv6CIDRBlockAssociation() *schema.Resource {
return nil
},
Schema: map[string]*schema.Schema{
"assign_generated_ipv6_cidr_block": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"ipv6_pool", "ipv6_ipam_pool_id", "ipv6_cidr_block", "ipv6_netmask_length"},
},
"ipv6_cidr_block": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validVPCIPv6CIDRBlock,
},
// ipam parameters are not required by the API but other usage mechanisms are not implemented yet. TODO ipv6 options:
// --amazon-provided-ipv6-cidr-block
// --ipv6-pool
"ipv6_ipam_pool_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"assign_generated_ipv6_cidr_block", "ipv6_pool"},
},
"ipv6_netmask_length": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
ValidateFunc: validation.IntInSlice(vpcCIDRValidIPv6Netmasks),
ConflictsWith: []string{"ipv6_cidr_block"},
// This RequiredWith setting should be applied once L57 is completed
// RequiredWith: []string{"ipv6_ipam_pool_id"},
},
"ipv6_pool": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"assign_generated_ipv6_cidr_block", "ipv6_ipam_pool_id"},
},
names.AttrVPCID: {
Type: schema.TypeString,
Expand All @@ -89,6 +99,10 @@ func resourceVPCIPv6CIDRBlockAssociationCreate(ctx context.Context, d *schema.Re
VpcId: aws.String(vpcID),
}

if v, ok := d.GetOk("assign_generated_ipv6_cidr_block"); ok {
input.AmazonProvidedIpv6CidrBlock = aws.Bool(v.(bool))
}

if v, ok := d.GetOk("ipv6_cidr_block"); ok {
input.Ipv6CidrBlock = aws.String(v.(string))
}
Expand All @@ -101,7 +115,10 @@ func resourceVPCIPv6CIDRBlockAssociationCreate(ctx context.Context, d *schema.Re
input.Ipv6NetmaskLength = aws.Int32(int32(v.(int)))
}

log.Printf("[DEBUG] Creating EC2 VPC IPv6 CIDR Block Association: %#v", input)
if v, ok := d.GetOk("ipv6_pool"); ok {
input.Ipv6Pool = aws.String(v.(string))
}

output, err := conn.AssociateVpcCidrBlock(ctx, input)

if err != nil {
Expand All @@ -110,9 +127,7 @@ func resourceVPCIPv6CIDRBlockAssociationCreate(ctx context.Context, d *schema.Re

d.SetId(aws.ToString(output.Ipv6CidrBlockAssociation.AssociationId))

_, err = waitVPCIPv6CIDRBlockAssociationCreated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate))

if err != nil {
if _, err := waitVPCIPv6CIDRBlockAssociationCreated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for EC2 VPC (%s) IPv6 CIDR block (%s) to become associated: %s", vpcID, d.Id(), err)
}

Expand All @@ -135,7 +150,12 @@ func resourceVPCIPv6CIDRBlockAssociationRead(ctx context.Context, d *schema.Reso
return sdkdiag.AppendErrorf(diags, "reading EC2 VPC IPv6 CIDR Block Association (%s): %s", d.Id(), err)
}

ipv6PoolID := aws.ToString(vpcIpv6CidrBlockAssociation.Ipv6Pool)
isAmazonIPv6Pool := ipv6PoolID == amazonIPv6PoolID

d.Set("assign_generated_ipv6_cidr_block", isAmazonIPv6Pool)
d.Set("ipv6_cidr_block", vpcIpv6CidrBlockAssociation.Ipv6CidrBlock)
d.Set("ipv6_pool", ipv6PoolID)
d.Set(names.AttrVPCID, vpc.VpcId)

return diags
Expand All @@ -158,9 +178,7 @@ func resourceVPCIPv6CIDRBlockAssociationDelete(ctx context.Context, d *schema.Re
return sdkdiag.AppendErrorf(diags, "deleting EC2 VPC IPv6 CIDR Block Association (%s): %s", d.Id(), err)
}

err = waitVPCIPv6CIDRBlockAssociationDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete))

if err != nil {
if err := waitVPCIPv6CIDRBlockAssociationDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting for EC2 VPC IPv6 CIDR block (%s) to become disassociated: %s", d.Id(), err)
}

Expand Down
88 changes: 88 additions & 0 deletions internal/service/ec2/vpc_ipv6_cidr_block_association_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,82 @@ import (
"context"
"fmt"
"strings"
"testing"

"github.com/aws/aws-sdk-go-v2/aws"
awstypes "github.com/aws/aws-sdk-go-v2/service/ec2/types"
sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/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"
"github.com/hashicorp/terraform-provider-aws/names"
)

func TestAccVPCIPv6CIDRBlockAssociation_basic(t *testing.T) {
ctx := acctest.Context(t)
var associationSecondary, associationTertiary awstypes.VpcIpv6CidrBlockAssociation
resource1Name := "aws_vpc_ipv6_cidr_block_association.secondary_cidr"
resource2Name := "aws_vpc_ipv6_cidr_block_association.tertiary_cidr"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.EC2ServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckVPCIPv6CIDRBlockAssociationDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccVPCIPv6CIDRBlockAssociationConfig_amazonProvided(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckVPCIPv6CIDRBlockAssociationExists(ctx, resource1Name, &associationSecondary),
testAccCheckVPCIPv6CIDRBlockAssociationExists(ctx, resource2Name, &associationTertiary),
resource.TestCheckResourceAttr(resource1Name, "ipv6_pool", "Amazon"),
resource.TestCheckResourceAttr(resource2Name, "ipv6_pool", "Amazon"),
),
},
{
ResourceName: resource1Name,
ImportState: true,
ImportStateVerify: true,
},
{
ResourceName: resource2Name,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccVPCIPv6CIDRBlockAssociation_disappears(t *testing.T) {
ctx := acctest.Context(t)
var associationSecondary, associationTertiary awstypes.VpcIpv6CidrBlockAssociation
resource1Name := "aws_vpc_ipv6_cidr_block_association.secondary_cidr"
resource2Name := "aws_vpc_ipv6_cidr_block_association.tertiary_cidr"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.EC2ServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckVPCIPv6CIDRBlockAssociationDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccVPCIPv6CIDRBlockAssociationConfig_amazonProvided(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckVPCIPv6CIDRBlockAssociationExists(ctx, resource1Name, &associationSecondary),
testAccCheckVPCIPv6CIDRBlockAssociationExists(ctx, resource2Name, &associationTertiary),
acctest.CheckResourceDisappears(ctx, acctest.Provider, tfec2.ResourceVPCIPv6CIDRBlockAssociation(), resource1Name),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccCheckVPCIPv6CIDRBlockAssociationDestroy(ctx context.Context) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Client(ctx)
Expand Down Expand Up @@ -78,3 +143,26 @@ func testAccCheckVPCAssociationIPv6CIDRPrefix(association *awstypes.VpcIpv6CidrB
return nil
}
}

func testAccVPCIPv6CIDRBlockAssociationConfig_amazonProvided(rName string) string {
return fmt.Sprintf(`
resource "aws_vpc" "test" {
cidr_block = "10.1.0.0/16"
assign_generated_ipv6_cidr_block = true

tags = {
Name = %[1]q
}
}

resource "aws_vpc_ipv6_cidr_block_association" "secondary_cidr" {
vpc_id = aws_vpc.test.id
assign_generated_ipv6_cidr_block = true
}

resource "aws_vpc_ipv6_cidr_block_association" "tertiary_cidr" {
vpc_id = aws_vpc.test.id
assign_generated_ipv6_cidr_block = true
}
`, rName)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ resource "aws_vpc_ipv6_cidr_block_association" "test" {

This resource supports the following arguments:

* `ipv6_cidr_block` - (Optional) The IPv6 CIDR block for the VPC. CIDR can be explicitly set or it can be derived from IPAM using `ipv6_netmask_length`. This parameter is required if `ipv6_netmask_length` is not set and the IPAM pool does not have `allocation_default_netmask` set.
* `ipv6_ipam_pool_id` - (Required) The ID of an IPv6 IPAM pool you want to use for allocating this VPC's CIDR. IPAM is a VPC feature that you can use to automate your IP address management workflows including assigning, tracking, troubleshooting, and auditing IP addresses across AWS Regions and accounts.
* `ipv6_netmask_length` - (Optional) The netmask length of the IPv6 CIDR you want to allocate to this VPC. Requires specifying a `ipv6_ipam_pool_id`. This parameter is optional if the IPAM pool has `allocation_default_netmask` set, otherwise it or `cidr_block` are required
* `assign_generated_ipv6_cidr_block` - (Optional) Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC. You cannot specify the range of IPv6 addresses, or the size of the CIDR block. Default is `false`. Conflicts with `ipv6_pam_pool_id`, `ipv6_pool`, `ipv6_cidr_block` and `ipv6_netmask_length`.
* `ipv6_cidr_block` - (Optional) The IPv6 CIDR block for the VPC. CIDR can be explicitly set or it can be derived from IPAM using `ipv6_netmask_length`. This parameter is required if `ipv6_netmask_length` is not set and the IPAM pool does not have `allocation_default_netmask` set. Conflicts with `assign_generated_ipv6_cidr_block`.
* `ipv6_ipam_pool_id` - - (Optional) The ID of an IPv6 IPAM pool you want to use for allocating this VPC's CIDR. IPAM is a VPC feature that you can use to automate your IP address management workflows including assigning, tracking, troubleshooting, and auditing IP addresses across AWS Regions and accounts. Conflict with `assign_generated_ipv6_cidr_block` and `ipv6_ipam_pool_id`.
* `ipv6_netmask_length` - (Optional) The netmask length of the IPv6 CIDR you want to allocate to this VPC. Requires specifying a `ipv6_ipam_pool_id`. This parameter is optional if the IPAM pool has `allocation_default_netmask` set, otherwise it or `ipv6_cidr_block` are required. Conflicts with `assign_generated_ipv6_cidr_block` and `ipv6_ipam_pool_id`.
* `ipv6_pool` - (Optional) The ID of an IPv6 address pool from which to allocate the IPv6 CIDR block. Conflicts with `ipv6_pam_pool_id`, `ipv6_pool`.
* `vpc_id` - (Required) The ID of the VPC to make the association with.

## Timeouts
Expand Down
Loading