Terraform:是否可以在输出块中的列表中插入或循环资源



我正试图通过以下操作输出gcp项目信息:

output "projects" {
value = tomap({
for project_name in ["project_1", "project_2", "project_3"] :
project_name => tomap({
id     = google_project."${project_name}".id
number = google_project."${project_name}".number
})
})
description = "Projects"
}

或者像这样:

output "projects" {
value = tomap({
for_each = toset([google_project.project_1,google_project.project_2])
id       = each.key.id
number   = each.key.number
})
description = "Projects"
}

这样使用资源名称有可能吗?我是否必须通过复制代码来指定每个资源?

例如

output "projects" {
value = tomap({
project_1 = tomap({
id     = google_project.project_1.id
number = google_project.project_1.number
})
project_2 = tomap({
id     = google_project.project_2.id
number = google_project.project_2.number
})
project_3 = tomap({
id     = google_project.project_3 .id
number = google_project.pproject_3 .number
})
})
description = "Projects"
}

EDIT:已声明的资源。

main.tf中,项目1到3以相同的方式声明。

resource "google_project" "project_3" {
name                = var.projects.project_3.name
project_id          = var.projects.project_3.id
folder_id           = google_folder.parent.name
billing_account     = data.google_billing_account.acct.id
auto_create_network = false
}

variables.tf

variable "projects" {
type = map(object({
name = string
id   = string
}))
}

variables.tfvars

projects = {
project_1= {
name = "project_1"
id   = "project_1-12345"
}  
project_2= {
name = "project_2"
id   = "project_2-12345"
}
project_3= {
name = "project_2"
id   = "project_2-12345"
}
}

我最初误解了你的问题。我现在明白了,您想要通过变量名引用资源。不,你不能那样做。但是你在这里的设置并没有真正的意义,而且似乎比它需要的更复杂

考虑一下这些选项是否会改善您的设置。

locals {
projects = { # This is equivalent to your input.
project_1 = {
name = "project_1"
id   = "project_1-12345"
}
project_2 = {
name = "project_2"
id   = "project_2-12345"
}
project_3 = {
name = "project_3"
id   = "project_3-12345"
}
}
}
resource "google_project" "this" {
for_each = local.projects
name                = each.key # or each.value.name / don't really need name
project_id          = each.value.id
folder_id           = google_folder.parent.name
billing_account     = data.google_billing_account.acct.id
auto_create_network = false
}
output "projects_from_input" {
description = "You can of course, just use the input."
value       = local.projects
}
output "projects_explicit_values" {
description = "Alternatively, if you need a subset of resource values."
value = { for k, v in google_project.this : k => {
name = v.name
id   = v.project_id
} }
}
output "complete_resources" {
description = "But you can just output the complete resource."
value       = google_project.this
}

在看到创建项目的Terraform资源后,我编辑了最初的答案。需要的是一种通过插值在输出块中获得资源名称的方法。

我认为,如果用一个资源来创建所有项目,而不是每个项目一个资源,那么在输出组中暴露这个资源会更容易。

例如,您可以从json文件配置projects元数据信息,也可以根据需要直接配置本地变量或var

json文件和本地变量的示例

mymodule/resource/projects.json:

{
"projects": {
"project_1": {
"id": "project_1",
"number": "23333311"
},
"project_2": {
"id": "project_2",
"number": "33399999"
}
}
}

然后从locals.tf文件中检索projects作为变量:

mymodule/locals.tf:

locals {
projects = jsondecode(file("${path.module}/resource/projects.json"))["projects"]
}

使用foreach在单个资源中创建项目:

resource "google_project" "projects" {
for_each           = local.projects
name                = each.key
project_id          = each.value["id"]
folder_id           = google_folder.parent.name
billing_account     = data.google_billing_account.acct.id
auto_create_network = false
}

output.tf文件中公开项目resource

output "projects" {
value = google_project.projects
description = "Projects"
}

同样的原理可以用var代替局部变量来实现。

最新更新