在 Terraform 中使用 If 条件进行循环

For loop with If condition in Terraform

我正在编写一个模块来创建包含所有相关资源的多个 S3 存储桶。目前,我有点卡在服务器端加密上,因为我需要为尚未创建的密钥参数化 KMS 密钥 ID。

传递给模块的变量是:

S3 存储桶的结构是

type = list(object({
    bucket          = string
    acl             = string
    versioning      = string
    kms_description = string
    logging         = bool
    loggingBucket   = optional(string)
    logPath         = optional(string)
  }))
}

KMS地图的结构类似于

kms_resources = {
    0 = {
        kms_arn         = (known after apply)
        kms_description = "my-kms"
        kms_id          = (known after apply)
    }
}

此变量是创建所有 KMS 的先前模块的输出。输出是这样创建的

output "kms_resources" {
  value = {
    for kms, details in aws_kms_key.my-kms :
    kms => ({
      "kms_description" = details.description
      "kms_id"          = details.key_id
      "kms_arn"         = details.arn
    })
  }
}

如您所见,想法是,在 S3 变量上,用户可以 select 他自己的 KMS 密钥,但我正在努力检索该值。此时资源是这样的

resource "aws_s3_bucket_server_side_encryption_configuration" "my-s3-buckets" {
  count = length(var.s3_buckets)

  bucket = var.s3_buckets[count.index].bucket

  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = [
        for k in var.kms_keys : k.kms_id
        if k.kms_description == var.s3_buckets[count.index].kms_description
      ]
      sse_algorithm     = "aws:kms"
    }
  }
}

我以为它会起作用,但一旦 Terraform 给了我 Inappropriate value for attribute "kms_master_key_id": string required.。我还希望,如果该值不存在,则 kms_master_key_id 默认设置为 aws/s3

问题似乎是您尝试将列表作为 kms_master_key_id 而不是字符串。事实上,您也可以使用 "aws/s3" 实际上使修复变得非常容易:

kms_master_key_id = concat([
    for k in var.kms_keys : k.kms_id
    if k.kms_description == var.s3_buckets[count.index].kms_description
  ], ["aws/s3"])[0]

这样您首先会得到一个包含键的列表/与描述匹配的那个键,然后附加默认的 s3 键。之后,您只需选择列表的第一个元素,即第一个实际键,或者如果 none 匹配,则选择默认键。