【问题标题】:Terraform - Multi Loops or MapsTerraform - 多循环或地图
【发布时间】:2021-10-15 00:14:50
【问题描述】:

我正在使用 terraform 在 AWS 中创建几个公共子网、私有子网、igw、nat、route_tables 和 route_table 条目。以下是我正在创建的资源数量。

terraform.tfvars

vpc_cidr = "10.0.0.0/16"
public_subnet_count = 6
public_subnets_cidr  = ["10.0.1.0/24","10.0.2.0/24","10.0.3.0/24","10.0.4.0/24","10.0.5.0/24", "10.0.6.0/24"]
availability_zones = ["us-east-2a", "us-east-2b","us-east-2c","us-east-2d"]

resources.tf

resource "aws_vpc" "vpc" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true
  tags = {
    Name        = "${var.environment}-vpc"
    Environment = var.environment
  }
}

resource "aws_subnet" "public_subnet" {
  vpc_id                  = "${aws_vpc.vpc.id}"
  count                   = var.public_subnet_count
  cidr_block              = "${element(var.public_subnets_cidr, count.index)}"
  availability_zone       = length(var.availability_zones) > 1 ? var.availability_zones[count.index % length(var.availability_zones)] : var.availability_zones[0]
  map_public_ip_on_launch = false
  tags = {
    Name        = "${var.environment}-${element(var.availability_zones, count.index)}-public-subnet"
    Environment = "${var.environment}"
  }
}

resource "aws_internet_gateway" "ig" {
  count = 1
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name        = "${var.environment}-igw"
    Environment = "${var.environment}"
  }
}

resource "aws_route_table" "public" {
  count = length(var.availability_zones)
  vpc_id = aws_vpc.vpc.id
  tags = {
    Name        = "${var.environment}-public-route-table"
    Environment = "${var.environment}"
  }
}

 resource "aws_route" "public_internet_gateway" {
  count = length(aws_route_table.public.*.id)
  route_table_id         = element(aws_route_table.public.*.id, count.index)
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.ig[0].id
}

resource "aws_route_table_association" "public" {
  count = length(var.availability_zones)
  subnet_id      = element(aws_subnet.public_subnet.*.id, count.index)
  route_table_id = element(aws_route_table.public.*.id, count.index)
}

在 aws_route_table_association.public 部分中查询。

如何将特定 az 的私有子网附加到路由表 ID。例如,如果我在 tfvars 中使用 6 个私有子网,它会在一个 az 中创建至少 2 个私有子网(例如:us-east-2a)。我如何循环并将来自 us-east-2a 的 2 个子网附加到为 us-east-2a 创建的一个路由表。一个 az 中多个子网之间的映射到该 az 中的路由表。

这是为了将每个 az nat 网关附加到该 az 子网以进行路由。

【问题讨论】:

    标签: amazon-web-services terraform terraform-provider-aws terraform0.12+


    【解决方案1】:

    您不需要为每个可用区创建路由表,路由表链接到子网。因此,您可以只创建一个路由表,然后将所有公共子网链接到它:

    resource "aws_route_table" "public" {
      vpc_id = aws_vpc.vpc.id
      route {
        cidr_block = "0.0.0.0/0"
        gateway_id = aws_internet_gateway.ig.id
      }
    }
    
    resource "aws_route_table_association" "public" {
      count = var.public_subnet_count
      subnet_id      = aws_subnet.public_subnet[count.index].id
      route_table_id = aws_route_table.public.id
    }
    

    我已经在route_table 中包含了单个路由以减少代码量,因此如果您使用它,可以删除aws_route 资源。

    [编辑] 抱歉,我刚刚注意到您提到了私有子网,但是附加路由表遵循相同的原则,并且您也不需要每个 AZ 的 NAT 网关(这很昂贵!)因此您可以通过单个 NAT 网关路由所有私有子网路由表。

    如果你真的想要 4 个 NAT 网关,那么你可以这样做:

    resource "aws_route_table" "private" {
      count  = length(var.availability_zones)
      vpc_id = aws_vpc.vpc.id
      route {
        cidr_block     = "0.0.0.0/0"
        nat_gateway_id = aws_nat_gateway.nat[count.index].id
      }
    }
    
    resource "aws_route_table_association" "private" {
      count = var.private_subnet_count
    
      subnet_id = aws_subnet.private[count.index].id
      route_table_id = aws_route_table.private[
        count.index % length(var.availability_zones)
      ].id
    }
    

    由于您已经使用模数 (%) 运算符来分配子网,我认为这样做会得到相同的结果。

    【讨论】:

    • 单一 NAT 不是最佳解决方案。如果一个 az 关闭并且所有实例都附加到同一个 nat,则其他 az 中的实例也会受到影响。 AWS 建议每个 az 使用一个 nat(至少 2 个 nat)。
    • 公平地说,我已经更新了我的答案以包含一个选项,以防需要多个 NAT。
    猜你喜欢
    • 2020-10-22
    • 2021-10-03
    • 2021-08-03
    • 1970-01-01
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    相关资源
    最近更新 更多