Skip to main content
Terraform Basics
CHAPTER 06

Variables, Outputs, and Locals

Updated: May 15, 2026
25 min read

# CHAPTER 6

Variables, Outputs, and Locals

1. Introduction

Hardcoding values—like instance_type = "t2.micro"—directly into your main.tf file is an anti-pattern. If you want to deploy the exact same architecture to a "Staging" environment (using cheap micro servers) and a "Production" environment (using massive enterprise servers), you would have to copy and paste the entire codebase and change every single line manually. This defeats the purpose of automation. In this chapter, we will learn how to make our Terraform code dynamic, flexible, and reusable by utilizing Input Variables to accept data, Output Values to return data, and Local Values to reduce repetition.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define and use Input Variables (variable block) to parameterize configurations.
  • Understand variable typing and validation.
  • Extract useful data from Terraform using Output Values (output block).
  • Utilize Local Values (locals block) to calculate and reuse internal logic.
  • Pass variables securely via .tfvars files or command-line arguments.

3. Beginner-Friendly Explanation

Imagine a coffee machine.
  • The Input Variable: The buttons on the front. Do you want "Small" or "Large"? Do you want "Dark Roast" or "Light Roast"? The machine's internal mechanics don't change, but the *inputs* change the final result.
  • The Output Value: The digital screen that says "Your coffee is ready at Spout 2." It gives you the information you need *after* the machine finishes its job.
  • The Local Value: The machine's internal memory. It calculates "Small + Dark Roast = 30 seconds of brewing." You never see this calculation; it just helps the machine stay organized internally so it doesn't have to recalculate the math every time.

4. Input Variables (variable block)

Variables are usually defined in a file named variables.tf.
hcl
123456
# Defining the variable
variable "server_size" {
  description = "The EC2 instance type"
  type        = string
  default     = "t2.micro" # Used if no value is provided
}

Now, in your main.tf, you replace the hardcoded string with the variable reference using the var. prefix:

hcl
1234
resource "aws_instance" "web" {
  ami           = "ami-12345"
  instance_type = var.server_size # Dynamic!
}

5. Output Values (output block)

When Terraform builds a server, AWS assigns it a random Public IP address. How do you find out what that IP is without logging into the AWS Console? You use an Output! Outputs are defined in outputs.tf.
hcl
1234
output "website_url" {
  description = "The public IP address of the new server"
  value       = aws_instance.web.public_ip
}

When you run terraform apply, the very last thing the terminal will print is: Outputs: website_url = "192.168.1.50"

6. Mini Project: Build Reusable Infrastructure Template

Let's use locals to create a standard naming convention for our servers, ensuring every server name includes the environment and project name.

Step-by-Step Architecture Concept:

hcl
123456789101112131415161718192021222324
# 1. Input Variables
variable "env" {
  type = string
}
variable "project" {
  type = string
}

# 2. Local Values (Internal calculations)
locals {
  # We combine the inputs to create a standard prefix: e.g., "prod-billing-"
  name_prefix = "${var.env}-${var.project}-"
}

# 3. The Resource (Using the Local)
resource "aws_instance" "app" {
  ami           = "ami-xyz"
  instance_type = "t2.micro"
  
  tags = {
    # The server will be named: "prod-billing-web-server"
    Name = "${local.name_prefix}web-server" 
  }
}

7. How to Pass Variable Values

If a variable doesn't have a default, Terraform will prompt you to type the value in the terminal when you run plan. This is annoying. The Solution: Use a .tfvars file. Create a file named terraform.tfvars:
hcl
123
env = "production"
project = "billing"
server_size = "t3.large"

Terraform automatically loads any file named terraform.tfvars and uses those values to run the code.

8. Real-World Scenarios

A company had a strict security policy requiring all cloud resources to be tagged with the department name, the environment, and the cost-center code. Developers kept forgetting to add these tags, leading to auditing nightmares. The DevOps team refactored the Terraform code using a locals block. They defined a commontags map containing all the mandatory tags based on input variables. In the resource blocks, developers simply wrote tags = local.commontags. This eliminated the repetition and ensured 100% tagging compliance across the entire infrastructure.

9. Best Practices

  • Variable Validation: You can force Terraform to reject bad inputs. In your variable block, add a validation block to ensure serversize is only allowed to be "t2.micro" or "t3.large". If a developer tries to deploy an expensive "p3.16xlarge" server, Terraform will reject the code and halt the deployment immediately.

10. Security Recommendations

  • Sensitive Variables: If an input variable is a database password, add sensitive = true to the variable block. When Terraform runs, it will mask the value as (sensitive value) in the terminal output, preventing passwords from leaking into the CI/CD logs.

11. Exercises

  1. 1. What is the syntax difference between referencing an Input Variable versus referencing a Local Value in an HCL resource block?
  1. 2. Why is using a terraform.tfvars file preferred over typing variables interactively into the terminal?

12. FAQs

Q: Can I use Environment Variables in my Linux terminal to pass data to Terraform? A: Yes! If you export an environment variable prefixed with TF
VAR, Terraform will automatically pick it up. For example, export TFVARserversize="t2.micro" will inject that value into the server_size variable in your code.

13. Interview Questions

  • Q: Differentiate the operational use cases for Input Variables (variable), Local Values (locals), and Output Values (output) within a Terraform module.
  • Q: You have a variable that accepts an API token. How do you configure the HCL to ensure this token is never printed in plain text to the console during a terraform plan execution?

14. Summary

In Chapter 6, we liberated our Terraform code from static, hardcoded values. We introduced Input Variables, allowing a single HCL template to deploy vastly different architectures based on user parameters. We explored Output Values, creating a mechanism to extract dynamically generated cloud data (like IPs and IDs) back to the terminal. Finally, we utilized Local Values to DRY up our code, centralizing complex naming conventions and tag generation. Our code is now dynamic, reusable, and ready for enterprise scale.

15. Next Chapter Recommendation

Our code is reusable, but what if we want to share our perfect "Web Server Template" with other teams in the company? Proceed to Chapter 7: Terraform Modules.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·