Skip to main content
Terraform is my go-to tool for provisioning any cloud infrastructure that needs to be reproducible, reviewed, and version-controlled. These notes cover the workflow I use daily — from first init through module composition and remote state management. Code examples use AWS but the patterns apply equally to GCP and Azure by swapping the provider block.

Core Workflow

1

terraform init — initialize the working directory

Downloads provider plugins and sets up the backend. Run this once per checkout, and again whenever you add providers or change the backend config.
2

terraform fmt — format code

Standardize HCL formatting before committing. Add this to your pre-commit hooks.
3

terraform validate — check configuration syntax

Validates the configuration without accessing any remote services or state. Fast and safe to run locally.
4

terraform plan — preview changes

Shows exactly what Terraform will create, modify, or destroy. Always review this before applying.
5

terraform apply — provision resources

6

terraform destroy — tear down resources

Never run terraform apply or terraform destroy directly in production without a saved plan file reviewed in a pull request. Even terraform apply -auto-approve in CI should only run after a plan output has been reviewed and approved.

Provider Configuration

Use ~> (pessimistic constraint) for provider versions: ~> 5.0 allows 5.x but not 6.x. This protects against breaking changes in major versions while still getting patch updates automatically on init -upgrade.

Variables, Outputs, and Locals


Remote State with S3 Backend

Storing state locally is fine for learning, but any team environment needs remote state. S3 + DynamoDB is the standard AWS pattern.
1

Create the S3 bucket and DynamoDB table

Bootstrap these resources once, manually or with a separate Terraform root. Do not put the state bucket itself in the state it manages.
2

Configure the backend block

3

Reference outputs from another state (remote state data source)


Resource and Data Source Patterns


Modules

Modules let you package reusable infrastructure patterns. The standard layout for a module:

Complete Example: AWS EC2 Instance

A self-contained, working Terraform configuration for a single EC2 instance with a security group, S3 bucket, and IAM role.

Useful Commands and Tips

Use workspaces (terraform workspace new staging) for managing multiple environments from a single config, but be aware they share the same backend bucket. Many teams prefer separate state files per environment with different key paths in the S3 backend — it’s more explicit and easier to reason about access controls.

AWS Reference

AWS CLI commands and service details that pair with Terraform-provisioned infrastructure.

GCP & Azure

Apply the same Terraform patterns to GCP and Azure by swapping the provider block.

GitLab CI/CD

Automate Terraform plan and apply in CI/CD pipelines with GitLab.

FinOps & Cost Management

Tag strategy and cost allocation practices to bake into Terraform from day one.
Last modified on June 9, 2026