2

I'm trying to create the following block dynamically based on a list of strings

        env {
          name = "SECRET_ENV_VAR"
      value_from {
            secret_key_ref {
              name = google_secret_manager_secret.secret.secret_id
              key = "1"
            }
          }
        }

Based off documentation: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_service#example-usage---cloud-run-service-secret-environment-variables

I would like to dynamically add Secrets, and have defined the following dynamic block:

        dynamic "env" {
          for_each = toset(var.secrets)
          content {
            name = each.value
            value_from {
              secret_key_ref {
                name = each.value
                key  = "1"
              }
            }
          }
        }

Where secrets is a variable of type list(string)

However, this throws an error: Blocks of type "value_from" are not expected here.

I'm not sure what I'm missing, or where I have incorrectly specified the value_from block.

Could someone point me in the right direction for fixing this up?

UPDATE; I have also tried to implement this variable as a map, as per the suggestion in the comments on this post. (https://www.terraform.io/docs/language/expressions/dynamic-blocks.html#multi-level-nested-block-structures)

        dynamic "env" {
          for_each = var.secrets
          content {
            name = each.key
            dynamic "value_from" {
              for_each = env.value.name
              secret_key_ref {
                name = value_from.value.name
                key  = value_from.value.version
              }
            }
          }
        }

However, this also gives the same error. Blocks of type "value_from" are not expected here.

In this example, the secrets variable is defined as a list(any) with this value:

secrets = [
    {
      name    = "SECRET"
      version = "1"
    }
  ]
fuzzi
  • 1,967
  • 9
  • 46
  • 90
  • Have you seen https://www.terraform.io/docs/language/expressions/dynamic-blocks.html#multi-level-nested-block-structures? – sethvargo Nov 12 '21 at 15:53
  • This is not the root cause, but your temporary lambda iterator variable is incorrect: it is `env` and not `each` for your dynamic block. You should update e.g. `each.value` to `env.value`. That will fix the next error you would encounter after fixing this one. – Matthew Schuchard Nov 12 '21 at 15:55
  • Thanks, I'm trying a solution with "dynamic" to cater for the nested "value_from" block – fuzzi Nov 12 '21 at 16:36
  • Updating to the nested dynamic block, still gives the error message: `Blocks of type "value_from" are not expected here.` – fuzzi Nov 12 '21 at 19:13
  • @sethvargo I tried following the documentation, and updated the variable type from a list of strings, to map of strings. But I still got the same error. I have updated my post with what I tried. – fuzzi Nov 12 '21 at 19:52

3 Answers3

1

You have to upgrade your gcp provider. Support for secrets in google_cloud_run_service was added in v3.67.0. Current version is v4.1.0, which means that you must be using very old gcp provider.

Marcin
  • 215,873
  • 14
  • 235
  • 294
  • 1
    Thanks - I confirmed that I have upgraded to v4.1.0, but still get the error message. – fuzzi Nov 19 '21 at 14:52
0

In the end, I solved this by changing the variable type to a map(any):

secrets = {
    "SECRET" = "1"
}

This allowed me to create the "dynamic" env block, without needing to implement the nested dynamic block.

fuzzi
  • 1,967
  • 9
  • 46
  • 90
0

I made it work this way, the nested dynamic blocks:

dynamic "env" {
  for_each = var.cloud_run_container_envs_secrets
  content {
    name = env.value.name
    dynamic "value_from" {
      for_each = [1]
      content {
        dynamic "secret_key_ref" {
          for_each = [1]
          content {
            name = env.value.value_from.secret_key_ref.name
            key  = env.value.value_from.secret_key_ref.key
          }
        }
      }
    }
  }
}

The variable definition:

variable "cloud_run_container_envs_secrets" {
  type = map(object({
    name = string
    value_from = object({
      secret_key_ref = object({
        name = string
        key  = string
      })
    })
  }))
}

A variable sample:

  cloud_run_container_envs_secrets = {
    MY_VAR = {
      name = "MY_VAR"
      value_from = {
        secret_key_ref = {
          name = "my_secret"
          key  = "latest"
        }
      }
    },
    MY_VAR2 = {
      name = "MY_VAR2"
      value_from = {
        secret_key_ref = {
          name = "my_secret2"
          key  = "latest"
        }
      }
    }
  }
Xut
  • 23
  • 4