Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional Dynamic block in Terraform

Tags:

terraform

I have a dynamic block like so:

 dynamic "origin" {
        for_each = var.ordered_cache_behaviors

        content {
            domain_name = "${origin.value.s3_target}.s3.amazonaws.com"
            origin_id   = "S3-${origin.value.s3_target}"    
        }
    }

My list is defined like so:

  "ordered_cache_behaviors": [
    {
      "path_pattern": "/my-app*",
      "s3_target": "${local.default_s3_target}",
      "ingress": "external"
    }
  ]

In my dynamic block I want to render the block ONLY if this condition is true origin.value.s3_target !== var.default_s3_target

how and where do I add the conditional to my dynamic block? Note, the rendering of the block is controlled by the value of the currently iterated object not on some variable that excludes the for loop altogether.

I want to iterate over everything and conditionally exclude some items. So writing it in say Javascript it would look like this:

for (origin in ordered_cache_behaviors) {
  if (origin.s3_target !== default_s3_target) {
     renderContent();
  } else {
     console.log('Content was skipped!');
  }
}
like image 251
SBKDeveloper Avatar asked Mar 05 '26 23:03

SBKDeveloper


1 Answers

The dynamic block for_each argument expects to receive a collection that has one element for each block you want to generate, so the best way to think about your problem is to think about producing a filtered version of var.ordered_cached_behaviors that only contains the elements you want to use to create blocks.

The usual way to filter the elements of a collection is a for expression which includes an if clause. For example:

  dynamic "origin" {
    for_each = [
      for b in var.ordered_cache_behaviors : b
      if b.s3_target == var.default_s3_target
    ]

    content {
      domain_name = "${origin.value.s3_target}.s3.amazonaws.com"
      origin_id   = "S3-${origin.value.s3_target}"    
    }
  }

The result of that for expression will be a new list containing only the subset of source elements that have the expected s3_target attribute value. If none of them have that value then the resulting list would be zero-length and thus Terraform will generate no origin blocks at all.

like image 143
Martin Atkins Avatar answered Mar 07 '26 13:03

Martin Atkins



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!