使用tf 0.12+从output.tf继承具有条件资源的值



我在GCP中有一个服务帐户模块,用于填充kubernetes机密

这是我的模块

resource "google_service_account" "service_account" {
count        = var.enabled ? 1 : 0
account_id   = var.account_id
display_name = var.display_name
}
resource "google_project_iam_member" "service_account_roles" {
count  = var.enabled ? length(var.roles) : 0
role   = "roles/${element(var.roles, count.index)}"
member = "serviceAccount:${google_service_account.service_account[0].email}"
}
resource "google_service_account_key" "service_account_key" {
count              = var.enabled ? 1 : 0
service_account_id = google_service_account.service_account[0].name
}

"output.tf"包含以下

output "private_decoded_key" {
value = base64decode(
element(
concat(
google_service_account_key.service_account_key.*.private_key,
[""],
),
0,
),
)
description = "The base 64 decoded version of the credentials"
}

由于有一个条件,即这些资源都不能在没有enabled标志的情况下创建,因此我不得不在tf0.11.14中以这种方式处理它,而tf0.12自动升级工具在这里没有做太多更改。

我如何在Terraform 0.12.24中简化它,我试着将输出修改为简单的

value = base64decode(google_service_account_key.service_account_key[0].private_key)

但问题是,如果相应的kubernetes集群在删除过程中被删除,并且由于地形而中途出现错误,我将无法使用`地形摧毁

如下所示,尝试将count转换为for_each时出现以下错误

resource "google_service_account" "service_account" {
# count        = var.enabled ? 1 : 0
for_each     = var.enabled ? 1 : 0
account_id   = var.account_id
display_name = var.display_name
}
resource "google_project_iam_member" "service_account_roles" {
# count  = var.enabled ? length(var.roles) : 0
for_each = var.enabled ? toset(var.roles) : 0
# role   = "roles/${element(var.roles, count.index)}"
role     = "roles/${each.value}" 
member   = "serviceAccount:${google_service_account.service_account[0].email}"
}
for_each = var.enabled ? toset(var.roles) : 0
The true and false result expressions must have consistent types. The given
expressions are set of dynamic and number, respectively.

我上面做错了什么?

在您提到的地形版本(0.12.24(中,您应该能够在outputs.tf:中使用try()

value = try(base64decode(google_service_account_key.service_account_key[0].private_key), "")

如果google_service_account_key.service_account_key[0].private_key由于任何原因无法解析,则默认为"";当然,您也可以默认为null

编辑/更新:回答问题的第二部分(已编辑(:

为了消除双方需要具有相同类型的错误,在转换为for_each:时,需要使用[]而不是0作为空集

for_each = var.enabled ? toset(var.roles) : []

请注意现有的基础设施,因为从count转换到for_each时需要操作状态文件,否则terraform将试图破坏和创建资源。

(我将在我目前正在写的一系列关于如何编写地形模块的故事的第3部分中更详细地介绍这一点。你可以在medium上找到第1部分,第2部分将于下周发布。(

最新更新