配置多个 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
}
我有两个 public 和跨两个可用区的私有子网。我想在两个 public 子网中创建一个 NAT。如何路由我的专用路由 table 以使用两个 NAT? 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
}