2

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

主文件:

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创建资源后计算。

4

2 回答 2

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}
  • ETC

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

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}
  • ETC
于 2019-05-31T17:17:57.227 回答
1

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

数据源的文档显示了如何使用它google_service_account的一个很好的示例:

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),我什至会推荐external数据源而不是数据源,因为数据源特别笨重。terraform_remote_stateterraform_remote_state

于 2019-05-31T17:51:30.130 回答