[英]Build dynamic list in Terraform?
我正在嘗試使用計數在 terraform 中動態創建一些 aws 資源,然后構建一個包含所有已創建資源 ID 列表的輸出變量
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 似乎不支持資源級別的通配符。
我懷疑這與我生成輸出列表的方式有關。 有沒有更好的方法來生成該動態列表,使其僅包含創建的資源?
您已經接近了,但您需要使用正確的 Terraform 資源語法RESOURCE-TYPE.RESOURCE-NAME.PROPERTY_NAME
或RESOURCE-TYPE.RESOURCE-NAME.*.PROPERTY_NAME
。 因此,在您的示例中,您將輸出:
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)}"
...
}
2017 年 6 月 6 日更新:感謝 @MartinAtkins 指出從 Terraform 0.9.x 開始,您不再需要將列表輸出包裝在[
和]
。 我已經更新了我的答案。
2017 年 6 月 8 日更新:要從兩個可能為空的列表中僅選擇非空列表,請使用${element(concat(aws_subnet.subnet-1.*.id, aws_subnet.subnet-2.*.id), 0)}
。 concat()
函數將接受一個空列表,並且element(..., 0)
將始終返回第一個元素,在這種情況下是非空列表。
我在嘗試創建動態列表時發現了這個問題,我必須在其中創建一個列表,其中包含列表中可變數量的元素。 我正在創建一個字符串列表。 我通過使用Terraform 的compact
方法解決了這個問題。 基本上,這個列表會過濾掉我在列表中生成的空白元素。
例如,假設我有以下列表,
myList = ["foo", barExists ? "bar" : ""]
這將創建["foo", "bar"]
或["foo", ""]
。 如果您需要["foo", "bar"]
或["foo"]
,那么緊湊函數就是您的朋友。
myList = compact(["foo", barExists ? "bar" : ""])
對於這種情況,上面的行將起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.