2017-06-05 56 views
0

我試圖動態創建terraform一些AWS資源利用計數,然後建立一個包含所有創建的資源ID列表輸出變量在Terraform中構建動態列表?

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似乎不支持資源級別的通配符。

我懷疑這與我生成輸出列表的方式有關。是否有更好的方式來生成動態列表,以便只包含創建的資源?

回答

2

您已經關閉,但需要使用正確的Terraform資源語法RESOURCE-TYPE.RESOURCE-NAME.PROPERTY_NAMERESOURCE-TYPE.RESOURCE-NAME.*.PROPERTY_NAME。所以,在你的榜樣,您將輸出:

output "ids" { 
    value = "${aws_subnet.subnet-1.*.id}" 
} 

當然,你可能想使用concat interpolation function加入兩個列表:

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)將始終返回第一個元素,在這種情況下,它是非空列表。

+0

從Terraform 0.9.6開始,包含「splat變量」的括號不再需要也不建議使用,因爲它們將在未來版本中被淘汰。儘管如此,這裏仍然有效! :D –

+0

'aws_subnet.subnet-1。*。id' does not exist afaik。正確的語法應該是'aws_subnet.subnet-1.id',因此我試圖從所有執行'aws_subnet。*。id'的資源中獲取所有id屬性的列表,但這不起作用。感謝關於coalescelist和語法的提示。這正是我正在尋找的插值函數組合。我想我得到的錯誤可能是由於其中一個資源的count = 0時列表中爲空的值。也許'compact'可能解決這個問題。我會在稍後嘗試。 – ByteFlinger

+0

嘗試從不存在的列表讀取,因爲'count = 0'是常見的情況。如果我記得我們如何入侵,我會更新我的迴應! –