Skip to content

Multiple dynamic blocks for , where only one will ultimately resolve, not working for blocks that only allow 1 max  #22414

@jhoos

Description

@jhoos

I'm running into an issue where I'm trying to use dynamic blocks to pick between two alternative types of liveness probes in a kubernetes_deployment resource, using a ternary expression in the for_each of each dynamic block to pick between an empty or non-empty list.

In this situation, Terraform seems to be seeing both dynamic blocks during validation, and is not taking into account the possibility that only one of the two dynamics will actually resolve into a real block.

For now I can work around this by using a pair of dynamic blocks inside the liveness_probe block, which works as long as one of the two blocks results in a real block (unfortunately it doesn't allow for the possibility of there being no liveness probe at all, due to an unrelated issue with the Kubernetes provider that results in an error during the actual call to Kubernetes in that case).

Terraform Version

Terraform v0.12.6
+ provider.kubernetes v1.8.1

Terraform Configuration Files

provider kubernetes {}

variable use_exec_instead {
    default = ["echo"]
}

resource "kubernetes_deployment" "this" {
    metadata {
        name = "test"
        namespace = "test"
        labels = { test: "test" }
    }

    spec {
        selector {
            match_labels = { test: "test" }
        }
        template {
            metadata {
                labels = { test: "test" }
            }
            spec {
                container {
                    name = "main"
                    image = "alpine:3.8"

                    dynamic "liveness_probe" {
                        for_each = var.use_exec_instead == null ? ["/check"] : []
                        content {
                            http_get {
                                path = liveness_probe.value
                            }
                        }
                    }

                    dynamic "liveness_probe" {
                        for_each = var.use_exec_instead != null ? [var.use_exec_instead] : []
                        content {
                            exec {
                                command = liveness_probe.value
                            }
                        }
                    }
                }
            }
        }
    }
}

Debug Output

Expected Behavior

Terraform should produce a plan containing the second dynamic "liveness_probe" block, and ignore the first.

Actual Behavior

Terraform produces the error:

Error: Too many liveness_probe blocks

  on  line 0:
  (source code not available)

No more than 1 "liveness_probe" blocks are allowed

Steps to Reproduce

  1. terraform init
  2. terraform plan -refresh=false

Additional Context

Interestingly, this scenario works just fine if I hard-code the two for_each lists instead of using the variable and ternary; e.g. if I do for_each = [] in one block and for_each = [["echo"]] in the other.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions