Terraform AWS vpc 自定义模块重新创建路由表和子网

时间:2021-04-14 16:16:09

标签: terraform terraform-provider-aws

我有以下复杂的地形模块

vpc.tf


resource "aws_vpc" "main_vpc" {
  cidr_block           = var.vpc_range

  enable_dns_support   = true
  enable_dns_hostnames = true
}

resource "aws_internet_gateway" "main_vpc_gateway" {
  vpc_id       = aws_vpc.main_vpc.id
}

resource "aws_subnet" "main_subnets" {
  vpc_id                  = aws_vpc.main_vpc.id
  for_each                = { for cidr_data in local.subnet_cidr_range: cidr_data.subnet_name => cidr_data }
  cidr_block              = each.value.subnet_cidr
  availability_zone_id    = each.value.subnet_az_id
  map_public_ip_on_launch = each.value.is_public
}

resource "aws_route_table" "subnet_route_tables" {
  vpc_id                  = aws_vpc.main_vpc.id
  for_each                = { for cidr_data in local.subnet_cidr_range: cidr_data.subnet_name => cidr_data }
}

resource "aws_route_table_association" "subnet_route_table_associations" {
  for_each       = { for route_table_association_details in local.route_table_association_details: route_table_association_details.subnet_name => route_table_association_details }

  subnet_id      = each.value.subnet_id
  route_table_id = each.value.route_table_id
}

resource "aws_route" "vpc_default_gateway" {
  route_table_id         = aws_vpc.main_vpc.main_route_table_id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.main_vpc_gateway.id
}

resource "aws_route" "subnet_internet_gateway" {
  for_each               = { for details in local.created_subnet_details: details.subnet_name => details if details.is_public }

  route_table_id         = each.value.route_table_id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.main_vpc_gateway.id
}

resource "aws_nat_gateway" "vpc_gateways" {
  for_each               = { for nat_details in local.private_nat_gateway_details: nat_details.availability_zone => nat_details }
  depends_on             = [ aws_internet_gateway.main_vpc_gateway ]

  allocation_id          = lookup(lookup(data.aws_eip.nat_gateway_ips, each.value.availability_zone, ""), "id", "")
  subnet_id              = each.value.nat_public_subnet_details.subnet_id
}

resource "aws_route" "subnet_nat_gateway" {
  for_each               = { for details in local.created_subnet_details: details.subnet_name => details if !details.is_public && details.subnet_type != "pvt_internal_privileged" }

  route_table_id         = each.value.route_table_id
  destination_cidr_block = "0.0.0.0/0"
  nat_gateway_id         = lookup(lookup(aws_nat_gateway.vpc_gateways, each.value.availability_zone, ""), "id", "")
}

data.tf

data "aws_availability_zones" "all_azs" {
  state       = "available"
}

data "aws_eip" "nat_gateway_ips" {
  for_each    = var.nat_gateway_ips

  public_ip   = each.value
}

locals.tf


locals {
  subnet_id_map = zipmap(data.aws_availability_zones.all_azs.names, data.aws_availability_zones.all_azs.zone_ids)

  subnet_cidr_range = flatten([
    for each_subnet in var.all_subnets : [
      for each_az in each_subnet.azs : {
        subnet_type                 = each_subnet.name
        subnet_az                   = each_az.name
        subnet_cidr                 = each_az.range
        subnet_name                 = "${replace(each_az.name, "-", "_")}_${each_subnet.name}"
        subnet_az_id                = local.subnet_id_map[each_az.name]
        is_public                   = length(regexall("^pub.*", each_subnet.name)) > 0
      }
    ]
  ])

  created_subnet_details = ([
    for each_subnet in local.subnet_cidr_range : {
      subnet_name                   = each_subnet.subnet_name
      is_public                     = each_subnet.is_public
      subnet_type                   = each_subnet.subnet_type
      subnet_cidr                   = each_subnet.subnet_cidr
      subnet_id                     = lookup(lookup(aws_subnet.main_subnets, each_subnet.subnet_name, {}), "id", "")
      route_table_id                = lookup(lookup(aws_route_table.subnet_route_tables, each_subnet.subnet_name, {}), "id", "")
      availability_zone             = each_subnet.subnet_az
    }
  ])

  created_subnet_map = { for details in local.created_subnet_details: details.subnet_name => details }

  route_table_association_details = ([
    for each_subnet in local.subnet_cidr_range : {
      subnet_id                     = lookup(lookup(aws_subnet.main_subnets, each_subnet.subnet_name, {}), "id", "")
      route_table_id                = lookup(lookup(aws_route_table.subnet_route_tables, each_subnet.subnet_name, {}), "id", "")
      subnet_name                   = each_subnet.subnet_name
    }
    ])

  # Retrive distinct AZs we want the nat gateways in
  private_nat_gateway_azs = distinct([
    for details in local.created_subnet_details: details.availability_zone if !details.is_public && details.subnet_type != "pvt_internal_privileged"
  ])

  private_nat_gateway_details = ([
    for details in local.private_nat_gateway_azs: {
      availability_zone             = details
      nat_public_subnet_details     = lookup(local.created_subnet_map, "${replace(details, "-", "_")}_pub_apps_cust", "")
    }
  ])

}

