将每个 EIP 附加到 Terraform 中的每个 Nat Gateway
Attach each EIP to each Nat Gatway in Terraform
我正在创建两个 public 子网,每个子网都包含一个 nat gateay。我的代码尝试为每个子网创建这些 nats,然后将 eip 分配给每个子网。然而,由于我的 for each 启动了代码块,看起来分配 ID 变成了 us-east-* 而不是 eip 的 ID。
Variables.tf:
variable "public_subnet_numbers" {
type = map(number)
description = "Map of AZ to a number that should be used for public subnets"
default = {
"us-east-1a" = 1
"us-east-1b" = 2
#"us-east-1c" = 3
}
}
variable "private_subnet_numbers" {
type = map(number)
description = "Map of AZ to a number that should be used for private subnets"
default = {
"us-east-1a" = 4
"us-east-1b" = 5
#"us-east-1c" = 6
}
}
variable "vpc_cidr" {
type = string
description = "The IP range to use for the VPC"
default = "192.168.0.0/16"
}
Main.tf:
resource "aws_eip" "nat" {
count = 2
vpc = true
lifecycle {
# prevent_destroy = true
}
tags = {
Name = "cf-${var.infra_env}-eip"
Project = "cf.io"
Environment = var.infra_env
VPC = aws_vpc.vpc.id
ManagedBy = "terraform"
Role = "private"
}
}
resource "aws_nat_gateway" "ngw" {
for_each = var.private_subnet_numbers
subnet_id = each.value.id #aws_subnet.public[each.key].id
allocation_id = aws_eip.nat[each.key].id
tags = {
Name = "cf-${var.infra_env}-ngw"
Project = "cf.io"
VPC = aws_vpc.vpc.id
Environment = var.infra_env
ManagedBy = "terraform"
Role = "private"
}
}
错误:
Error: Invalid index
│
│ on ../terraform/modules/networking/gateways.tf line 42, in resource "aws_nat_gateway" "ngw":
│ 42: allocation_id = aws_eip.nat[each.key].id
│ ├────────────────
│ │ aws_eip.nat is tuple with 2 elements
│ │ each.key is "us-east-1a"
│
│ The given key does not identify an element in this collection value: a number is required.
╵
╷
│ Error: Invalid index
│
│ on ../terraform/modules/networking/gateways.tf line 42, in resource "aws_nat_gateway" "ngw":
│ 42: allocation_id = aws_eip.nat[each.key].id
│ ├────────────────
│ │ aws_eip.nat is tuple with 2 elements
│ │ each.key is "us-east-1b"
│
│ The given key does not identify an element in this collection value: a number is required.
您正在混合 count
和 for_each
。解决这个问题的最简单方法是在您的 EIP 创建中也使用 for_each
,这是有道理的,因为您正在为每个 NAT 创建一个 EIP。如果您稍后决定添加另一个子网,这也会使您的代码更好地工作,您不需要进入并将 count
从 2
更改为 3
。
否则,您需要使用index function将each
值转换为索引号。
正如 Mark B 提到的,不建议混合使用 count
和 for_each
。在您当前的设置中,仅使用 for_each
是基于 private_subnet_numbers
变量的方法。
在您的 aws_eip.nat
资源中将 count
更改为 for_each
resource "aws_eip" "nat" {
for_each = var.private_subnet_numbers
vpc = true
}
接下来在您的资源 aws_nat_gateway.ngw
中,您应该使用 each
引用 subnet ids
resource "aws_nat_gateway" "ngw" {
for_each = var.private_subnet_numbers
subnet_id = aws_subnet.public[each.key].id
....
}
为了清晰起见,代码作为一个整体
resource "aws_vpc" "vpc" {
... vpc configurations ...
}
resource "aws_subnet" "public" {
for_each = var.private_subnet_numbers
vpc_id = aws_vpc.vpc.id
... subnet configurations ...
}
resource "aws_eip" "nat" {
for_each = var.private_subnet_numbers
vpc = true
lifecycle {
# prevent_destroy = true
}
tags = {
Name = "cf-${var.infra_env}-eip"
Project = "cf.io"
Environment = var.infra_env
VPC = aws_vpc.vpc.id
ManagedBy = "terraform"
Role = "private"
}
}
resource "aws_nat_gateway" "ngw" {
for_each = var.private_subnet_numbers
subnet_id = aws_subnet.public[each.key].id
allocation_id = aws_eip.nat[each.key].id
tags = {
Name = "cf-${var.infra_env}-ngw"
Project = "cf.io"
VPC = aws_vpc.vpc.id
Environment = var.infra_env
ManagedBy = "terraform"
Role = "private"
}
}
我正在创建两个 public 子网,每个子网都包含一个 nat gateay。我的代码尝试为每个子网创建这些 nats,然后将 eip 分配给每个子网。然而,由于我的 for each 启动了代码块,看起来分配 ID 变成了 us-east-* 而不是 eip 的 ID。
Variables.tf:
variable "public_subnet_numbers" {
type = map(number)
description = "Map of AZ to a number that should be used for public subnets"
default = {
"us-east-1a" = 1
"us-east-1b" = 2
#"us-east-1c" = 3
}
}
variable "private_subnet_numbers" {
type = map(number)
description = "Map of AZ to a number that should be used for private subnets"
default = {
"us-east-1a" = 4
"us-east-1b" = 5
#"us-east-1c" = 6
}
}
variable "vpc_cidr" {
type = string
description = "The IP range to use for the VPC"
default = "192.168.0.0/16"
}
Main.tf:
resource "aws_eip" "nat" {
count = 2
vpc = true
lifecycle {
# prevent_destroy = true
}
tags = {
Name = "cf-${var.infra_env}-eip"
Project = "cf.io"
Environment = var.infra_env
VPC = aws_vpc.vpc.id
ManagedBy = "terraform"
Role = "private"
}
}
resource "aws_nat_gateway" "ngw" {
for_each = var.private_subnet_numbers
subnet_id = each.value.id #aws_subnet.public[each.key].id
allocation_id = aws_eip.nat[each.key].id
tags = {
Name = "cf-${var.infra_env}-ngw"
Project = "cf.io"
VPC = aws_vpc.vpc.id
Environment = var.infra_env
ManagedBy = "terraform"
Role = "private"
}
}
错误:
Error: Invalid index
│
│ on ../terraform/modules/networking/gateways.tf line 42, in resource "aws_nat_gateway" "ngw":
│ 42: allocation_id = aws_eip.nat[each.key].id
│ ├────────────────
│ │ aws_eip.nat is tuple with 2 elements
│ │ each.key is "us-east-1a"
│
│ The given key does not identify an element in this collection value: a number is required.
╵
╷
│ Error: Invalid index
│
│ on ../terraform/modules/networking/gateways.tf line 42, in resource "aws_nat_gateway" "ngw":
│ 42: allocation_id = aws_eip.nat[each.key].id
│ ├────────────────
│ │ aws_eip.nat is tuple with 2 elements
│ │ each.key is "us-east-1b"
│
│ The given key does not identify an element in this collection value: a number is required.
您正在混合 count
和 for_each
。解决这个问题的最简单方法是在您的 EIP 创建中也使用 for_each
,这是有道理的,因为您正在为每个 NAT 创建一个 EIP。如果您稍后决定添加另一个子网,这也会使您的代码更好地工作,您不需要进入并将 count
从 2
更改为 3
。
否则,您需要使用index function将each
值转换为索引号。
正如 Mark B 提到的,不建议混合使用 count
和 for_each
。在您当前的设置中,仅使用 for_each
是基于 private_subnet_numbers
变量的方法。
在您的 aws_eip.nat
资源中将 count
更改为 for_each
resource "aws_eip" "nat" {
for_each = var.private_subnet_numbers
vpc = true
}
接下来在您的资源 aws_nat_gateway.ngw
中,您应该使用 each
subnet ids
resource "aws_nat_gateway" "ngw" {
for_each = var.private_subnet_numbers
subnet_id = aws_subnet.public[each.key].id
....
}
为了清晰起见,代码作为一个整体
resource "aws_vpc" "vpc" {
... vpc configurations ...
}
resource "aws_subnet" "public" {
for_each = var.private_subnet_numbers
vpc_id = aws_vpc.vpc.id
... subnet configurations ...
}
resource "aws_eip" "nat" {
for_each = var.private_subnet_numbers
vpc = true
lifecycle {
# prevent_destroy = true
}
tags = {
Name = "cf-${var.infra_env}-eip"
Project = "cf.io"
Environment = var.infra_env
VPC = aws_vpc.vpc.id
ManagedBy = "terraform"
Role = "private"
}
}
resource "aws_nat_gateway" "ngw" {
for_each = var.private_subnet_numbers
subnet_id = aws_subnet.public[each.key].id
allocation_id = aws_eip.nat[each.key].id
tags = {
Name = "cf-${var.infra_env}-ngw"
Project = "cf.io"
VPC = aws_vpc.vpc.id
Environment = var.infra_env
ManagedBy = "terraform"
Role = "private"
}
}