我需要创建低于cidr值的6个子网,但是在使用terraform创建子网时,其顺序已更改。
private_subnets = {
"10.1.80.0/27" = "x"
"10.1.80.32/27" = "x"
"10.1.80.64/28" = "y"
"10.1.80.80/28" = "y"
"10.1.80.96/27" = "z"
"10.1.80.128/27" = "z"
}
Terraform创建时具有10.1.80.0/27,10.1.80.128/27,10.1.80.32/27,10.1.80.64/28,10.1.80.80/28,10.1.80.96/27顺序
terraform模块:
resource "aws_subnet" "private" {
vpc_id = "${var.vpc_id}"
cidr_block = "${element(keys(var.private_subnets), count.index)}"
availability_zone = "${element(var.availability_zones, count.index)}"
count = "${length(var.private_subnets)}"
tags {
Name = "${lookup(var.private_subnets, element(keys(var.private_subnets), count.index))}
}
}
答案 0 :(得分:0)
由于评论中的讨论,我修改了答案:
您正在假设字典中的顺序。这不是预期的行为。从您的示例中可以看到,terraform在内部按字母顺序对键进行排序,即,您可以将变量“认为”为
private_subnets = {
"10.1.80.0/27" = "x"
"10.1.80.128/27" = "z"
"10.1.80.32/27" = "x"
"10.1.80.64/28" = "y"
"10.1.80.80/28" = "y"
"10.1.80.96/27" = "z"
}
您遇到了问题,因为您与其他变量var.availability_zones
不匹配,在该变量中您假定索引的排序方式与var.private_subnets
相同。
依靠上述顺序(按字母顺序)并不是一个好的解决方案,因为它可能随任何版本的terraform改变(不保证键的顺序)。
因此,我建议使用地图列表:
private_subnets = [
{
"cidr" = "10.1.80.0/27"
"name" = "x"
"availability_zone" = 1
},
{
"cidr" = "10.1.80.32/27"
"name" = "x"
"availability_zone" = 2
},
…
]
我将可用区域编码为您的var.availability_zones
列表的索引。但是,您也可以考虑直接使用可用性区域。
代码的修改非常简单:获取(element(…)
)列表元素以获取地图,然后lookup(…)
获得所需的键。
在Terraform创建任何资源之前,它会创建一个图结构来表示要跟踪(创建,更新,删除)的所有对象以及彼此之间的依赖关系。
在您的示例中,图中创建了6个不同的aws_subnet
对象,它们彼此不依赖(一个子网中没有变量依赖于另一个子网)。
当Terraform现在尝试创建属性时,它将在多个线程中(潜在地)同时进行创建,并且如果它们彼此不依赖,则可能同时创建资源。 这就是为什么您可能会在terraform的多次运行中看到不同的执行顺序的原因。
请注意,这是一项功能,因为如果要创建的许多资源彼此不依赖,则可以同时创建所有资源,从而节省了长时间运行的创建操作的时间。
您的问题的解决方案是显式地建模您正在考虑的依赖项。为什么要先创建一个子网?如果是这样,如何使它们成为依赖项(例如,通过depends_on
参数)?
回答此问题应使您朝正确的方向,以根据所需的布局对代码进行建模。