【问题标题】:How to output attributes of resources created?如何输出创建的资源的属性?
【发布时间】:2019-10-17 08:01:22
【问题描述】:

我正在执行 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 在资源创建后计算。

【问题讨论】:

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


    【解决方案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}

    【讨论】:

      【解决方案2】:

      如果您的其他模块针对不同的状态文件运行(例如,您的 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)}"
        }
      }
      

      这避免了需要配置远程状态数据源,并且可以显着简化。事实上,在提供者拥有合适的数据源的任何情况下,我都建议通过这种方式访问​​有关现有资源的信息。我什至会推荐external data source 而不是terraform_remote_state 数据源,因为terraform_remote_state 数据源特别笨重,如果有另一种获取该信息的方法(例如通过云提供商CLI)。

      【讨论】:

        猜你喜欢
        • 2020-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-09
        • 1970-01-01
        • 1970-01-01
        • 2021-08-19
        相关资源
        最近更新 更多