variables.tf

variable "region" {
  type = string
}

variable "vpc_range" {
  type = string
}

variable "all_subnets" {}

variable "cluster" {
  type = string
}

variable "nat_gateway_ips" {
 type = map
}

variable "sensitive_nat_gateway_ips" {
 type = map
}

outputs.tf

output "created_subnet_details" {
  value = { for details in local.created_subnet_details: details.subnet_name => details }
}

output "vpc_details" {
  value = aws_vpc.main_vpc
}

并调用这个模块

root.tf

module "vpc-sa-east-1" {
  source                    = "../../../modules/vpc"
  providers                 = {
                                aws = aws.sa-east-1
                              }
  region                    = "sa-east-1"
  cluster                   = ""
  vpc_range                 = "10.73.0.0/16"
  nat_gateway_ips           = {}
  sensitive_nat_gateway_ips = {}
  all_subnets               = [ {
                                name: "pub_apps_cust",
                                azs: [{
                                  name: "sa-east-1a"
                                  range: "10.73.164.0/25"
                                }, {
                                  name: "sa-east-1b"
                                  range: "10.73.164.128/25"
                                }]
                              }]
}

当我尝试在 all_subnets 变量中添加一个新的数组元素并运行 terraform plan 时,它显示它将强制替换 subnetroute table,这将固有地尝试替换routeroute table association

