0

I'm trying to create a secret on GCP's Secret Manager.

The secret value is coming from Vault (HCP Cloud).

How can I pass a value of the secret if I'm using a .tfvars file for the values?

Creating the secret without .tfvars works. Other suggestions rather than data source are welcomed as well. I saw that referring locals isn't possible as well inside tfvars.

vault.tf:

provider "vault" {
  address = "https://testing-vault-public-vault-numbers.numbers.z1.hashicorp.cloud:8200"
  token   = "someToken"
}

data "vault_generic_secret" "secrets" {
  path = "secrets/terraform/cloudcomposer/kafka/"
}

main.tf:

resource "google_secret_manager_secret" "connections" {
  provider  = google-beta
  count     = length(var.connections)
  secret_id = "${var.secret_manager_prefix}-${var.connections[count.index].name}"
  replication {
    automatic = true
  }
}

resource "google_secret_manager_secret_version" "connections-version" {
  count       = length(var.connections)
  secret      = google_secret_manager_secret.connections[count.index].id
  secret_data = var.connections[count.index].uri
}

dev.tfvars:

image_version                     = "composer-2-airflow-2.1.4"
env_size                          = "LARGE"
env_name                          = "development"
region                            = "us-central1"
network                           = "development-main"
subnetwork                        = "development-subnet1"
secret_manager_prefix = "test"
connections = [
  { name = "postgres", uri = "postgresql://postgres_user:[email protected]:5432/"}, ## This one works
  { name = "kafka", uri = "${data.vault_generic_secret.secrets.data["kafka_dev_password"]}" 
]

Getting:

Error: Invalid expression on ./tfvars/dev.tfvars line 39: Expected the start of an expression, but found an invalid expression token.

Thanks in advance.

2
  • That is not possible. Commented Dec 26, 2022 at 9:27
  • Thanks for the fast response. Is there an alternative you can think of? Commented Dec 26, 2022 at 9:31

1 Answer 1

6

Values in the tfvars files have to be static, i.e., they cannot use any kind of a dynamic assignment like when using data sources. However, in that case, using local variables [1] should be a viable solution:

locals {
  connections = [
    {
      name = "kafka",
      uri = data.vault_generic_secret.secrets.data["kafka_dev_password"]
    }
  ]
}

Then, in the resource you need to use it in:

resource "google_secret_manager_secret" "connections" {
  provider  = google-beta
  count     = length(local.connections)
  secret_id = "${var.secret_manager_prefix}-${local.connections[count.index].name}"
  replication {
    automatic = true
  }
}

resource "google_secret_manager_secret_version" "connections-version" {
  count       = length(local.connections)
  secret      = google_secret_manager_secret.connections[count.index].id
  secret_data = local.connections[count.index].uri
}

[1] https://developer.hashicorp.com/terraform/language/values/locals

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! I prefer having all values in .tfvars but if it's what I have i'll take the connections out to a locals block.
This also means I can't deploy secrets per env since today I'm passing env.app.tfvars. Having locals block like this means TF will always deploy all connections every deployment
You can of course play around, but this is the only way it can work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.