Skip to content

How to parameterize a template with a tfvars file

How-to · Updated Jun 2026

Coming from another cloud?

▸AWS·Terraform Workspaces

This Quake AI feature maps to AWS’s Terraform Workspaces.

▸Google Cloud·Terraform Environments

This Quake AI feature maps to Google Cloud’s Terraform Environments.

How to parameterize a template with a tfvars file

Reuse the same OpenTofu template in development, staging, and production without forking the HCL. Store environment-specific values in .tfvars files and pass them with -var-file at plan and apply time.

This guide applies to any template under Automation templates that declares variables in variables.tf.

Prerequisites#

Identify variables to externalize#

Open variables.tf in your template directory. Every template exposes a set of input variables with optional defaults. Values you change per environment or per deployment belong in a tfvars file, not in edited defaults inside variables.tf.

The simple-vm template declares six variables:

VariableDefaultTypical override
flavor_names1a.smallLarger flavor in production
image_nameUbuntu-24.04Pin a specific OS build
key_name(required)Same key across environments
instance_namesimple-vmPrefix with environment name
external_networkPublicStaticRarely changes
private_cidr10.10.10.0/24Unique CIDR per environment

The edge-reverse-proxy template adds proxy and upstream settings:

VariableDefaultTypical override
flavor_names1a.smallSize up web nodes
domain(empty)Environment-specific hostname
upstream_host10.42.0.10Private address of the application
private_cidr10.42.0.0/24Unique CIDR per environment

Required variables such as key_name have no default. You must set them in a tfvars file or pass them with -var on the command line.

Create a base tfvars file#

Add terraform.tfvars in the template directory for values that apply to every environment:

HCL
# terraform.tfvars: shared across all environments
key_name         = "deploy-key"
external_network = "PublicStatic"
image_name       = "Ubuntu-24.04"

OpenTofu loads terraform.tfvars automatically on every plan and apply. You do not pass a flag for this file.

Add per-environment override files#

Create one tfvars file per environment under an envs/ subdirectory:

iac/templates/simple-vm/
  main.tf
  variables.tf
  terraform.tfvars
  envs/
    dev.tfvars
    prod.tfvars

envs/dev.tfvars:

HCL
instance_name = "dev-simple-vm"
flavor_name   = "s1a.small"
private_cidr  = "10.10.10.0/24"

envs/prod.tfvars:

HCL
instance_name = "prod-simple-vm"
flavor_name   = "m2a.large"
private_cidr  = "10.10.100.0/24"

For edge-reverse-proxy, set the hostname and upstream per environment:

envs/dev.tfvars:

HCL
domain        = "dev.example.com"
upstream_host = "10.40.0.20"
flavor_name   = "s1a.small"
private_cidr  = "10.40.0.0/24"

envs/prod.tfvars:

HCL
domain        = "www.example.com"
upstream_host = "10.41.0.20"
flavor_name   = "m2a.large"
private_cidr  = "10.41.0.0/24"

Later files passed with -var-file override earlier values. OpenTofu merges terraform.tfvars first, then each -var-file in the order you specify.

Plan and apply with -var-file#

From the template directory, pass the environment file explicitly:

bash
tofu plan -var-file=envs/dev.tfvars
tofu apply -var-file=envs/dev.tfvars

For production:

bash
tofu plan -var-file=envs/prod.tfvars
tofu apply -var-file=envs/prod.tfvars

Pass multiple var-files when a shared baseline and an environment override live in separate files:

bash
tofu apply -var-file=envs/common.tfvars -var-file=envs/prod.tfvars

Values in prod.tfvars win over common.tfvars for any variable defined in both.

Pair tfvars with separate state#

Variable files control what OpenTofu provisions. They do not isolate state. Dev and production must use different state files so a tofu destroy in dev never touches production resources.

If you use a remote backend, pass a different state key per environment during init:

bash
tofu init -backend-config="key=dev/simple-vm.tfstate"
tofu apply -var-file=envs/dev.tfvars

For production, re-init with a different key:

bash
tofu init -reconfigure -backend-config="key=prod/simple-vm.tfstate"
tofu apply -var-file=envs/prod.tfvars

The full remote-backend setup lives in How to manage OpenTofu state with Quake AI S3. The directory-per-environment alternative is in How to manage multiple environments with OpenTofu.

Verify the active variable values#

After apply, read the values OpenTofu wrote to state:

bash
tofu show

Search the output for resource attributes such as flavor_name and instance_name. State reflects the -var-file values from apply, not the defaults in variables.tf.

To inspect variable resolution before a plan, pass the same -var-file flag to the console:

bash
tofu console -var-file=envs/dev.tfvars

At the prompt, read a variable:

> var.flavor_name
"s1a.small"

Type exit to leave the console.

For compute templates, cross-check the flavor against the live catalog:

bash
openstack server list -f table -c Name -c Flavor

If a plan fails with value must be known or No value for required variable, the variable is missing from both terraform.tfvars and the -var-file you passed. Add it to the tfvars file or pass -var 'key_name=deploy-key' on the command line.

See also#

Usage Guidelines

The sample code, software libraries, command line tools, proofs of concept, templates, and other related technology on this page (including any of the foregoing that is provided by Quake AI personnel) is provided to you as Quake AI Content under the Quake AI Customer Agreement, or the relevant written agreement between you and Quake AI (whichever applies). Do not use this Quake AI Content in your production accounts, or on production or other critical data. You are responsible for testing, securing, and optimizing the Quake AI Content (such as sample code) as appropriate for production grade use based on your specific quality control practices and standards. Deploying Quake AI Content may incur Quake AI charges for creating or using Quake AI chargeable resources, such as running Compute instances or storing data in Object Storage. Your use is also subject to the Acceptable Use Policy.

For the full policy, see Usage Guidelines.

Last validated: 26.06.2026

Was this page helpful?