module "vpc-sa-east-1" {
  source                    = "../../../modules/vpc"
  providers                 = {
                                aws = aws.sa-east-1
                              }
  region                    = "sa-east-1"
  cluster                   = ""
  vpc_range                 = "10.73.0.0/16"
  nat_gateway_ips           = {}
  sensitive_nat_gateway_ips = {}
  all_subnets               = [ {
                                name: "pub_apps_cust",
                                azs: [{
                                  name: "sa-east-1a"
                                  range: "10.73.164.0/25"
                                }, {
                                  name: "sa-east-1b"
                                  range: "10.73.164.128/25"
                                }]
                              },
                              {
                                name: "pub_apps_internal",
                                azs: [{
                                  name: "sa-east-1a"
                                  range: "10.73.165.0/25"
                                }, {
                                  name: "sa-east-1b"
                                  range: "10.73.165.128/25"
                                }]
                              }
                              ]
}
module.vpc-sa-east-1.data.aws_availability_zones.all_azs: Refreshing state...
module.vpc-sa-east-1.aws_vpc.main_vpc: Refreshing state... [id=vpc-03290a49cb9a5f386]
module.vpc-sa-east-1.aws_internet_gateway.main_vpc_gateway: Refreshing state... [id=igw-0c347532f77a6d3f1]
module.vpc-sa-east-1.aws_route_table.subnet_route_tables["sa_east_1a_pub_apps_cust"]: Refreshing state... [id=rtb-09007bf313da448a7]
module.vpc-sa-east-1.aws_route_table.subnet_route_tables["sa_east_1b_pub_apps_cust"]: Refreshing state... [id=rtb-02a9db11897c33a60]
module.vpc-sa-east-1.aws_subnet.main_subnets["sa_east_1a_pub_apps_cust"]: Refreshing state... [id=subnet-03e76a75c4657f8c3]
module.vpc-sa-east-1.aws_subnet.main_subnets["sa_east_1b_pub_apps_cust"]: Refreshing state... [id=subnet-002840ae3c5946fe8]
module.vpc-sa-east-1.aws_route.vpc_default_gateway: Refreshing state... [id=r-rtb-0bd35615cda8a41381080289494]
module.vpc-sa-east-1.aws_route_table_association.subnet_route_table_associations["sa_east_1a_pub_apps_cust"]: Refreshing state... [id=rtbassoc-0ff404ba7fb15473f]
module.vpc-sa-east-1.aws_route_table_association.subnet_route_table_associations["sa_east_1b_pub_apps_cust"]: Refreshing state... [id=rtbassoc-07309d0b46df5a8e3]
module.vpc-sa-east-1.aws_route.subnet_internet_gateway["sa_east_1b_pub_apps_cust"]: Refreshing state... [id=r-rtb-02a9db11897c33a601080289494]
module.vpc-sa-east-1.aws_route.subnet_internet_gateway["sa_east_1a_pub_apps_cust"]: Refreshing state... [id=r-rtb-09007bf313da448a71080289494]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # module.vpc-sa-east-1.aws_route.subnet_internet_gateway["sa_east_1a_pub_apps_cust"] must be replaced
-/+ resource "aws_route" "subnet_internet_gateway" {
        destination_cidr_block     = "0.0.0.0/0"
      + destination_prefix_list_id = (known after apply)
      + egress_only_gateway_id     = (known after apply)
        gateway_id                 = "igw-0c347532f77a6d3f1"
      ~ id                         = "r-rtb-09007bf313da448a71080289494" -> (known after apply)
      + instance_id                = (known after apply)
      + instance_owner_id          = (known after apply)
      + nat_gateway_id             = (known after apply)
      + network_interface_id       = (known after apply)
      ~ origin                     = "CreateRoute" -> (known after apply)
      ~ route_table_id             = "rtb-09007bf313da448a7" -> (known after apply) # forces replacement
      ~ state                      = "active" -> (known after apply)
    }

  # module.vpc-sa-east-1.aws_route.subnet_internet_gateway["sa_east_1a_pub_apps_internal"] will be created
  + resource "aws_route" "subnet_internet_gateway" {
      + destination_cidr_block     = "0.0.0.0/0"
      + destination_prefix_list_id = (known after apply)
      + egress_only_gateway_id     = (known after apply)
      + gateway_id                 = "igw-0c347532f77a6d3f1"
      + id                         = (known after apply)
      + instance_id                = (known after apply)
      + instance_owner_id          = (known after apply)
      + nat_gateway_id             = (known after apply)
      + network_interface_id       = (known after apply)
      + origin                     = (known after apply)
      + route_table_id             = (known after apply)
      + state                      = (known after apply)
    }

  # module.vpc-sa-east-1.aws_route.subnet_internet_gateway["sa_east_1b_pub_apps_cust"] must be replaced
