1
votes

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!');
  }
}
1

1 Answers

4
votes

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.