我正在处理一些 Terraform 代码,旨在部署 VPC、创建公共和私有子网,然后创建负载均衡器、ECS 容器等。我的 VPC 创建工作正常,但在创建应用程序负载时遇到问题平衡器。
我的代码分为几个不同的模块。 VPC 模块创建公共子网如下:
resource "aws_subnet" "public" {
count = length(var.public_subnet_cidr_blocks)
vpc_id = aws_vpc.primary_vpc.id
availability_zone = data.aws_availability_zones.available.names[count.index % length(data.aws_availability_zones.available.names)]
cidr_block = var.public_subnet_cidr_blocks[count.index]
tags = {
Name = "Public Subnet"
}
}
我为公共子网定义了 2 个 CIDR 块,在我的输出中我看到它在 2 个不同的可用区中创建了 2 个子网。
我的负载均衡器模块作为
aws_subnets
数据源来提取公共子网的详细信息:
data "aws_subnets" "public" {
filter {
name = "vpc-id"
values = [var.vpc_id]
}
tags = {
Name = "Public Subnet"
}
}
我的问题是当我尝试使用以下代码创建
aws_lb
资源时:
resource "aws_lb" "keycloak" {
name = "my-lb"
load_balancer_type = "application"
internal = false
subnets = data.aws_subnets.public.ids
security_groups = [aws_security_group.lb_sg.id]
}
plan
操作正常,但是当我运行 apply
时,我收到以下错误消息:
│ Error: creating ELBv2 application Load Balancer (my-lb): ValidationError: At least two subnets in two different Availability Zones must be specified
输出显示我的公共子网位于 2 个不同的可用区。如果我输出
aws_subnets.public
数据源,我可以看到我期望的子网 ID。事实上,如果我在代码中硬编码子网 ID,它就可以正常工作(示例):
resource "aws_lb" "keycloak" {
name = "my-lb"
load_balancer_type = "application"
internal = false
subnets = [
"subnet-XXXXXXXXXXX",
"subnet-YYYYYYYYYYY",
]
security_groups = [aws_security_group.lb_sg.id]
}
为什么使用
aws_subnets
数据源进行子网查找在这里不起作用?我是不是错过了什么?
这不是一个完美的答案,因为我确信您正在尝试使用计数索引在可用的“可用区”之间进行分配。
Andres Bores 关于依赖性的回应是正确的。在我们获取子网数据之前,需要先创建公共子网。
data "aws_subnets" "public"
返回的数据是一个列表。 Terraform 资源 alb 仅使用数据返回的列表中的第一个条目。
可能有一种使用 count.index 的方法,这会比下面的代码更好。以下代码确实有效,因为它将列表中的第一个和第二个声明为要使用的子网。
data "aws_subnets" "foobar" {
tags = {
Name = "public subnet"
}
depends_on = [aws_subnet.public-subnets]
}
resource "aws_lb" "alb" {
name = "my-alb"
internal = false
load_balancer_type = "application"
subnets = [data.aws_subnets.foobar.ids[0],data.aws_subnets.foobar.ids[1]]
security_groups = ["${aws_security_group.alb-sg.id}"]
}
output "aws_alb" {
value = aws_lb.alb.id
}
PS。我在发布之前测试了以上内容