-/+ resource "aws_route" "subnet_internet_gateway" {
        destination_cidr_block     = "0.0.0.0/0"
      + destination_prefix_list_id = (known after apply)
      + egress_only_gateway_id     = (known after apply)
        gateway_id                 = "igw-0c347532f77a6d3f1"
      ~ id                         = "r-rtb-02a9db11897c33a601080289494" -> (known after apply)
      + instance_id                = (known after apply)
      + instance_owner_id          = (known after apply)
      + nat_gateway_id             = (known after apply)
      + network_interface_id       = (known after apply)
      ~ origin                     = "CreateRoute" -> (known after apply)
      ~ route_table_id             = "rtb-02a9db11897c33a60" -> (known after apply) # forces replacement
      ~ state                      = "active" -> (known after apply)
    }

  # module.vpc-sa-east-1.aws_route.subnet_internet_gateway["sa_east_1b_pub_apps_internal"] will be created
  + resource "aws_route" "subnet_internet_gateway" {
      + destination_cidr_block     = "0.0.0.0/0"
      + destination_prefix_list_id = (known after apply)
      + egress_only_gateway_id     = (known after apply)
      + gateway_id                 = "igw-0c347532f77a6d3f1"
      + id                         = (known after apply)
      + instance_id                = (known after apply)
      + instance_owner_id          = (known after apply)
      + nat_gateway_id             = (known after apply)
      + network_interface_id       = (known after apply)
      + origin                     = (known after apply)
      + route_table_id             = (known after apply)
      + state                      = (known after apply)
    }

  # module.vpc-sa-east-1.aws_route_table.subnet_route_tables["sa_east_1a_pub_apps_internal"] will be created
  + resource "aws_route_table" "subnet_route_tables" {
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = (known after apply)
      + vpc_id           = "vpc-03290a49cb9a5f386"
    }

  # module.vpc-sa-east-1.aws_route_table.subnet_route_tables["sa_east_1b_pub_apps_internal"] will be created
  + resource "aws_route_table" "subnet_route_tables" {
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = (known after apply)
      + vpc_id           = "vpc-03290a49cb9a5f386"
    }

  # module.vpc-sa-east-1.aws_route_table_association.subnet_route_table_associations["sa_east_1a_pub_apps_cust"] must be replaced
-/+ resource "aws_route_table_association" "subnet_route_table_associations" {
      ~ id             = "rtbassoc-0ff404ba7fb15473f" -> (known after apply)
      ~ route_table_id = "rtb-09007bf313da448a7" -> (known after apply)
      ~ subnet_id      = "subnet-03e76a75c4657f8c3" -> (known after apply) # forces replacement
    }

  # module.vpc-sa-east-1.aws_route_table_association.subnet_route_table_associations["sa_east_1a_pub_apps_internal"] will be created
  + resource "aws_route_table_association" "subnet_route_table_associations" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # module.vpc-sa-east-1.aws_route_table_association.subnet_route_table_associations["sa_east_1b_pub_apps_cust"] must be replaced
-/+ resource "aws_route_table_association" "subnet_route_table_associations" {
      ~ id             = "rtbassoc-07309d0b46df5a8e3" -> (known after apply)
      ~ route_table_id = "rtb-02a9db11897c33a60" -> (known after apply)
      ~ subnet_id      = "subnet-002840ae3c5946fe8" -> (known after apply) # forces replacement
    }

  # module.vpc-sa-east-1.aws_route_table_association.subnet_route_table_associations["sa_east_1b_pub_apps_internal"] will be created
  + resource "aws_route_table_association" "subnet_route_table_associations" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # module.vpc-sa-east-1.aws_subnet.main_subnets["sa_east_1a_pub_apps_internal"] will be created
  + resource "aws_subnet" "main_subnets" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = false
      + availability_zone               = (known after apply)
      + availability_zone_id            = "sae1-az2"
      + cidr_block                      = "10.73.165.0/25"
      + id                              = (known after apply)
      + ipv6_cidr_block                 = (known after apply)
      + ipv6_cidr_block_association_id  = (known after apply)
      + map_public_ip_on_launch         = true
      + owner_id                        = (known after apply)
      + vpc_id                          = "vpc-03290a49cb9a5f386"
    }

  # module.vpc-sa-east-1.aws_subnet.main_subnets["sa_east_1b_pub_apps_internal"] will be created
  + resource "aws_subnet" "main_subnets" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = false
      + availability_zone               = (known after apply)
      + availability_zone_id            = "sae1-az1"
      + cidr_block                      = "10.73.165.128/25"
      + id                              = (known after apply)
      + ipv6_cidr_block                 = (known after apply)
      + ipv6_cidr_block_association_id  = (known after apply)
      + map_public_ip_on_launch         = true
      + owner_id                        = (known after apply)
      + vpc_id                          = "vpc-03290a49cb9a5f386"
    }

Plan: 12 to add, 0 to change, 4 to destroy.

当没有数组索引问题时,我无法弄清楚为什么要重新创建子网和路由表。

`

0 个答案:

没有答案