簡體   English   中英

在 Terraform 中構建動態列表?

[英]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_NAMERESOURCE-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM