Google cloud platform 使用tf 0.12+;

Google cloud platform 使用tf 0.12+;,google-cloud-platform,terraform,terraform-provider-gcp,terraform0.12+,terraform-provider-kubernetes,Google Cloud Platform,Terraform,Terraform Provider Gcp,Terraform0.12+,Terraform Provider Kubernetes,我在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_acco

我在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"
}
由于有一个条件,即这些资源都是在没有启用
标志的情况下创建的,因此我不得不以这种方式在tf0.11.14中处理它,而tf0.12自动升级工具在这里没有做太多更改

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

value = base64decode(google_service_account_key.service_account_key[0].private_key)
但问题是,如果相应的kubernetes集群在删除过程中被删除,并且中途由于地形而出现错误,我将无法使用 `地形破坏'

尝试将每个
计数
转换为
,如下所示,出现以下错误

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}"
}

上面我做错了什么?

在您提到的地形版本(0.12.24)中,您应该能够在
输出中使用。tf

value = try(base64decode(google_service_account_key.service_account_key[0].private_key), "")
如果
google\u service\u account\u key.service\u account\u key[0],则默认为
。私钥因任何原因都无法解析;当然,您也可以将默认值设置为
null

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

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

for_each = var.enabled ? toset(var.roles) : []
请注意现有基础设施,因为您需要在从
count
转换为
时操作状态文件,否则terraform将尝试销毁和创建资源


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

我不确定是否完全理解您的问题。但根据我的理解,你是在谈论输出中的条件。如果是,则可以使用输出值的
dependens\u
。您知道如何解决上述每个问题的计数吗?@ShoaibAhmedNasir更新了答案,解释了如何解决您的问题。每个for\u也可以用于条件资源吗?对于_each=var.enabled?1:0,给了我一个错误“给定的”for_each参数值不合适:“for_each”参数必须是一个映射或字符串集,并且您提供了一个类型为number的值。”@ShoaibAhmedNasir您今天在terraform中基本上找到了三种类型的资源(如我的链接文章所述):单一资源,带有
计数的批量资源,以及每个
的带有
的批量资源。。仅仅为了对每个
使用
,而将所有的
计数
替换为
。。因此,了解未来如何扩展/使用资源是有意义的。。对于单个资源,我将使用
count
来启用/禁用它们。如果您知道这将很快用作批量资源,请尝试将其设为每个_的
,除非键取决于计算值。
for_each = var.enabled ? toset(var.roles) : []