2

我在 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标志的情况下创建的,所以我不得不在 TF 0.11.14 中这样处理它,而 tf0.12 自动升级工具在这里没有做太多的更改。

如何在 Terraform 0.12.24 中简化这一点,我尝试将输出修改为简单

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

但问题是,如果在删除过程中对应的kubernetes集群被删除,中途因为terraform出现错误,我将无法使用`terraform destroy'清理其余资源的terraform状态

尝试将其转换countfor_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.

我在上面做错了什么?

4

1 回答 1

3

在您提到的 terraform 版本(0.12.24)中,您应该能够try()在您的outputs.tf

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

这将默认为""if google_service_account_key.service_account_key[0].private_keyis not resolvable for any reason; 当然也可以默认null

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

为了摆脱双方需要具有相同类型的错误,您需要使用[]作为空集而不是0转换为for_each

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

请注意现有的基础设施,因为在转换时需要操作状态文件,countfor_each​​则 terraform 将尝试破坏和创建资源。

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

于 2020-04-25T00:54:33.090 回答