Terraform Infrastructure as Code
Learn how to define, provision, and manage cloud infrastructure using Terraform with reusable modules and best practices.
DevOpsAdvanced22 min read
AI Summary
Quick context for Terraform Infrastructure as Code
Terraform Infrastructure as Code is a advanced guide in DevOps. Learn how to define, provision, and manage cloud infrastructure using Terraform with reusable modules and best practices.. Key topics: cloud, iac, infrastructure, terraform.
## What is Infrastructure as Code?
Infrastructure as Code (IaC) allows you to define and manage infrastructure through configuration files instead of manual processes. Terraform, created by HashiCorp, is the leading IaC tool for provisioning and managing cloud resources across multiple providers.
Terraform uses a declarative approach: you describe the desired end state of your infrastructure, and Terraform determines the steps needed to reach that state.
## Installing and Configuring Terraform
After installing Terraform, configure your first provider. The AWS provider is the most common, but Terraform supports Azure, GCP, Kubernetes, and hundreds of others.
```hcl
# main.tf
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
provider "aws" {
region = var.aws_region
}
```
The backend configuration stores state remotely in S3 with DynamoDB locking to prevent concurrent modifications.
## Defining Resources
Resources are the building blocks of Terraform configurations. Each resource represents an infrastructure component.
```hcl
# variables.tf
variable "aws_region" {
description = "AWS region for resource deployment"
type = string
default = "us-east-1"
}
variable "vpc_cidr" {
description = "CIDR block for the VPC"
type = string
default = "10.0.0.0/16"
}
variable "environment" {
description = "Environment name (dev, staging, production)"
type = string
validation {
c "staging", "production"], var.environment)
error_message = "Environment must be dev, staging, or production."
}
}
```
```hcl
# vpc.tf
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.environment}-vpc"
Envir
ManagedBy = "terraform"
}
}
resource "aws_subnet" "public" {
count = 3
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index)
availability_z
map_public_ip_
tags = {
Name = "${var.environment}-public-${count.index}"
Tier = "public"
}
}
```
## Using Modules
Modules let you encapsulate and reuse infrastructure patterns. A well-structured module can be shared across projects and teams.
```hcl
# modules/ecs-service/main.tf
variable "service_name" {
type = string
}
variable "image" {
type = string
}
variable "cpu" {
type = number
default = 256
}
variable "memory" {
type = number
default = 512
}
resource "aws_ecs_task_definition" "app" {
family = var.service_name
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = var.cpu
memory = var.memory
c
{
name = var.service_name
image = var.image
essential = true
portMappings = [
{
c
hostPort = 3000
}
]
}
])
}
resource "aws_ecs_service" "app" {
name = var.service_name
cluster = var.cluster_id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 2
launch_type = "FARGATE"
}
```
## Outputs and Data Sources
Outputs expose values from your configuration for use by other modules or for reference. Data sources let you query existing infrastructure.
```hcl
# outputs.tf
output "vpc_id" {
description = "ID of the created VPC"
value = aws_vpc.main.id
}
output "public_subnet_ids" {
description = "IDs of public subnets"
value = aws_subnet.public[*].id
}
```
```hcl
# data.tf
data "aws_availability_zones" "available" {
state = "available"
}
data "aws_caller_identity" "current" {}
locals {
account_id = data.aws_caller_identity.current.account_id
}
```
## State Management
Terraform state tracks the relationship between your configuration and real infrastructure. Treat state files as sensitive—they contain infrastructure metadata and sometimes secrets.
- Store state remotely with encryption at rest
- Enable state locking to prevent race conditions
- Use workspaces to manage multiple environments from the same configuration
- Never commit state files to version control
## Best Practices
- **Pin provider versions** to avoid unexpected breaking changes
- **Use variables and locals** to reduce duplication
- **Plan before applying** with `terraform plan` to review changes
- **Tag all resources** for cost tracking and organizational clarity
- **Keep modules focused** on a single concern
- **Use `.tfvars` files** for environment-specific values and exclude them from git
## Workflow Summary
1. `terraform init` — Initialize the working directory and download providers
2. `terraform plan` — Preview changes before applying
3. `terraform apply` — Provision the infrastructure
4. `terraform destroy` — Tear down resources when no longer needed
Continue with related content
Suggested next reads and tools from the knowledge graph.