Using conditional dynamic blocks in Terraform

Revision history
Tags: terraform

Preface

I wanted to use a conditional dynamic block in my Terraform configuration, but dynamic does not support count.

Conditional dynamic block

Instead of count we can use for_each with a conditional map, yielding an empty map for a false value, and a populated map with a single field for a true value:

dynamic "env" {
  # A bogus map for a conditional block
  for_each = var.enable_vault ? {} : { vault_disabled = true }

  content {
    name  = "DOCKER_CONFIG"
    value = "/dockerconfig"
  }
}

For a full example, here’s an example configuration for a Kubernetes pod that conditionally enables secrets via Hashicorp Vault.

variable "enable_vault" {
  type = bool
}

resource "kubernetes_pod_v1" "test" {
  metadata {
    name = "terraform-example"
    annotations = var.enable_vault ? {
      "vault.hashicorp.com/client-timeout"            = "5m"
      "vault.hashicorp.com/agent-inject"              = "true"
      "vault.hashicorp.com/agent-inject-secret-azure" = "azure/creds/some-secret-name"
      "vault.hashicorp.com/role"                      = "some-role-name"
      "vault.hashicorp.com/agent-pre-populate-only"   = "true"
    } : {}
  }

  spec {
    container {
      image = "busybox"
      name  = "app"

      dynamic "env" {
        # A bogus map for a conditional block
        for_each = var.enable_vault ? {} : { vault_disabled = true }

        content {
          name  = "DOCKER_CONFIG"
          value = "/dockerconfig"
        }
      }

      dynamic "volume_mount" {
        # A bogus map for a conditional block
        for_each = var.enable_vault ? {} : { vault_disabled = true }

        content {
          name       = "dockerconfig"
          sub_path   = ".dockerconfigjson"
          mount_path = "/dockerconfig/config.json"
        }
      }
    }

    dynamic "volume" {
      # A bogus map for a conditional block
      for_each = var.enable_vault ? {} : { vault_disabled = true }

      content {
        name = "dockerconfig"
        secret {
          default_mode = "0640"
          optional     = false
          secret_name  = "container-registry"
        }
      }
    }
  }
}

References

If you have any comments or feedback, please send me an e-mail. (stig at stigok dotcom).

Did you find any typos, incorrect information, or have something to add? Then please propose a change to this post.

Creative Commons License This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.