ad4469dc-7beb-4b7f-90b1-7de.../docs/04_variables_tfvars_outputs.md

4.7 KiB
Raw Blame History

4) Variables, tfvars & Outputs (20 min)

In this section, youll parameterize your Terraform configuration so its flexible across environments (like dev and prod) and learn how to print useful values after deployment.

Why variables and tfvars?

  • Variables let you avoid hardcoding values (e.g., instance type, names).
  • .tfvars files store a specific set of variable values for each environment. You can switch environments quickly without editing code.
  • Outputs print important information (IDs, IPs, AZs) for later use in scripts, CD pipelines, or as inputs to other modules.

Step 1: Create a working directory

mkdir -p ~/terraform-vars-lab && cd ~/terraform-vars-lab

Creates a clean folder for this exercise and moves into it.

Step 2: Define variables

Create a file variables.tf:

variable "instance_type" {}
variable "instance_name" {}
  • Declares two variables, instance_type and instance_name.
  • No defaults are provided, so Terraform will expect values (either via -var flags, .tfvars files, or prompts).

Tip: You can add descriptions and types to make your code self-documenting:

variable "instance_type" { type = string, description = "EC2 size, e.g. t2.micro" }
variable "instance_name" { type = string, description = "Tag: Name for the instance" }

Step 3: Write the main configuration

Create main.tf:

provider "aws" { region = "ap-south-1" }

resource "aws_instance" "ec2_instance" {
  ami           = "ami-0e6329e222e662a52"
  instance_type = var.instance_type

  tags = { Name = var.instance_name }
}
  • provider "aws": points Terraform to AWS in the Mumbai region.
  • resource "aws_instance" "ec2_instance": creates an EC2 instance.
    • ami: the base OS image (Amazon Linux 2 for ap-south-1).
    • instance_type: references your variable using var.instance_type.
    • tags: uses var.instance_name so the tag can change per environment.

Step 4: Expose useful outputs

Create outputs.tf:

output "instance_id"       { value = aws_instance.ec2_instance.id }
output "public_ip"         { value = aws_instance.ec2_instance.public_ip }
output "availability_zone" { value = aws_instance.ec2_instance.availability_zone }
  • After apply, Terraform will print these values.
  • Great for quickly finding the instance or for handing values to other tools.

Tip: Add sensitive = true to hide secrets in logs:

output "db_password" { value = var.db_password, sensitive = true }

Step 5: Create environment files (tfvars)

Create dev.tfvars:

instance_type = "t2.micro"
instance_name = "Dev-Instance"

Create prod.tfvars:

instance_type = "t3.micro"
instance_name = "Prod-Instance"
  • These files define different values for the same variables.
  • You can add more environments (e.g., test.tfvars, staging.tfvars) as needed.

Tip: Keep environment files in version control, but never commit secrets. For secrets, use a secure tool (e.g., AWS SSM Parameter Store, Vault) or CI/CDcontrolled variables.

Step 6: Initialize, apply, output, and switch environments

terraform init
  • Downloads provider plugins and prepares the working directory.
terraform apply -var-file="dev.tfvars" -auto-approve
  • Applies with dev values.
  • Creates a t2.micro instance named Dev-Instance.
terraform output
  • Prints the values from outputs.tf to the terminal (instance id, public IP, AZ).
terraform destroy -auto-approve
  • Destroys the dev instance to avoid charges before testing prod.
terraform apply -var-file="prod.tfvars" -auto-approve
  • Applies with prod values.
  • Creates a t3.micro instance named Prod-Instance.
terraform output -json > output.json
cat output.json
  • Exports outputs in JSON format, perfect for automation pipelines.
  • output.json can be parsed by scripts or downstream systems.

Common gotchas & best practices

  • Keep AMIs per region: AMI IDs are regionspecific. If you change regions, update the AMI.
  • Validate before apply: Run terraform validate and terraform plan to catch mistakes early.
  • Naming: Tags are your friend. Use Name tags consistently so you can find resources fast.
  • Separate state: For real projects, use separate state/workspaces or remote backends (S3 + DynamoDB) per environment.

Wrap-Up

You now know how to:

  • Declare variables and pass values with .tfvars
  • Reuse the same code for multiple environments
  • Surface key information using outputs
  • Export outputs to JSON for automation

This pattern is the backbone of scalable Terraform projects.