Skip to main content

Command Palette

Search for a command to run...

Understanding Terraform Variables: Input, Local, and Output Variables with a Practical AWS S3 Demo

Updated
โ€ข5 min readโ€ขView as Markdown
Understanding Terraform Variables: Input, Local, and Output Variables with a Practical AWS S3 Demo

๐Ÿšจ If you're learning Terraform, stop focusing only on resources and providers for a moment.

One of the most important concepts that makes Terraform reusable, scalable, and production-ready is Variables.

In this hands-on exercise, I explored the three types of variables available in Terraform:

  • Input Variables

  • Local Variables

  • Output Variables

To understand them better, I created a simple AWS S3 bucket and used all three variable types in a single Terraform configuration.


Why Variables Matter in Terraform

Imagine hardcoding every bucket name, environment name, region, and resource configuration inside your Terraform files.

It may work for a small demo, but it quickly becomes difficult to maintain when managing multiple environments such as:

  • Development

  • Staging

  • Production

Variables help us write reusable and flexible infrastructure code that can be deployed across different environments without changing the core configuration.


Types of Variables in Terraform

1. Input Variables

Input variables are similar to function parameters in programming.

They allow users to provide values without modifying Terraform code.

Example:

variable "environment" {
  description = "The environment to deploy to"
  type        = string
  default     = "dev"
}

In this example, the default environment is set to dev, but it can be overridden using tfvars files, environment variables, or command-line arguments.


2. Local Variables

Local variables help compute values internally and avoid repeating code.

Example:

locals {
  Environment = var.environment
  Project     = "Terraform-Demo"
}

Instead of repeating values throughout the configuration, local variables provide a centralized place for reusable logic.


3. Output Variables

Output variables act like return values from a function.

They display useful information after Terraform creates or updates infrastructure.

Example:

output "s3_bucket_name" {
  value = aws_s3_bucket.sample.bucket
}

Outputs are especially useful when sharing resource information with other Terraform configurations or CI/CD pipelines.


Hands-On Demo

For this demo, I configured:

  • AWS Provider

  • Remote Backend using S3

  • Input Variables

  • Local Variables

  • Output Variables

  • AWS S3 Bucket

Terraform Configuration

terraform {

  backend "s3" {
    bucket = "tf-state-bucket-1212"
    key    = "dev/terraform.tfstate"
    region = "us-east-1"
    encrypt = true
    use_lockfile = true
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

variable "environment" {
  description = "The environment to deploy to"
  type        = string
  default     = "dev"
}

locals {
  Environment = var.environment
  Project     = "Terraform-Demo"
}

variable "bucket_name" {
  description = "S3 bucket name"
  type        = string
  default     = "variable-bucket-1212"
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "sample" {
  bucket = var.bucket_name

  tags = {
    Environment = local.Environment
  }
}

output "s3_bucket_name" {
  value = aws_s3_bucket.sample.bucket
}

output "s3_environment" {
  value = aws_s3_bucket.sample.tags["Environment"]
}

Commands Practiced

During the lab, I executed the following commands:

terraform apply --auto-approve

terraform plan -var="environment=production"

terraform output

Output Verification

Terraform Apply

tf apply --auto-approve

aws_s3_bucket.sample: Refreshing state... [id=variable-bucket-1212]

Changes to Outputs:
  + s3_environment = "dev"

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

s3_bucket_name = "variable-bucket-1212"
s3_environment = "dev"

Terraform detected that the bucket already existed in the state and only updated the output values.


Testing Variable Override

Command executed:

terraform plan -var="environment=production"

Output:

Plan: 0 to add, 1 to change, 0 to destroy.

Changes to Outputs:
  ~ s3_environment = "dev" -> "production"

This demonstrates Terraform's variable precedence mechanism.

The command-line value successfully overrides the default variable value.


Viewing Outputs

Command:

terraform output

Output:

s3_bucket_name = "variable-bucket-1212"
s3_environment = "dev"

This confirms the values currently stored in Terraform state.


Understanding Variable Precedence

One of the most important concepts I learned was Terraform's variable precedence order.

Terraform resolves values in the following order:

  1. Command Line Variables (-var)

  2. terraform.tfvars

  3. Environment Variables (TF_VAR_)

  4. Default Values

Example:

terraform plan -var="environment=production"

This overrides all other values because command-line arguments have the highest precedence.


Key Takeaways

โœ” Input Variables make configurations reusable

โœ” Local Variables help compute and reuse values internally

โœ” Output Variables expose useful deployment information

โœ” Variables reduce hardcoding and improve maintainability

โœ” Command-line variables have the highest precedence

โœ” Outputs are useful for integrations and automation pipelines

โœ” Terraform configurations become significantly more scalable when variables are used correctly


Conclusion

This hands-on exercise helped me understand how Terraform variables work together to create flexible and reusable infrastructure code.

Although the demo used only a single S3 bucket, the same concepts are heavily used in real-world Terraform projects involving VPCs, EC2 instances, EKS clusters, RDS databases, and multi-environment deployments.

The official Terraform documentation and YouTube hands-on tutorials helped me understand these concepts and practice them effectively.

My next focus will be exploring more advanced Terraform concepts such as modules, state management techniques, and scalable infrastructure design patterns.


Connect with me on LinkedIn: https://www.linkedin.com/in/devops-samarjeet/

More from this blog

Sam's blog

56 posts