# Vault\_generic\_secret and variables in json?

**URL:** <https://discuss.hashicorp.com/t/vault-generic-secret-and-variables-in-json/29790>\
**Category:** Terraform\
**Created:** [September 22, 2021, 4:15pm UTC](https://discuss.hashicorp.com/t/vault-generic-secret-and-variables-in-json/29790 "2021-09-22T16:15:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![tnr](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/tnr/32/17393_2.png) [@tnr](https://discuss.hashicorp.com/u/tnr)\
**Post date:** [September 22, 2021, 4:15pm UTC](https://discuss.hashicorp.com/t/vault-generic-secret-and-variables-in-json/29790/1 "2021-09-22T16:15:52Z")

</div>

Hi all,

So I am configuring Vault with Terraform and using vault\_generic\_secret to enter my secrets. The issue is that I’m using gitlab to do this as I don’t want the secrets in my raw code of course. I’m using gitlab variables to define the secrets. Looks like the only way to enter secrets is through json

So here is my resource:

```auto
resource "vault_generic_secret" "secret" {
  path = "kv/mysecret"
  depends_on = [vault_mount.kv2]

  data_json = <<EOT
{
  "username": "$my_user",
  "password": "$my_password"
}
EOT
}

```

The secret values I get from this are $my\_user $my\_password, so it’s not evaluating the variables. I’ve even tried curly braces around the variable names with no luck.

There has to be a simple solution for this that I am ignorant of 🙂

thanks for any input

---

<div class="post-metadata">

**Author:** ![apparentlymart](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/apparentlymart/32/702_2.png) [@apparentlymart](https://discuss.hashicorp.com/u/apparentlymart)\
**Post date:** [September 23, 2021, 5:27pm UTC](https://discuss.hashicorp.com/t/vault-generic-secret-and-variables-in-json/29790/2 "2021-09-23T17:27:20Z")

</div>

Hi @tnr,

When building JSON values in Terraform I recommend always using [the `jsonencode` function](https://www.terraform.io/docs/language/functions/jsonencode.html), rather than string concatenation using templates, because then you can just construct a suitable data structure using normal Terraform expressions and let Terraform be the one responsible for making it valid JSON syntax.

In your case, that would look something like the following:

```auto
variable "username" {
  type = string
}

variable "password" {
  type = string
  sensitive = true
}

resource "vault_generic_secret" "secret" {
  depends_on = [vault_mount.kv2]

  path = "kv/mysecret"
  data_json = jsonencode({
    username = var.username
    password = var.password
  })
}

```

You could then arrange for your GitLab task to pass in the values to those variables. One relatively-easy way to do that is to set environment variables whose names start with `TF_VAR_`, which in this case would be `TF_VAR_username` and `TF_VAR_password` (case sensitive), which Terraform can then use as values for those two input variables I declared in the example above.

With that said, if you intend to populate Vault using Terraform please be sure to read the guidelines and recommendations in [the `hashicorp/vault` provider documentation](https://registry.terraform.io/providers/hashicorp/vault/latest/docs) to understand what additional steps you might need to take in order to protect the sensitive values. The `sensitive = true` in the example above is only for hiding values in the Terraform UI and so the values you specify for `password` will still be included in clear text in the state snapshots produced by this configuration and in saved plan files, if you use `terraform plan -out=tfplan` or similar to carry a plan between two workflow steps as an artifact.

---

<div class="post-metadata">

**Author:** ![tnr](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/tnr/32/17393_2.png) [@tnr](https://discuss.hashicorp.com/u/tnr)\
**Post date:** [September 23, 2021, 6:26pm UTC](https://discuss.hashicorp.com/t/vault-generic-secret-and-variables-in-json/29790/3 "2021-09-23T18:26:22Z")

</div>

Thank you for the reply, I was actually working on what you replied with as I’ve done much Googling this morning piecing stuff together 🙂 jsonencode was not part of that but that looks much cleaner and I will implement that.

I am torn on this a bit as it seems to negate what Vault was designed to do, be a place to store secrets among other things and not have them living anywhere else. Well, now they are in Gitlab as variables as well as any terraform artifacts, but not having its config codified can lead to other issues as well. So yeah, I’m a bit torn on this solution.

---

<div class="post-metadata">

**Author:** ![apparentlymart](https://sea2.discourse-cdn.com/hashicorp/user_avatar/discuss.hashicorp.com/apparentlymart/32/702_2.png) [@apparentlymart](https://discuss.hashicorp.com/u/apparentlymart)\
**Post date:** [September 23, 2021, 10:13pm UTC](https://discuss.hashicorp.com/t/vault-generic-secret-and-variables-in-json/29790/4 "2021-09-23T22:13:42Z")

</div>

Indeed… while I can’t give you specific security advice (what’s appropriate will always depend on your specific situation and your threat model), I will say that when folks use the `hashicorp/vault` provider to populate Vault it’s _normally_ for secrets that were generated as part of Terraform’s normal work, such as saving a key that was dynamically generated and returned as part of creating some other object.

Using Terraform in this way to place _static_ credentials into Vault is not so conventional, particularly if part of getting there is to save them as variables in your CI system. If you’re going to manually configure the static secrets _somewhere_, it could be reasonable for that “somewhere” to be Vault itself directly, rather than a CI process that writes to Vault.

Of course, there can be advantages and disadvantages on both sides, so the final decision is ultimately yours to make.
