Terraform Intermediate: State, Variables & Modules¶
In this guide, we'll move beyond simple resources and explore how to make your Terraform code reusable, configurable, and robust.
1. Variables (variables.tf)¶
Hardcoding values is bad practice. Variables allow you to parameterize your configuration.
Defining Variables¶
Create a variables.tf file:
variable "filename" {
description = "The name of the file to create"
type = string
default = "default.txt"
}
variable "content" {
type = string
default = "Hello World"
}
Using Variables¶
Update your main.tf:
resource "local_file" "example" {
filename = var.filename
content = var.content
}
Passing Values¶
You can set values in multiple ways (priority order):
1. CLI flags: -var="filename=my-file.txt"
2. terraform.tfvars file:
filename = "prod-config.txt"
content = "This is production configuration."
TF_VAR_filename="env-file.txt"
4. Defaults (defined in variable block).
2. Outputs (outputs.tf)¶
Outputs are like return values for your Terraform project. They print useful information to the CLI after an apply.
Create outputs.tf:
output "file_id" {
value = local_file.example.id
}
After terraform apply, you will see:
Outputs:
file_id = "7c1d..."
3. Data Sources¶
Data sources allow you to read information that was created outside of Terraform or by another Terraform configuration.
Example: finding the latest Ubuntu AMI in AWS.
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
}
4. Terraform State (terraform.tfstate)¶
The state file maps your real-world resources to your configuration.
- Local State: Stored by default in
terraform.tfstateon your machine. Not recommended for teams. - Remote State: Stored in a remote backend like S3, Azure Blob Storage, or Terraform Cloud.
Configuring Remote State (S3 Example)¶
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "dev/terraform.tfstate"
region = "us-east-1"
}
}
terraform init) after adding a backend configuration.
5. Modules¶
Modules are containers for multiple resources that are used together. Every Terraform configuration has at least one module, known as the root module.
Consuming a Public Module¶
The Terraform Registry hosts thousands of pre-built modules.
Example: Creating a VPC using the official AWS module.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
}
What's Next?¶
Ready for the pro level? We'll dive into workspaces, loops, and advanced state management.
๐ Go to Advanced Guide
๐ฌ DevopsPilot Weekly โ Learn DevOps, Cloud & Gen AI the simple way.
๐ Subscribe here