terraform-aws-modules / terraform-aws-vpc

Terraform module to create AWS VPC resources πŸ‡ΊπŸ‡¦
https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws
Apache License 2.0
2.98k stars 4.44k forks source link

aws_vpc_ipam_preview_next_cidr forcing changes on subsequent runs #980

Closed glerma closed 1 year ago

glerma commented 1 year ago

Description

I am reporting a problem I cannot seem to get around elegantly or without making a not so ideal workaround.

When using the vpc module with an existing IPAM pool: data.aws_vpc_ipam_preview_next_cidr.this.cidr to get the next cidr to assign to my vpc, cidr argument. On the initial execution, everything works fine, my subnets are created with the sizes needed, transit gateway attachment, and the terraform apply completes successfully.

However, subsequent runs result in changes detected, the terraform plan shows attempts to destroy/replace the vpc and subnets due to the behavior of data.aws_vpc_ipam_preview_next_cidr.this.cidr changing in value. This is not ideal for many reasons. It needs to stay idempotent.

I do not rule out the possibility that i'm doing this wrong. :) - However, maybe this could be a feature or enhancement to allow for ignore_changes lifecycle block in one of the resources in the module source? Perhaps enabled/disabled via a boolean variable?

⚠️ Note

Before you submit an issue, please perform the following first:

  1. Remove the local .terraform directory (! ONLY if state is stored remotely, which hopefully you are following that best practice!): rm -rf .terraform/
  2. Re-initialize the project root to pull down modules: terraform init
  3. Re-attempt your terraform plan or apply and check if the issue still persists

Versions

Reproduction Code [Required]

# Determine the current AWS region (for Terraform 0.13 and later)
data "aws_region" "current" {}

# Retrieve available availability zone names for the current region
data "aws_availability_zones" "available" {}

# Define the IP Pool
data "aws_vpc_ipam_pool" "ipv4" {
  filter {
    name   = "description"
    values = ["*IPAM Pool for Test Environment*"]
  }

  filter {
    name   = "locale"
    values = [data.aws_region.current.name]
  }

  filter {
    name   = "address-family"
    values = ["ipv4"]
  }
}

data "aws_vpc_ipam_preview_next_cidr" "this" {
  ipam_pool_id   = data.aws_vpc_ipam_pool.ipv4.id
  netmask_length = 22
}

# Retrieve Transit Gateway ID based on filter
data "aws_ec2_transit_gateway" "this" {
  filter {
    name   = "options.amazon-side-asn"
    values = ["64526"]
  }
}

# Calculate non-overlapping private subnet CIDRs
locals {

  vpc_cidr = data.aws_vpc_ipam_preview_next_cidr.this.cidr
  private_subnet_count = 3
  public_subnet_count = 3

  private_subnets = [
    for idx in range(local.private_subnet_count) :
    cidrsubnet(local.vpc_cidr, 2, idx) # /24
  ]

  public_subnets = [
    for idx in range(local.public_subnet_count) :
    cidrsubnet(local.vpc_cidr, 4, (local.private_subnet_count * 4) + idx) # /26
  ]

  available_azs = data.aws_availability_zones.available.names
}

# NOTE:
# In order to deprovision CIDRs all Allocations must be released.
# Allocations created by a VPC take up to 30 minutes to be released.
module "vpc" {
  source                        = "terraform-aws-modules/vpc/aws"
  name                          = "vpc-test"
  ipv4_ipam_pool_id         = data.aws_vpc_ipam_pool.ipv4.id
  cidr                          = local.vpc_cidr
  azs                           = local.available_azs
  private_subnets               = local.private_subnets
  enable_dns_support            = true
  enable_dns_hostnames          = true
  manage_default_security_group = false

  # Cloudwatch log group and IAM role will be created
  enable_flow_log                      = true
  create_flow_log_cloudwatch_log_group = true
  create_flow_log_cloudwatch_iam_role  = true

}

resource "aws_ec2_transit_gateway_vpc_attachment" "attach" {
  subnet_ids         = module.vpc.private_subnets
  transit_gateway_id = data.aws_ec2_transit_gateway.this.id
  vpc_id             = module.vpc.vpc_id
}

# Create Subnet Routes referencing the retrieved Transit Gateway ID
resource "aws_route" "tgw" {
  count                  = length(local.private_subnets)
  route_table_id         = module.vpc.private_route_table_ids[count.index]
  destination_cidr_block = "0.0.0.0/0"
  transit_gateway_id     = data.aws_ec2_transit_gateway.this.id
}

Steps to reproduce the behavior:

Are you using workspaces? No Have you cleared the local cache (see Notice section above)?: Yes

Expected behavior

It is expected that when an IP CIDR is obtained then assigned to the vpc cidr argument, subsequent runs of terraform apply will not detect changes and try to destroy/replace the VPC and the subnets.

Actual behavior

Subsequent runs result in changes found, due to the data.aws_vpc_ipam_preview_next_cidr.cidr changing every time.

Terminal Output Screenshot(s)

vpc

Additional context

Context:

Using an existing IP pool. The IP Pool has a existing CIDR.

glerma commented 1 year ago

ping?

nickletelliersi commented 1 year ago

I have a similar issue with the ipv6_ipam_pool_id. On first apply, it finds the pool_id (which I find using the aws_vpc_ipam_pool data source). First apply works ok, however, when I look at the state for the VPC, I find that the ipv6_ipam_pool_id parameter returns "IPAM Managed", which means that every subsequent plans/applies want to change this back to the correct pool_id... Thoughts?

bryantbiggs commented 1 year ago

have you see the guidance shared here https://github.com/hashicorp/terraform-provider-aws/issues/25958#issuecomment-1263608883 ?

glerma commented 1 year ago

have you see the guidance shared here hashicorp/terraform-provider-aws#25958 (comment) ?

I will give it a read! Thanks!

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has been open 30 days with no activity. Remove stale label or comment or this issue will be closed in 10 days

github-actions[bot] commented 1 year ago

This issue was automatically closed because of stale in 10 days

github-actions[bot] commented 11 months ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.