我需要创建6个具有低于cidr值的子网,但是在使用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订单
地形模块:
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))}
}
}
1 回答
更新的答案:
感谢评论中的讨论,我修改了我的答案:
您在字典中假设订单 . 这不是预期的行为 . 从您的示例中可以看出,terraform在内部按字母顺序排列键,即您可以将您的变量“思考”为
您遇到了问题,因为您与其他变量
var.availability_zones
不匹配,您假设索引的排序方式与var.private_subnets
相同 .依赖于上述顺序(按字母顺序排列),不是一个好的解决方案,因为它可能会随着任何版本的terraform而改变(不保证键的顺序) .
因此,我建议使用 Map 列表:
我将可用区编码为
var.availability_zones
列表的索引 . 但是,您也可以考虑直接使用可用区 .您的代码的调整很简单:获取(
element(…)
)列表元素以获取 Map ,然后lookup(…)
所需的密钥 .旧答案(此处不适用):
在Terraform创建任何资源之前,它会创建一个图形结构来表示它想要跟踪(创建,更新,删除)的所有对象以及彼此之间的依赖关系 .
在您的示例中,在图中创建了6个不同的
aws_subnet
对象,这些对象彼此不相关(一个子网中没有变量依赖于另一个子网) .当Terraform现在尝试创建属性时,它会在(可能)多个线程中同时执行,并且如果它们不相互依赖,则可能同时创建资源 . 这就是为什么你可能会在多次terraform运行中看到非常不同的执行顺序 .
请注意,这是一项功能,因为如果您要创建的许多资源彼此之间没有依赖关系,则会同时创建所有资源,从而在长时间运行的创建操作中节省大量时间 .
解决您的问题的方法是明确建模您正在考虑的依赖关系 . 为什么要在另一个子网之前创建一个子网?如果是这样,你怎么能让他们依赖(例如通过
depends_on
参数)?回答这些问题应该会让您按照所需的布局为您的代码建模 .