首页 > 解决方案 > 如何形成 key=value terraform 输出

问题描述

我正在尝试构建一个简单的模块,该模块将 gcp 项目作为输入并输出 default_service_account

如何从 root 的 main.tf 调用它

module "default_service_accounts" {
  source = "./default_service_accounts"
  for_each = module.projects.enterprise_projects
  project_name = each.key
  project_id = each.value
}

default_service_accounts input.tf:

variable "project_name" {
  description   = "project_name"
  type = string
}

variable "project_id" {
  description = "project_id"
  type = string
}

default_service_accounts main.tf

data "google_compute_default_service_account" "default" {
  project = var.project_id
}

default_service_accounts 输出.tf

output "output" {
    value = {
        (var.project_name) = data.google_compute_default_service_account.default.email
    }
}

然后我想将它传递给另一个模块:

module "compute" {
  source        = "./compute"
  projects      = module.projects.enterprise_projects
  default_service_accounts = module.default_service_accounts.output
}

并在该模块中像这样访问它:

var.default_service_accounts["myproject"]

标签: terraform

解决方案


我认为您对输出的理解有些混乱。您不需要从 DSA 模块中将项目名称的映射返回到 DSA - 调用模块已经为您制作了该映射。或者至少是从项目名称到完整 DSA 模块实例的映射,您可以从中访问电子邮件输出。

您应该能够通过更改default_service_accounts/outputs.tf

output "account_email" {
    value = data.google_compute_default_service_account.default.email
}

然后你就可以使用了module.default_service_accounts["myproject"].account_email;即,您可以将模块实例的集合传递给compute模块

module "compute" {
  source        = "./compute"
  projects      = module.projects.enterprise_projects
  default_service_accounts = module.default_service_accounts # <== note the removal of the output from this line
}

并且您将访问这些值作为var.default_service_accounts["myproject"].account_email.

模块中的变量compute将类似于

variable "projects" {
  description = "..."
  type = map(string)
}
variable "default_service_accounts" {
  description = "..."
  type = map(object(
    account_email = string
  ))
}

当你指定一个map类型变量时,你只是指定了映射的的类型,键总是一个字符串。


如果您真的只想将映射从项目名称传递到默认服务帐户电子邮件,您可以使用

locals {
  service_accounts = {
    for project_name, dsa in module.default_service_accounts: 
      project_name => dsa.account_email
  }
}

然后像这样使用

module "compute" {
  source        = "./compute"
  projects      = module.projects.enterprise_projects
  default_service_accounts = local.service_accounts  # <== here's the use of that new local variable
}

并且在compute模块中,您可以完全按照您在问题末尾显示的那样访问值 ( var.default_service_accounts["myproject"])。

在这种情况下,compute模块的变量看起来像

variable "projects" {
  description = "..."
  type = map(string)
}
variable "default_service_accounts" {
  description = "..."
  type = map(string)
}

因为该default_service_accounts变量现在直接从项目名称映射到服务帐户电子邮件地址(字符串)。


推荐阅读