0
0
Terraformcloud~15 mins

Variable declaration syntax in Terraform - Deep Dive

Choose your learning style9 modes available
Overview - Variable declaration syntax
What is it?
Variable declaration syntax in Terraform is how you define inputs that can change the behavior of your infrastructure code. Variables let you write flexible and reusable configurations by allowing values to be set outside the code. You declare variables with a specific syntax that includes the variable name, type, default value, and description.
Why it matters
Without variables, every time you want to change something in your infrastructure, you'd have to edit the code directly, which is slow and error-prone. Variables make your infrastructure code adaptable and easier to manage, especially when working with different environments or teams. They help avoid mistakes and speed up deployment.
Where it fits
Before learning variable declaration, you should understand basic Terraform configuration files and resource definitions. After mastering variables, you can learn about variable validation, input/output variables, and how to use variables in modules for reusable infrastructure.
Mental Model
Core Idea
Variables in Terraform are named placeholders that let you customize infrastructure settings without changing the code itself.
Think of it like...
Think of variables like adjustable knobs on a machine. Instead of rebuilding the machine for every task, you just turn the knobs to set it up differently each time.
┌───────────────┐
│ variable "name" │
│ ┌───────────┐ │
│ │ type      │ │
│ │ default   │ │
│ │ description│ │
│ └───────────┘ │
└───────────────┘

Usage: var.name
Build-Up - 7 Steps
1
FoundationBasic variable declaration syntax
🤔
Concept: How to declare a simple variable with a name and optional default value.
In Terraform, you declare a variable using the 'variable' block with a name. You can optionally provide a default value. Example: variable "region" { default = "us-west-1" } This creates a variable named 'region' with a default value 'us-west-1'.
Result
Terraform now knows about a variable called 'region' that can be used in the configuration. If no value is provided during apply, it uses 'us-west-1'.
Understanding the basic syntax is the foundation for making your Terraform code flexible and reusable.
2
FoundationVariable types and their declaration
🤔
Concept: Variables can have types like string, number, bool, list, map, and object to enforce the kind of data they hold.
You can specify the type of a variable to ensure only valid data is accepted. Example: variable "instance_count" { type = number default = 3 } This variable only accepts numbers. If you try to assign a string, Terraform will error.
Result
Terraform validates input values against the declared type, preventing configuration errors early.
Knowing variable types helps catch mistakes before deployment and documents expected input clearly.
3
IntermediateUsing descriptions for clarity
🤔
Concept: Adding descriptions to variables improves code readability and helps users understand what each variable controls.
You can add a description inside the variable block: variable "environment" { type = string description = "The deployment environment, e.g., dev, staging, or prod" } This text appears when users run 'terraform input' or read documentation.
Result
Users and collaborators understand the purpose of variables without guessing, reducing misconfiguration.
Descriptions make your code self-explanatory and easier to maintain, especially in teams.
4
IntermediateNo default means required input
🤔Before reading on: Do you think a variable without a default value is optional or required? Commit to your answer.
Concept: If you declare a variable without a default, Terraform requires a value to be provided during apply.
Example: variable "project_name" { type = string } Since no default is set, Terraform will prompt for this value or require it via CLI or environment variables.
Result
Terraform enforces that required variables are provided, preventing incomplete configurations.
Knowing this helps you design configurations that force users to provide critical information.
5
IntermediateComplex types: lists, maps, and objects
🤔Before reading on: Which do you think is better for multiple values: list or map? Commit to your answer.
Concept: Terraform supports complex variable types like lists (ordered values), maps (key-value pairs), and objects (structured data).
Examples: variable "availability_zones" { type = list(string) default = ["us-west-1a", "us-west-1b"] } variable "tags" { type = map(string) default = { "env" = "prod", "team" = "devops" } } variable "server" { type = object({ cpu = number memory = number }) default = { cpu = 2, memory = 4096 } } These allow passing structured data to your infrastructure.
Result
You can pass multiple related values cleanly and enforce their structure.
Understanding complex types unlocks powerful ways to configure infrastructure with precision.
6
AdvancedVariable validation rules
🤔Before reading on: Do you think Terraform variables can check if a value meets conditions? Commit to your answer.
Concept: Terraform lets you add validation blocks inside variables to enforce rules on input values.
Example: variable "instance_count" { type = number default = 1 validation { condition = var.instance_count > 0 && var.instance_count < 10 error_message = "instance_count must be between 1 and 9" } } Terraform will reject values outside this range with a clear error.
Result
Input values are checked before deployment, preventing invalid configurations.
Validation improves reliability by catching errors early and guiding users to correct inputs.
7
ExpertVariable declaration in modules and overrides
🤔Before reading on: Can variables declared in modules be overridden from the root module? Commit to your answer.
Concept: Variables declared inside modules act as inputs that can be set or overridden by the root module or calling modules, enabling reuse and customization.
Inside a module: variable "region" { type = string default = "us-east-1" } In root module calling it: module "my_module" { source = "./modules/example" region = "us-west-2" } The root module overrides the default region for the module. This pattern allows creating reusable modules with flexible inputs.
Result
Modules become configurable building blocks, making infrastructure code scalable and maintainable.
Understanding variable overrides in modules is key to building complex, reusable Terraform architectures.
Under the Hood
Terraform parses variable blocks during the plan phase and builds an internal map of variable names to values. It merges default values with user-provided inputs from CLI flags, environment variables, or tfvars files. Type constraints and validations are applied to ensure correctness before resource creation. Variables are then referenced in the configuration as 'var.', replaced with their resolved values during execution.
Why designed this way?
Terraform variables were designed to separate configuration from code, enabling reuse and flexibility. The syntax balances simplicity with power, allowing both simple and complex data types. Validation was added later to improve safety. The design avoids hardcoding values, which would limit automation and increase errors.
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│ Variable Block│──────▶│ Value Sources │──────▶│ Validation &  │
│ (name, type,  │       │ (default, CLI,│       │ Type Checking │
│  default, desc)│       │ env, tfvars)  │       └───────────────┘
└───────────────┘       └───────────────┘               │
                                                      ▼
                                               ┌───────────────┐
                                               │ Final Variable│
                                               │ Values Used   │
                                               │ in Config     │
                                               └───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does a variable without a default always have a value at runtime? Commit yes or no.
