配置多个 NAT 网关

Configure Multiple NAT gateways

我有两个 public 和跨两个可用区的私有子网。我想在两个 public 子网中创建一个 NAT。如何路由我的专用路由 table 以使用两个 NAT? 中的案例三接受了答案。我知道这是可能的,但我不确定如何实施它。目标 cidr_block 应该是 public 子网的 cidr 块吗?我也试过 0.0.0.0/0 并出错了。

resource "aws_route" "r" {
  count                     = length(aws_nat_gateway.this)
  route_table_id            = aws_vpc.vpc.default_route_table_id
  destination_cidr_block    = "aws_subnet.public_subnets.${count.index}.cidr_block"
  nat_gateway_id            = "aws_nat_gateway.this.${count.index}.id"
  depends_on                = [aws_vpc.vpc,aws_subnet.public_subnets,aws_nat_gateway.this]
}

当我尝试时 0.0.0.0/0

error creating Route in Route Table (rtb-059eee10e310ade77) with destination (0.0.0.0/0): RouteAlreadyExists: The route identified by 0.0.0.0/0 already exists.

简答:您需要为每个私有子网设置单独的路由 table。

长答案:我将从定义一个包含每个可用区配置的映射开始。我避免在现代 Terraform 配置中使用 count,因为它很容易导致不兼容(尤其是当您使用它来索引数组时)。

locals {
  subnets = {
    "1a" = { "public_cidr": "172.31.0.0/24", private_cidr: "172.31.1.0/24" }
    "1b" = { "public_cidr": "172.31.2.0/24", private_cidr: "172.31.3.0/24" }
  }
}

现在,您可以使用 for_each 为每个可用区创建 public 和私有子网:

resource "aws_subnet" "public" {
  for_each    = local.subnets
  vpc_id      = aws_vpc.example.id
  cidr_block  = each.value["public_cidr"]
  tags = {
    Name      = "public-${each.key}"
  }
}

resource "aws_subnet" "private" {
  for_each    = local.subnets
  vpc_id      = aws_vpc.example.id
  cidr_block  = each.value["private_cidr"]
  tags = {
    Name      = "private-${each.key}"
  }
}

您可以将 public 个子网与默认路由 table 相关联(该路由必须具有到 Internet 网关的路由)。就个人而言,我更喜欢创建自己的 public 路由 table,而不是更新默认值。

接下来,您需要在每个 public 子网中创建一个 NAT 网关:

resource "aws_nat_gateway" "example" {
  depends_on    = [aws_internet_gateway.example]
  for_each      = local.subnets
  allocation_id = aws_eip.nat_ip[each.key].id
  subnet_id     = aws_subnet.public[each.key].id

  tags = {
    Name        = "nat-${each.key}"
  }
}

现在是重要的部分:每个私有子网都需要自己的路由 table,它引用特定于其可用区的 NAT 网关。

resource "aws_route_table" "private" {
  for_each          = local.subnets
  vpc_id            = aws_vpc.example.id

  route {
    cidr_block      = "0.0.0.0/0"
    nat_gateway_id  = aws_nat_gateway.example[each.key].id
  }

  tags = {
    Name            = "private-${each.key}"
  }
}


resource "aws_route_table_association" "private" {
  for_each       = local.subnets
  subnet_id      = aws_subnet.private[each.key].id
  route_table_id = aws_route_table.private[each.key].id
}