terraform: Using dynamic blocks to conditionally set a block on a resource

2 min read

In the same way we can conditionally include a resource, we can also use for_each to conditionally include a nested block using terraform's dynamic blocks

For example, if we want to add a variable that controls whether we should set this value:

resource "helm_release" "spinnaker" {
  name  = "spinnaker"

  (...)

  set {
    name = "halyard.additionalScripts.data.enable_mptv2"
    type = "string"
    value = <<-EOF
      #!/bin/sh
      cat $0
      echo "custom mptv2"
      $HAL_COMMAND config features edit --managed-pipeline-templates-v2-ui true
    EOF
  }
}

What we can do is to create a dynamic block with a for_each that contains just one element if the variable is true and none otherwise:

resource "helm_release" "spinnaker" {
  name  = "spinnaker"

  (...)

  dynamic "set" {
    for_each = var.mptv2 ? ["a"] : []
    content {
      name = "halyard.additionalScripts.data.enable_mptv2"
      type = "string"
      value = <<-EOF
        #!/bin/sh
        cat $0
        echo "custom mptv2"
        $HAL_COMMAND config features edit --managed-pipeline-templates-v2-ui true
      EOF
    }
  }
}

So, if the variable var.mptv2 is false; for_each will be evaluated to an empty list so this block won't be included on the resource definition. On the other hand, if var.mptv2 is true; for_each will contain a list of exactly one element so the block will be included once. Notice we are not using any loop variables for the block creation.

At the end of the day, are using for_each in a similar fashion we use count to conditionally include a resource but for a set of attributes for a given resource.


Posted on 28/05/2021