Common Belief:If a variable has no default, Terraform will automatically assign a null or empty value.
Tap to reveal reality
Reality:Terraform requires the user to provide a value for variables without defaults; otherwise, it errors.
Why it matters:Assuming a variable is optional when it is required causes deployment failures and confusion.
Quick: Can you assign any type of value to a variable regardless of its declared type? Commit yes or no.
Common Belief:Terraform variables accept any value regardless of the declared type.
Tap to reveal reality
Reality:Terraform enforces the declared type strictly and rejects incompatible values during plan.
Why it matters:Ignoring type constraints leads to runtime errors and broken infrastructure deployments.
Quick: Do variables declared inside modules behave independently from root module variables? Commit yes or no.
Common Belief:Module variables are global and cannot be overridden by the root module.
Tap to reveal reality
Reality:Module variables are local to the module but can be overridden by passing values from the root module.
Why it matters:Misunderstanding this limits module reuse and flexibility, causing duplicated code.
Quick: Does adding a description to a variable affect its runtime behavior? Commit yes or no.
Common Belief:Descriptions change how variables behave during deployment.
Tap to reveal reality
Reality:Descriptions are only for documentation and user guidance; they do not affect execution.
Why it matters:Confusing descriptions with behavior can lead to wasted effort trying to 'fix' non-issues.
Expert Zone
1
Terraform variable defaults are evaluated only once during plan, so dynamic expressions in defaults can lead to unexpected results.
2
Validation blocks run after merging all input sources, so they can enforce complex rules combining multiple variables indirectly.
3
Variables of object type can have nested attributes with their own types, enabling precise schema validation for complex inputs.
When NOT to use
Avoid using variables for secrets or sensitive data directly; instead, use dedicated secret management tools or Terraform's sensitive variable feature. Also, do not overuse variables for static values that never change, as it adds unnecessary complexity.
Production Patterns
In production, variables are often managed via tfvars files per environment, combined with environment variables for secrets. Modules expose variables as inputs to create reusable components. Validation rules enforce organizational policies. Variables are documented thoroughly to aid team collaboration.
Connections
Function parameters in programming
Variables in Terraform are like parameters passed to functions in code.
Understanding how functions accept inputs helps grasp how Terraform variables customize infrastructure behavior.
Configuration management (e.g., Ansible variables)
Terraform variables serve a similar role as variables in configuration management tools.
Knowing this connection helps when moving between infrastructure provisioning and configuration automation.
User input forms in web development
Terraform variables are like form fields where users input data to customize output.
This analogy helps understand the importance of validation and clear descriptions to guide correct input.
Common Pitfalls
#1Forgetting to provide a value for a variable without a default.
Wrong approach:variable "project" { type = string } # Running terraform apply without setting 'project' value
Correct approach:variable "project" { type = string } # Provide value via CLI: terraform apply -var='project=myproj' # Or via tfvars file or environment variable
Root cause:Misunderstanding that variables without defaults are required inputs.
#2Assigning a wrong type to a variable.
Wrong approach:variable "count" { type = number default = "three" }
Correct approach:variable "count" { type = number default = 3 }
Root cause:Not respecting the declared variable type causes Terraform to fail.
#3Overusing variables for values that never change.
Wrong approach:variable "region" { type = string default = "us-west-2" } # Used everywhere even when region is fixed
Correct approach:# Hardcode region in provider block if it never changes provider "aws" { region = "us-west-2" }
Root cause:Adding unnecessary variables complicates code and confuses users.
Key Takeaways
Terraform variables let you write flexible infrastructure code by defining inputs that can change without editing the code.
Declaring variable types and defaults helps prevent errors and documents expected inputs clearly.
Variables without defaults are required and must be provided during deployment to avoid errors.
Complex types and validation rules enable precise control over input data, improving reliability.
Understanding variable overrides in modules is essential for building reusable and scalable Terraform configurations.