如何输出所创建资源的属性?

时间:2019-05-31 16:51:30

标签: google-cloud-platform terraform terraform-provider-gcp

我正在执行GCP模块以创建服务帐户。

main.tf:

resource "google_service_account" "gsvc_account" {
    account_id   = "xxx"
    display_name = ""
    project      = "proj-yyy"
}

output "account_id" {
    value = "${google_service_account.gsvc_account.account_id}"
}

创建帐户后,将创建一个terraform.tfstate文件,其中包含该帐户的所有详细信息。

terraform.tfstate

{
    "version": 4,
    "terraform_version": "0.12.0",
    "serial": 3,
    "lineage": "aaaa-bbbb-cccc",
    "outputs": {
        "xxx": {
            "value": "xxx",
            "type": "string"
        }
    },
    "resources": [
      {
            "module": "module.gsvc_tf",
            "mode": "managed",
            "type": "google_service_account",
            "name": "gsvc_account",
            "provider": "provider.google",
            "instances": [
                {
                    "schema_version": 0,
                    "attributes": {
                        "account_id": "xxx",
                        "display_name": "",
                        "email": "xxx@yyy.com",
                        "id": "projects/proj-yyy/serviceAccounts/xxx@yyy.com",
                        "name": "projects/proj-yyy/serviceAccounts/xxx@yyy.com",
                        "policy_data": null,
                        "project": "proj-xxx",
                        "unique_id": "10891885"
                    }
                }
            ]
        }
    ]
}

如上所述,在模块中,我正在输出account_id输入变量。有没有一种输出attributes的方法。 idname等,以便其他模块可以访问它们? attributes是在资源创建后计算的。

2 个答案:

答案 0 :(得分:1)

来自google_service_account资源的文档:

  

将导出以下计算的属性:

     

email -服务帐户的电子邮件地址。应该从任何将授予服务帐户特权的google_iam_policy数据源中引用该值。

     

name -服务帐户的标准名称。

     

unique_id -服务帐户的唯一ID。

您可以使用这些属性声明输出,就像声明account_id输出一样。例如:

   output "id" {
     value = "${google_service_account.gsvc_account.unique_id}"
   }

   output "email" {
     value = "${google_service_account.gsvc_account.email}"
   }

关于此内容:“以便它们可以被另一个模块访问” ...如果“另一个模块”使用相同的状态文件,则可以使用...来寻址上述输出。

  • ${google_service_account.gsvc_account.account_id}
  • ${google_service_account.gsvc_account.email}

...也就是说,您根本不需要输出。因此,我猜测“其他模块”位于单独的项目/工作空间/存储库中,因此使用了不同的状态文件。如果是这样,那么您将通过remote state访问这些输出。例如,您将声明一个远程状态数据源以指向包含您的输出的任何状态:

resource "terraform_remote_state" "the_other_state" {
  backend = "..."
  config {
    ...
  }
}


然后参考该状态下的输出,如下所示:

  • ${terraform_remote_state.the_other_state.output.account_id}
  • ${terraform_remote_state.the_other_state.output.email}

答案 1 :(得分:1)

如果您的其他模块是针对另一个状态文件运行的(例如Terraform代码位于单独的目录中),那么最好使用google_service_account data source而不是尝试将资源值输出到您的状态文件并使用terraform_remote_state data source来获取它们。

google_service_account数据源的文档很好地example展示了如何使用它:

data "google_service_account" "myaccount" {
  account_id = "myaccount-id"
}

resource "google_service_account_key" "mykey" {
  service_account_id = "${data.google_service_account.myaccount.name}"
}

resource "kubernetes_secret" "google-application-credentials" {
  metadata = {
    name = "google-application-credentials"
  }
  data {
    credentials.json = "${base64decode(google_service_account_key.mykey.private_key)}"
  }
}

这避免了需要配置您的远程状态数据源,并且可以大大简化。实际上,在提供者具有合适的数据源的任何情况下,这都是我建议访问有关现有资源的信息的方式。如果还有其他方法(例如通过云提供商CLI)获取该信息,我什至建议在terraform_remote_state数据源上推荐external data source,因为terraform_remote_state数据源特别笨拙。