Skip to content

Using Variables

Hardcoding values directly in your configuration is inflexible and can be cumbersome at scale. Input variables in OpenTofu allow you to parameterize your configurations, making them reusable, easier to manage, and safer to share. This guide covers the primary ways to define and provide variables for your OpenTofu projects.

  • The OpenTofu CLI installed.
  • Familiarity with the basic concepts of IaC. See our Introduction to IaC.
  • An active University of Oregon AWS account.

An input variable is a key-value pair that serves as a parameter for your OpenTofu module, allowing you to customize your infrastructure without altering the underlying code. Imagine you have a single, well-architected OpenTofu configuration for your application. Your goal is to deploy this application to three different environments: development, test, and production.

Instead of maintaining three separate, nearly identical copies of your code, you can use one codebase and simply provide different variables for each environment. For development, you might use a small, inexpensive server and a basic database. For test, you might use slightly more powerful resources. For production, you would deploy highly available, resilient, and performant infrastructure. The only thing that changes between these deployments is the set of variables you provide—defining instance sizes, replica counts, or feature flags. This approach makes your infrastructure dramatically more consistent, reusable, and easier to manage, forming the foundation of a robust and scalable deployment strategy.

You declare variables using a variable block, typically in a variables.tf file or at the top of your main.tf. A declaration can include a type, a description, and a default value.

variables.tf
variable "bucket_name" {
description = "The name of the S3 bucket to create. Must be globally unique."
type = string
# No default value is provided.
}
variable "environment_tag" {
description = "The environment for which this infrastructure is being deployed."
type = string
# No default value is provided.
}
  • variable "bucket_name": This block declares a variable named bucket_name.
  • description: It’s a best practice to describe what the variable is for.
  • type: Enforces type constraints (e.g., string, number, bool).
  • default: A fallback value to use if no other value is provided. If a variable has no default, OpenTofu will require you to provide one during the run.

There are several ways to provide values for your declared variables, following a specific order of precedence.

You can pass variables directly at the command line when you run tofu plan or tofu apply using the -var flag. This method is useful for quick, one-off changes.

Terminal window
# Example of providing a variable on the command line
to tofu apply -var="bucket_name=my-new-unique-bucket" -var="environment_tag=development"

This method overrides any default values or values set in other files.

OpenTofu can also read variables from your shell’s environment. The environment variable must be prefixed with TF_VAR_, followed by the name of the variable you want to set.

This is a common method for use in CI/CD pipelines or containerized deployments.

Terminal window
# Set environment variables in your shell
export TF_VAR_bucket_name="another-unique-bucket-name"
export TF_VAR_environment_tag="production"
# Now run tofu, and it will pick up these variables automatically
to tofu apply

For more permanent values, you can create variable definition files. OpenTofu automatically loads variables from files named terraform.tfvars or *.auto.tfvars if they are present in the directory.

Create a file named terraform.tfvars:

terraform.tfvars
bucket_name = "my-app-storage-bucket"
environment_tag = "test"

When you run tofu plan or tofu apply, OpenTofu will automatically load these values.

For more complex setups, such as managing multiple environments, it is common to create environment-specific variable files (e.g., development.tfvars, production.tfvars). You can then instruct OpenTofu to use a specific file at runtime using the -var-file command-line flag. This is a powerful way to switch context between environments.

Terminal window
# Create a specific var file for production
# production.tfvars
# bucket_name = "uo-prod-critical-app"
# environment_tag = "production"
# Tell OpenTofu to use this file
tofu apply -var-file="production.tfvars"

Precedence Order: OpenTofu loads variables in a specific order, with later sources overriding earlier ones. Understanding this is key to managing complex configurations. The order is:

  1. Command-line flags: The -var and -var-file flags have the highest precedence.
  2. .auto.tfvars files: Any files with this extension are loaded next.
  3. terraform.tfvars file: This is the standard variable file.
  4. Environment variables: TF_VAR_ prefixed variables are loaded after file-based variables.
  5. Default values: A variable’s default block is used only if no other value is provided (lowest priority).