Home > Back-end >  For loop with If condition in Terraform
For loop with If condition in Terraform

Time:03-19

I'm writing a module to create multiple S3 Buckets with all the related resources. Currently, I'm a little bit stuck on the server side encryption as I need to parametrize the KMS key id for a key that is not still created.

The variables passed to the module are:

  • A list of S3 buckets
  • A map with the KMS created

The structure of the S3 buckets is

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

The structure of the KMS map is similar to

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

This variable is an output from a previous module that creates all the KMS. The output is created this way

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

As you can see the idea is that, on the S3 variable, the user can select his own KMS key, but I'm struggling to retrieve the value. At this moment, resource looks like this

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

I thought it was gonna work but once terraform is giving me Inappropriate value for attribute "kms_master_key_id": string required.. I would also like that if the value does not exist the kms_master_key_id is set by default to aws/s3

CodePudding user response:

The problem seems to be that you try to give a list as kms_master_key_id instead of just a string. The fact that you alternatively want to use "aws/s3" actually makes the fix quite easy:

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]

That way you first get a list with keys / that key that matches the description and then append the default s3 key. Afterwards you simply pick the first element of the list, either the first actual key or if none matched you pick the default key.

  • Related