HashiCorp Terraform: Infrastructure as Code
Terraform enables you to safely and predictably create, change, and improve infrastructure by codifying APIs into declarative configuration files that can be shared, versioned, and reviewed.
- Step 1
What is Terraform?
Terraform is an open-source Infrastructure as Code (IaC) tool by HashiCorp that enables you to define and provision infrastructure using a declarative configuration language called HCL (HashiCorp Configuration Language). It is source-available and widely used as the de facto standard for infrastructure automation.
Unlike traditional provisioning scripts that use imperative commands, Terraform uses a declarative approach where you describe the end state of your infrastructure, and Terraform figures out how to get there.
Key concepts:
- Declarative Configuration: Define what you want with HCL files
- Providers: Plugins that interact with cloud APIs (AWS, Azure, GCP, etc.)
- Resources: The building blocks of infrastructure (servers, networks, databases)
- State Management: Terraform tracks infrastructure state in a state file
- Plan & Apply: Preview changes before applying them
- Modular Design: Reusable modules for consistent infrastructure
Core Workflow:
- Write: Define infrastructure in .tf files using HCL
- Initialize: terraform init downloads providers and plugins
- Plan: terraform plan previews changes to be made
- Apply: terraform apply creates or updates infrastructure
- Destroy: terraform destroy removes all provisioned resources
- Step 2
Technology stack and architecture
Terraform is built on Go (Golang) with a modular architecture that supports multiple cloud providers and tools through a plugin ecosystem.
Core Language & Build:
- Go 1.22+ (compiled to static binaries for all major platforms)
- Go modules for dependency management
- HashiCorp Configuration Language (HCL) as declarative DSL
- JSON format as alternative configuration syntax
Language Features:
- HCL (HashiCorp Configuration Language)
- Built-in language functions (string, list, map, conditional)
- Dynamic blocks for programmatic iteration
- Interpolation and expressions
- Resource dependencies (implicit and explicit)
Provider Ecosystem:
- 600+ official and community providers
- Plugin protocol for provider communication
- Protocol buffers (protobuf) for plugin communication
- HashiCorp Plugin SDK for provider development
State Management:
- JSON-based state file (.terraform.tfstate)
- Locking via state backends
- State backends (local, S3, Azure Blob, GCS, Consul, etc.)
- State remote locking with DynamoDB, Redis, etc.
- State isolation with workspaces
Key Dependencies:
- github.com/hashicorp/go-getter (dependency fetching)
- github.com/hashicorp/hcl/v2 (HCL parser)
- github.com/zclconf/go-cty (type system)
- github.com/hashicorp/go-plugin (plugin RPC)
- github.com/hashicorp/terraform-plugin-go (plugin protocol)
- github.com/hashicorp/terraform-plugin-sdk/v2 (provider SDK)
Architecture Overview: +-- CLI (Go) | +-- Command parsing | +-- Configuration loading | +-- User interaction +-- Core Engine | +-- Graph Builder (dependency graph) | +-- Planner (change detection) | +-- Executor (resource operations) +-- Providers (Plugins) | +-- AWS Provider | +-- Azure Provider | +-- GCP Provider | +-- 600+ more +-- State Backend (Remote/Local) | +-- S3 | +-- Azure Blob | +-- Google Cloud Storage | +-- Consul +-- Language (HCL) +-- Parser +-- Type System +-- Functions - Step 3
Installation methods
Terraform can be installed on various platforms with multiple methods.
Homebrew (macOS/Linux): brew install terraform
Official Binary (Linux): curl -L https://releases.hashicorp.com/terraform/1.9.0/terraform_1.9.0_linux_amd64.zip -o terraform.zip unzip terraform.zip sudo mv terraform /usr/local/bin/ terraform version
Snap (Linux): sudo snap install hashicorp-terraform
Chocolatey (Windows): choco install terraform
Scoop (Windows): scoop install terraform
Docker: docker run --rm -v "$(pwd)":/myconfig hashicorp/terraform:1.9.0 init
macOS with Apple Silicon (ARM64): curl -O https://releases.hashicorp.com/terraform/1.9.0/terraform_1.9.0_darwin_arm64.zip unzip terraform_1.9.0_darwin_arm64.zip sudo mv terraform /usr/local/bin/
# Homebrew (macOS/Linux) brew install terraform # Snap (Linux) sudo snap install hashicorp-terraform # Chocolatey (Windows) choco install terraform # Scoop (Windows) scoop install terraform # Docker docker run --rm -v "$(pwd)":/myconfig hashicorp/terraform:1.9.0 version # Manual (Linux x86_64) curl -L https://releases.hashicorp.com/terraform/1.9.0/terraform_1.9.0_linux_amd64.zip -o terraform.zip unzip terraform.zip sudo mv terraform /usr/local/bin/ terraform version - Step 4
Basic configuration and providers
Every Terraform configuration requires a provider block that specifies which cloud or service to interact with. Providers are plugins that implement the APIs for managing infrastructure resources.
AWS Provider Setup: terraform { required_version = ">= 1.0.0" required_providers { aws = { source = "hashicorp/aws" version = ">= 5.0" } } }
provider "aws" { region = "us-east-1" # Authentication via environment variables: # AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY }
Azure Provider Setup: provider "azurerm" { features {} subscription_id = "your-subscription-id" }
Google Cloud Provider Setup: provider "google" { project = "your-project-id" region = "us-central1" }
terraform { required_version = ">= 1.0.0" required_providers { aws = { source = "hashicorp/aws" version = ">= 5.0" } } } provider "aws" { region = "us-east-1" default_tags { tags = { Environment = "development" ManagedBy = "terraform" } } } - Step 5
Your first Terraform resource
Resources are the building blocks of infrastructure in Terraform. Each resource type represents a specific object you can manage (like an AWS EC2 instance, S3 bucket, etc.).
Basic AWS EC2 Instance: resource "aws_instance" "example_web_server" { ami = "ami-0c7217cd13ae2cb4c" instance_type = "t3.micro" tags = { Name = "example-web-server" Environment = "development" } }
Create an S3 Bucket: resource "aws_s3_bucket" "example" { bucket = "my-unique-bucket-name-12345" tags = { Name = "Example Bucket" Environment = "Development" } }
resource "aws_instance" "web_server" { ami = "ami-0c7217cd13ae2cb4c" instance_type = "t3.micro" tags = { Name = "web-server" } } resource "aws_security_group" "web_sg" { name = "web-sg" description = "Allow HTTP/HTTPS/SSH" ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } } output "public_ip" { value = aws_instance.web_server.public_ip } - Step 6
Terraform core commands
Terraform provides a consistent set of commands for managing infrastructure lifecycle.
Initialization: terraform init # Download providers terraform init -backend-config="..." # With backend
Planning: terraform plan # Preview changes terraform plan -out=tfplan # Save plan to file
Applying: terraform apply # Make changes terraform apply -auto-approve # CI mode terraform apply tfplan # Apply saved plan
Destroying: terraform destroy # Remove all resources terraform -target=aws_instance.example
Validation: terraform validate # Check syntax terraform fmt # Format code terraform fmt -check # Check without modifying
State Management: terraform state list # List resources terraform show # View state terraform import aws_instance.example i-12345678 terraform refresh # Sync state
Workspaces: terraform workspace new dev terraform workspace select dev
# Terraform CLI Workflow # 1. Initialize - download providers $ terraform init # 2. Format - style code $ terraform fmt # 3. Validate - check syntax $ terraform validate # 4. Plan - preview changes $ terraform plan # 5. Apply - make changes $ terraform apply # 6. Destroy - clean up $ terraform destroy # Workspaces terraform workspace new dev terraform workspace select dev # Debugging export TF_LOG=DEBUG terraform plan - Step 7
Remote state and collaboration
For team collaboration, Terraform uses remote backends to store state centrally. This enables state locking, versioning, and sharing.
S3 Backend with DynamoDB (AWS): terraform { backend "s3" { bucket = "my-terraform-state-bucket" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-state-lock" } }
Azure Blob Backend: terraform { backend "azurerm" { resource_group_name = "terraform-state-rg" storage_account_name = "mystatestorage" container_name = "tfstate" key = "prod.terraform.tfstate" } }
Google Cloud Storage Backend: terraform { backend "gcs" { bucket = "my-terraform-state-bucket" prefix = "prod/terraform.tfstate" } }
Remote State References: data "terraform_remote_state" "production" { backend = "s3" config = { bucket = "my-terraform-state-bucket" key = "prod/terraform.tfstate" region = "us-east-1" } }
resource "aws_security_group" "web" { vpc_id = data.terraform_remote_state.production.vpc_id }
terraform { backend "s3" { bucket = "my-terraform-state-bucket" key = "prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-state-lock" } required_version = ">= 1.0.0" required_providers { aws = { source = "hashicorp/aws" version = ">= 5.0" } } } - Step 8
Modules for reusability
Modules are reusable Terraform configurations that package resources together. They enable modular design patterns, code reuse, and consistent infrastructure patterns.
Module Structure: mymodule/ +-- main.tf # Module resources +-- variables.tf # Input variables +-- outputs.tf # Output values +-- versions.tf # Terraform & provider versions
Using a Module: module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "3.0.0" 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"] }
Local Module: module "local" { source = "./modules/vpc" }
GitHub Module: module "vpc" { source = "github.com/hashicorp/example-terraform-aws-vpc//modules/vpc?ref=v2.0.0" }
resource "aws_vpc" "main" { cidr_block = var.cidr enable_dns_hostnames = true tags = { Name = var.name } } resource "aws_subnet" "public" { count = 2 vpc_id = aws_vpc.main.id cidr_block = cidrsubnet(var.cidr, 8, count.index + 1) availability_zone = var.availability_zones[count.index] tags = { Name = "${var.name}-public-${count.index + 1}" } } # Using the module module "production_vpc" { source = "./modules/vpc" name = "production" cidr = "10.0.0.0/16" } - Step 9
State management best practices
Terraform state is the central record of your infrastructure. Proper state management is critical for security, reliability, and collaboration.
State Security:
- Store state remotely (S3, Azure, GCS) - NOT locally
- Enable encryption at rest
- Restrict IAM access to state files
- Version your state files
- Enable state locking to prevent concurrent modifications
State Commands: terraform state list # List resources terraform show # Show state terraform state mv # Move resources terraform state rm # Remove from state terraform refresh # Sync state terraform import # Import existing resources
Workspaces for Isolation: terraform workspace new dev terraform workspace new staging terraform workspace new prod
Backup Strategy:
- Regular state exports: terraform show -json > backup.json
- Enable versioning in S3 backend
- Document state structure for disaster recovery
# State Management Commands $ terraform state list $ terraform show $ terraform refresh $ terraform state mv aws_instance.old aws_instance.new $ terraform state rm aws_instance.example $ terraform import aws_instance.example i-12345678 $ terraform taint aws_instance.example $ terraform workspace list $ terraform workspace new staging $ terraform workspace select staging - Step 10
Common use cases and patterns
Terraform is widely used across cloud infrastructure for various patterns and scenarios.
Cloud Infrastructure Deployment: module "networking" { source = "terraform-aws-modules/vpc/aws" } module "compute" { source = "terraform-aws-modules/autoscaling/aws" } module "database" { source = "terraform-aws-modules/rds/aws" }
Infrastructure as Code Pipeline:
- GitOps repository with Terraform code
- CI/CD validates syntax (terraform fmt, validate)
- Plan review in PR comments
- Apply on merge (or approved changes)
- Auto-destroy test resources
GitOps Integration:
- Store Terraform in Git
- Use Terraform Cloud for remote state
- PR-based change proposals
- Automated plan/apply workflows
# Multi-environment pattern module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "3.0.0" name = var.environment cidr = var.vpc_cidr private_subnets = var.private_subnets public_subnets = var.public_subnets azs = var.azs enable_nat_gateway = true } module "web_app" { source = "./modules/web-app" environment = var.environment vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.public_subnet_ids } - Step 11
Resources and documentation
Official Resources:
- Website: https://developer.hashicorp.com/terraform
- Documentation: https://www.terraform.io/docs
- Registry: https://registry.terraform.io
- Terraform Cloud: https://www.terraform.io/cloud
- GitHub: https://github.com/hashicorp/terraform
- Learning: https://learn.hashicorp.com/terraform
Popular Providers:
- AWS: https://registry.terraform.io/providers/hashicorp/aws
- Azure: https://registry.terraform.io/providers/hashicorp/azurerm
- Google Cloud: https://registry.terraform.io/providers/hashicorp/google
- Kubernetes: https://registry.terraform.io/providers/hashicorp/kubernetes
- Docker: https://registry.terraform.io/providers/kreuzwerker/docker
Learning Resources:
- HashiCorp Learn - Free courses
- Terraform Up & Running (Book)
- Terraform Community Forums
- Terraform Provider Documentation
License: Business Source License 1.1 (source-available)
Community:
- HashiCorp Discuss Forum
- r/terraform on Reddit
- HashiCorp Slack Community
- Stack Overflow (tag: terraform)
Security Considerations:
- Never store secrets in state or code
- Use environment variables or Vault for secrets
- Enable state encryption
- Implement state access controls
- Review provider policies for sensitive data handling
Official Website: https://developer.hashicorp.com/terraform Documentation: https://www.terraform.io/docs Registry: https://registry.terraform.io GitHub: https://github.com/hashicorp/terraform Learning: https://learn.hashicorp.com/terraform AWS Provider: https://registry.terraform.io/providers/hashicorp/aws Azure Provider: https://registry.terraform.io/providers/hashicorp/azurerm GCP Provider: https://registry.terraform.io/providers/hashicorp/google Kubernetes: https://registry.terraform.io/providers/hashicorp/kubernetes Forum: https://discuss.hashicorp.com Stack Overflow: terraform tag License: Business Source License 1.1
Feature requests
Sign in to suggest features or vote on existing ones.
No feature requests yet.
Discussion
Sign in to join the discussion.
No comments yet.