我正在尝试使用count在terraform中动态地创建一些aws资源,然后构建一个包含所有创建的资源in的列表的输出变量。
resource "aws_subnet" "subnet-1" {
// If subnet_id value is supplied then we set count to 1 to create otherwise skip
count = "${replace(replace(var.primary_subnet_cidr, "/^.+/", "1"), "/^$/", "0")}"
tags = {
Name = "subnet-1"
}
cidr_block = "${var.primary_subnet_cidr}"
vpc_id = "${var.vpc_id}"
availability_zone = "${var.aws_region}a"
}
resource "aws_subnet" "subnet-2" {
// If subnet_id value is supplied then we set count to 1 to create otherwise skip
count = "${replace(replace(var.secondary_subnet_cidr, "/^.+/", "1"),"/^$/", "0")}"
tags = {
Name = "subnet-2"
}
cidr_block = "${var.secondary_subnet_cidr}"
vpc_id = "${var.vpc_id}"
availability_zone = "${var.aws_region}b"
}
output "ids" {
value = ["${aws_subnet.subnet-1.id}","${aws_subnet.subnet-2.id}"]
}其想法是只通过提供它的变量(primary_subnet_cidr或secondary_subnet_cidr)来创建您想要的子网。
动态创建它们很好,但是我的问题是动态列表。
当试图在类似于接收列表的aws_db_subnet_group.subnet_ids中使用此列表时,只有在创建了两个子网时,它才能工作,否则会引发以下错误
InvalidSubnet: Subnet IDs are required.
我也试过这个
output "ids" {
value = ["${aws_subnet.*.id}"]
}但在资源级别上,terraform似乎不支持通配符。
我怀疑这与我生成输出列表的方式有关。是否有更好的方法来生成动态列表,使其只包含所创建的资源?
发布于 2017-06-06 06:14:47
您已经接近了,但是您需要使用正确的RESOURCE-TYPE.RESOURCE-NAME.PROPERTY_NAME或RESOURCE-TYPE.RESOURCE-NAME.*.PROPERTY_NAME的Terraform资源语法。因此,在您的示例中,您将输出:
output "ids" {
value = "${aws_subnet.subnet-1.*.id}"
}当然,您可能希望使用concat插值函数连接这两个列表
output "ids" {
value = "${concat(aws_subnet.subnet-1.*.id, aws_subnet.subnet-2.*.id)}"
}但是,如果在任一资源上将count属性设置为0,则可能会引发错误。为了弥补这一点,您可以使用一些其他插值函数的组合(例如coalescelist()),但我恐怕记不起确切的组合了。
最后,对于您的count属性,这些var定义读起来有点棘手。以下是一些值得尝试的其他想法:
// Count = 1 if var.secondary_subnet_cidr is non-empty
resource "aws_subnet" "subnet-1" {
count = "${signum(length(var.secondary_subnet_cidr))}"
...
}
// Define a separate var altogether. Ideally, you could infer this, but sometimes it's the best you can do.
resource "aws_subnet" "subnet-1" {
count = "${var.should_create_secondary_subnet)}"
...
}UpdateJun6,2017:感谢@MartinAtkins指出,截至Terraform0.9.x,您不再需要在[和]中包装列表输出。我更新了我的答案。
更新2017年6月8日:在两个可能为空的列表中只选择非空列表,使用${element(concat(aws_subnet.subnet-1.*.id, aws_subnet.subnet-2.*.id), 0)}。concat()函数将接受一个空列表,element(..., 0)将始终返回第一个元素,在本例中是非空列表。
发布于 2021-07-23 18:27:57
我在尝试创建一个动态列表时发现了这个问题,在这个列表中,我必须创建一个列表,列表中包含可变数量的元素。我在创建一个字符串列表。我用方法解决了这个问题。基本上,这个列表将过滤掉我在列表中生成的空白元素。
例如,假设我有以下列表,
myList = ["foo", barExists ? "bar" : ""]这将创建["foo", "bar"]或["foo", ""]。如果您需要["foo", "bar"]或["foo"],那么紧凑型函数就是您的朋友。
myList = compact(["foo", barExists ? "bar" : ""])在这种情况下,上述项目将有效。
https://stackoverflow.com/questions/44373102
复制相似问题