Move sensitive Terraform values from terraform.tfvars into an external secrets store for improved security.
By default, sensitive values like tfy_api_key are stored directly in terraform.tfvars. While convenient for initial setup, this is a security risk if the file is committed to version control.
Terraform only reads from the secrets backend. You are responsible for creating and updating the secrets outside of Terraform.
Pick the tab that matches your secrets infrastructure and follow the steps.
AWS Secrets Manager
AWS SSM Parameter Store
HashiCorp Vault
1Password
Prerequisites
AWS IAM permissions — the identity running Terraform needs:
secretsmanager:GetSecretValue
secretsmanager:DescribeSecret
Migration Steps
1
Create the secret in AWS Secrets Manager
Before running Terraform, manually create a secret in AWS Secrets Manager. The secret value must be a JSON object containing all the credentials you want to manage:
Terraform — must be compatible with the Vault provider hashicorp/vault (version = 4.8.0).
Migration Steps
1
Create the secret in Vault
Store all the credentials you want to manage in a single Vault secret. This can be done manually via console or using the CLI. For example, store tfy_api_key and license_key as keys in the secret.
2
Add secrets.tf
Create a file named secrets.tf in your Terraform root directory with the following contents:
secrets.tf
terraform { required_providers { vault = { source = "hashicorp/vault" version = "4.8.0" } }}provider "vault" {}variable "use_remote_credentials" { type = bool description = "When true, pull secrets from Vault. When false, use values from terraform.tfvars directly." default = true}variable "vault_secret_mount" { type = string description = "Vault KV v2 mount path where TrueFoundry credentials are stored" default = "secret"}variable "vault_secret_path" { type = string description = "Path within the Vault KV v2 mount for TrueFoundry credentials. The secret must contain key: tfy_api_key" default = "truefoundry/terraform-secrets"}data "vault_kv_secret_v2" "tfy" { count = var.use_remote_credentials ? 1 : 0 mount = var.vault_secret_mount name = var.vault_secret_path}locals { secrets = var.use_remote_credentials ? data.vault_kv_secret_v2.tfy[0].data : {} tfy_api_key = var.use_remote_credentials ? local.secrets["tfy_api_key"] : var.tfy_api_key license_key = var.use_remote_credentials ? local.secrets["license_key"] : var.license_key}
Add a line to locals for each key in your Vault secret. The fallback variables (e.g. var.license_key) are only used when use_remote_credentials = false.
export VAULT_ADDR="https://vault.example.com:8200"export VAULT_TOKEN="your-vault-token"tofu init # downloads the hashicorp/vault providertofu plan # review — no new resources, just data source readstofu apply
Prerequisites
1Password CLI installed (optional, for creating the item).
1Password Service Account with access to the vault containing your credentials.
Service Account Token — set the following environment variable before running Terraform:
OP_SERVICE_ACCOUNT_TOKEN — your 1Password service account token
Terraform — must be compatible with the 1Password provider (1Password/onepassword, version >= 2.1.0).
Migration Steps
1
Create the 1Password item
Create a Secure Note in your 1Password vault with custom text fields for each credential:
Field Label
Value
tfy_api_key
Your TrueFoundry API key
license_key
Your license key
This can be done via the 1Password web app, desktop app, or CLI. Note down the vault UUID and item UUID — the values are the actual vault name and item name.
2
Add secrets.tf
Create a file named secrets.tf in your Terraform root directory with the following contents:
secrets.tf
terraform { required_providers { onepassword = { source = "1Password/onepassword" version = ">= 2.1.0" } }}provider "onepassword" {}variable "use_remote_credentials" { type = bool description = "When true, pull secrets from 1Password. When false, use values from terraform.tfvars directly." default = true}variable "op_vault_uuid" { type = string description = "UUID of the 1Password vault containing TrueFoundry credentials"}variable "op_item_uuid" { type = string description = "UUID of the 1Password item containing TrueFoundry credentials"}data "onepassword_item" "tfy" { count = var.use_remote_credentials ? 1 : 0 vault = var.op_vault_uuid uuid = var.op_item_uuid}locals { secrets = var.use_remote_credentials ? { for f in data.onepassword_item.tfy[0].section[0].field : f.label => f.value } : {} tfy_api_key = var.use_remote_credentials ? local.secrets["tfy_api_key"] : var.tfy_api_key license_key = var.use_remote_credentials ? local.secrets["license_key"] : var.license_key}
Add a line to locals for each field in your 1Password item. The fallback variables (e.g. var.license_key) are only used when use_remote_credentials = false.
export OP_SERVICE_ACCOUNT_TOKEN="your-service-account-token"tofu init # downloads the 1Password/onepassword providertofu plan # review — no new resources, just data source readstofu apply
The 1Password provider requires the OP_SERVICE_ACCOUNT_TOKEN environment variable to be set even during tofu init when the provider block is present.
Update the secret value directly in your secrets store (AWS Secrets Manager, SSM, Vault, or 1Password), then run tofu apply to propagate the new values.
How do I fall back to terraform.tfvars?
All four backends support a quick fallback without removing secrets.tf. Set:
use_remote_credentials = false
in your terraform.tfvars and provide the tfy_api_key value directly. The remote data source will be skipped entirely (count = 0) — no network calls to the secrets backend will be made.
How do I switch between backends?
Replace the contents of secrets.tf with the new backend’s configuration from the relevant tab above.
Update terraform.tfvars with the new backend’s variables and remove the old backend’s variables.
Re-initialize and apply:
tofu init -upgrade # install any new providerstofu plantofu apply
The secrets.tf file should contain only one backend’s configuration at a time.