Terraform’s Vault provider can inject secrets directly into your infrastructure configuration at apply time, but it’s not a substitute for managing secrets in Vault itself.

Let’s say you’re provisioning a new Kubernetes cluster and need to give your application pods access to a database password stored in Vault.

Here’s how you’d typically do it:

provider "vault" {
  address = "http://127.0.0.1:8200"
  token   = "my-root-token" # In production, use proper authentication!
}

data "vault_generic_secret" "db_creds" {
  path = "secret/data/myapp/database"
}

resource "kubernetes_secret" "db_password" {
  metadata {
    name = "db-password"
  }

  data = {
    password = data.vault_generic_secret.db_creds.data.password
  }
}

resource "kubernetes_deployment" "app" {
  # ... other deployment configurations ...
  spec {
    template {
      spec {
        container {
          name  = "myapp"
          image = "my-app-image:latest"
          env {
            name  = "DB_PASSWORD"
            value = kubernetes_secret.db_password.data.password
          }
        }
      }
    }
  }
}

When you run terraform apply, Terraform first queries Vault using the vault_generic_secret data source. It fetches the secret located at secret/data/myapp/database. The data block in this source is crucial; it tells Terraform to retrieve the data field from the Vault secret, which in this example, contains the actual password.

Then, Terraform takes the retrieved password and uses it to populate the kubernetes_secret resource, which will create a Kubernetes secret object. Finally, it uses that secret’s data to set an environment variable within your Kubernetes deployment. This means your application pod will receive the database password as an environment variable at runtime, securely fetched from Vault by Terraform during the provisioning process.

The real power here is that your Terraform code itself never directly contains the sensitive password. It only knows how to ask Vault for it. This keeps your Terraform state file clean and prevents accidental exposure of credentials.

What most people don’t realize is that the path in vault_generic_secret maps directly to the Vault KV v2 path. If your secret is at secret/myapp/database in Vault, you’d use path = "secret/data/myapp/database". The data suffix is for KV v2 engine’s read operation. For KV v1, you’d omit the /data/.

Understanding how Vault’s authentication methods integrate with the Terraform provider is the next logical step for secure secret management.

Want structured learning?

Take the full Terraform course →