Skip to content

VPC module incompatible with IPv4 cidr_block and IPv6 IPAM pool #1282

@owen-method

Description

@owen-method

Description

The use_ipam_pool variable couples IPv4 and IPv6 IPAM configuration, making it impossible to create a VPC that uses an IPv4 cidr_block with an IPv6 IPAM pool (e.g., BYOIPv6).

When use_ipam_pool = true is set to enable IPv6 IPAM allocation, the module nullifies cidr_block on the aws_vpc resource (main.tf#L33):

cidr_block = var.use_ipam_pool ? null : var.cidr

This results in:

Error: creating EC2 VPC: operation error EC2: CreateVpc, https response error StatusCode: 400,
api error MissingParameter: Either 'cidrBlock' or 'ipv4IpamPoolId' should be provided.

When use_ipam_pool = false, cidr_block is set correctly, but assign_generated_ipv6_cidr_block becomes true (main.tf#L37), which conflicts with ipv6_ipam_pool_id at the provider level:

assign_generated_ipv6_cidr_block = var.enable_ipv6 && !var.use_ipam_pool ? true : null

There is no valid combination of inputs that allows IPv4 cidr_block + IPv6 IPAM pool.

This configuration is fully supported by the AWS API:

aws ec2 create-vpc \
  --cidr 10.0.0.0/16 \
  --ipv6-ipam-pool-id ipam-pool-0123456789abcdef0 \
  --ipv6-netmask-length 56
  • I have searched the open/closed issues and my issue is not listed.

Previous Issues

This was previously raised in #1153 and a fix was submitted in #1155. That PR was closed because it introduced breaking changes (removing use_ipam_pool and replacing it with two new variables). The fix proposed below is fully backwards-compatible and requires no new variables.

Versions

  • Module version: v6.6.0
  • Terraform/OpenTofu version: OpenTofu v1.11.5
  • Provider version(s): AWS provider ~> 6.0

Reproduction Code

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 6.0"

  name = "ipv6-ipam-example"
  cidr = "10.0.0.0/16"

  azs             = ["us-east-2a", "us-east-2b"]
  private_subnets = ["10.0.0.0/20", "10.0.16.0/20"]
  public_subnets  = ["10.0.48.0/24", "10.0.49.0/24"]

  # IPv6 via IPAM (BYOIPv6)
  enable_ipv6         = true
  use_ipam_pool       = true
  ipv6_ipam_pool_id   = "ipam-pool-0123456789abcdef0"  # Replace with your IPAM pool ID
  ipv6_netmask_length = 56

  public_subnet_assign_ipv6_address_on_creation  = true
  public_subnet_ipv6_prefixes                    = [0, 1]
  private_subnet_assign_ipv6_address_on_creation = true
  private_subnet_ipv6_prefixes                   = [2, 3]

  enable_nat_gateway     = true
  single_nat_gateway     = true
  create_egress_only_igw = true
}

Expected behavior

The VPC is created with IPv4 cidr_block = "10.0.0.0/16" and an IPv6 CIDR allocated from the specified IPAM pool.

Actual behavior

CreateVpc fails with MissingParameter: Either 'cidrBlock' or 'ipv4IpamPoolId' should be provided because the module sets cidr_block = null when use_ipam_pool = true.

Suggested Fix

A two-line, backwards-compatible change to main.tf:

- cidr_block          = var.use_ipam_pool ? null : var.cidr
+ cidr_block          = var.use_ipam_pool && var.ipv4_ipam_pool_id != null ? null : var.cidr

- assign_generated_ipv6_cidr_block     = var.enable_ipv6 && !var.use_ipam_pool ? true : null
+ assign_generated_ipv6_cidr_block     = var.enable_ipv6 && !var.use_ipam_pool && var.ipv6_ipam_pool_id == null ? true : null

This preserves existing behavior: cidr_block is only nulled when an IPv4 IPAM pool is actually provided, and assign_generated_ipv6_cidr_block is only set when no IPv6 IPAM pool is specified. No new variables or breaking changes required.

Additional context

I have implemented and validated this fix in a fork: owen-method@bc9225e. Happy to open a PR against this repo if the approach looks good to maintainers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions