簡體   English   中英

Terraform如何輸出使用count創建的對象ID

[英]Terraform how to output object id that were created using count

我有一個創建 2 個子網的 terraform 模塊。 我需要以某種方式獲取每個子網的輸出。 當使用 [count.index] 作為輸出塊的一部分時,我收到一個錯誤,即無法使用 count。

那么解決方案應該是什么,因為我需要將 ec2 關聯到特定的子網。

module "private_subnet" {
     source = "./modules/private_subnet"
     vpc_id = module.vpc.vpcid
     number_of_subnets = 2
     private-subnet-block = var.private-subnet-block
     tag_enviroment= var.tag_enviroment
     project_name = var.project_name }



 resource "aws_subnet" "private_subnet" {
        count = var.number_of_subnets
        cidr_block = var.private-subnet-block[count.index]
        availability_zone = var.availability_zone[count.index]
        vpc_id = var.vpc_id   
        map_public_ip_on_launch = false
        tags = {
        Name = "${var.project_name}-private-subnet-${count.index+1}"
        env = var.tag_enviroment   } }

output "privatesubnetid"{
    value = aws_subnet.private_subnet[count.index].id }

錯誤信息 :

錯誤:在非計數上下文中引用“count”││在 modules/private_subnet/output.tf 第 2 行,輸出“privatesubnetid”中:│2:value = aws_subnet.private_subnet[count.index].id ││“ count”對象只能在“module”、“resource”和“data”塊中使用,並且只有在設置了“count”參數時才能使用

為了在此處繼續,您需要確定在沒有該子網實例的情況下要在該輸出值中放置什么值。


最直接的答案是只返回一個包含所有 id 的列表,如果沒有,則該列表將是一個空列表:

output "private_subnet_ids" {
  value = aws_subnet.private_subnet[*].id
}

這里的[*]splat 運算符,這是一種簡潔的說法,通過獲取[*]左側列表中每個元素的.id屬性來構造列表,即aws_subnet.private_subnet -該資源的所有實例的列表 - 在您的情況下。


另一種選擇是返回從可用區名稱到子網 ID 的映射,以防模塊的調用者出於某種原因需要能夠區分不同的 ID:

output "private_subnet_ids" {
  value = tomap({
    for s in aws_subnet.private_subnet : s.availability_zone => s.id
  })
}

這是一個for表達式,它可能是我們之前看到的 splat 表達式的更通用形式:它將生成一個映射,其中對於aws_subnet.private_subnet s每個元素,它都會生成一個映射元素,其鍵為s.availability_zone ,其值為s.id

與前面的示例類似,如果沒有任何子網,這將生成一個空映射。


另一個可能與您在問題中給出的示例最接近的選項是僅返回第一個子網,或者如果子網為零,則返回null

output "private_subnet_id" {
  value = length(aws_subnet.private_subnet) > 0 ? aws_subnet.private_subnet[0] : null
}

這是一個條件表達式,它根據第三個布爾表達式 ( length(aws_subnet.private_subnet) > 0 ) 的結果選擇兩個結果之一(在本例中為aws_subnet.private_subnet[0]null )。

這似乎不是一個特別有用的選項,因為它無法訪問后續子網。 我包含它只是因為在您的示例中您使用了單數名稱“私有子網 ID”而不是復數名稱“私有子網 ID”,所以我想知道您是否打算以某種方式僅選擇一個子網 ID。


這里也有很多其他的排列。 一般的答案是aws_subnet.private_subnet是一個對象列表,因此您可以編寫在處理對象列表時有效的任何 Terraform 表達式,以對您想要產生的結果有意義的任何方式轉換該列表。 但是,您必須編寫一個對任意數量的子網(包括零子網)有效的表達式,以確保該模塊適用於number_of_subnets的所有值。

您可以使用 Terraform splat 表達式 [1]:

output "privatesubnetid" {
    value = aws_subnet.private_subnet[*].id 
}

[1] https://www.terraform.io/language/expressions/splat

這可以幫助您:

output "database_subnets" {
  description = "IDs of database subnets"
  value       = aws_subnet.database.*.id
}

output "database_subnet_group" {
  description = "ID of database subnet group"
  value       = concat(aws_db_subnet_group.database.*.id, [""])[0]
}

要輸出使用 count 創建的資源 ID,請執行以下操作:

output "private_subnet_ids" {
  value = one(aws_subnet.private_subnet[*].id)
}

上面的表達式首先使用splat operator將對象列表轉換為僅包含id值的列表,根據資源計數,該列表也將包含零個或一個元素。

然后, one函數處理兩種情況:

  • 如果列表只有一個值,它將返回該值。
  • 如果列表沒有值,它將返回 null 表示沒有值。

參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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