Terraform
Terraform Basics and Best Practices
This page covers Terraform fundamentals, best practices, essential commands, and deployment examples for AWS.
Introduction
Terraform is an Infrastructure as Code (IaC) tool used to provision, manage, and automate cloud infrastructure. It enables declarative configuration, making infrastructure deployments more reliable and consistent.
Best Practices
1. Use Remote Backend for State Management
Terraform stores state to track infrastructure changes. A remote backend (e.g., S3 + DynamoDB) ensures consistency and team collaboration.
Example (`backend.tf`): <source lang="hcl"> terraform {
backend "s3" { bucket = "my-terraform-state" key = "envs/prod/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-lock" encrypt = true }
} </source>
2. Use Modules for Reusability
Organizing infrastructure as modules makes it easier to maintain and reuse components.
Example Directory Structure:
terraform/ ├── modules/ │ ├── vpc/ │ ├── ec2/ │ ├── rds/ │ ├── s3/ ├── environments/ │ ├── dev/ │ ├── prod/ │ ├── test/
3. Use Workspaces for Multi-Environment Management
Workspaces allow Terraform to manage multiple environments within the same configuration.
Commands: <source lang="bash"> terraform workspace new dev terraform workspace select dev terraform apply </source>
4. Secure Secrets and Sensitive Data
Use Terraform variables with `sensitive = true` and AWS Secrets Manager.
Example (`variables.tf`): <source lang="hcl"> variable "db_password" {
description = "Database password" type = string sensitive = true
} </source>
Essential Terraform Commands
These commands are used in most Terraform workflows.
Initialization: <source lang="bash"> terraform init </source>
Plan the deployment: <source lang="bash"> terraform plan -var="aws_region=us-east-1" </source>
Apply changes: <source lang="bash"> terraform apply -var="aws_region=us-east-1" -auto-approve </source>
Check Terraform state: <source lang="bash"> terraform state list </source>
Destroy resources: <source lang="bash"> terraform destroy -var="aws_region=us-east-1" -auto-approve </source>
Deploying an AWS VPC
This example provisions a VPC with public and private subnets.
VPC Module (`vpc.tf`): <source lang="hcl"> module "vpc" {
source = "./modules/vpc"
vpc_name = "prod-vpc" cidr_block = "10.0.0.0/16" public_subnets = ["10.0.1.0/24", "10.0.2.0/24"] private_subnets = ["10.0.3.0/24", "10.0.4.0/24"]
} </source>
VPC Module (`modules/vpc/main.tf`): <source lang="hcl"> resource "aws_vpc" "main" {
cidr_block = var.cidr_block tags = { Name = var.vpc_name }
} </source>
Variables (`modules/vpc/variables.tf`): <source lang="hcl"> variable "vpc_name" { type = string } variable "cidr_block" { type = string } variable "public_subnets" { type = list(string) } variable "private_subnets" { type = list(string) } </source>
Deploying a Terraform CI/CD Pipeline
A Terraform CI/CD pipeline ensures consistent and automated deployments. This example uses AWS CodePipeline.
Pipeline Stages:
- Source – Fetch Terraform code from Bitbucket.
- Plan – Run `terraform plan`.
- Approve – Manual approval for `prod`.
- Apply – Run `terraform apply`.
Pipeline Definition (`pipeline.tf`): <source lang="hcl"> resource "aws_codepipeline" "terraform_pipeline" {
name = "terraform-deploy" role_arn = aws_iam_role.pipeline_role.arn
artifact_store { location = "my-codepipeline-bucket" type = "S3" }
stage { name = "Source" action { name = "FetchSource" category = "Source" owner = "AWS" provider = "CodeCommit" version = "1" configuration = { RepositoryName = "terraform-repo", BranchName = "main" } output_artifacts = ["source_output"] } }
stage { name = "Plan" action { name = "TerraformPlan" category = "Build" owner = "AWS" provider = "CodeBuild" version = "1" input_artifacts = ["source_output"] configuration = { ProjectName = aws_codebuild_project.terraform_plan.name } } }
stage { name = "Approve" action { name = "ManualApproval" category = "Approval" owner = "AWS" provider = "Manual" version = "1" } }
stage { name = "Apply" action { name = "TerraformApply" category = "Build" owner = "AWS" provider = "CodeBuild" version = "1" input_artifacts = ["source_output"] configuration = { ProjectName = aws_codebuild_project.terraform_apply.name } } }
} </source>
Security Best Practices
- Enable AWS Config & GuardDuty – Monitor changes and security threats.
- Encrypt sensitive data – Use AWS KMS for encrypting resources.
- Use private subnets – Keep sensitive resources off the public internet.
- Use IAM roles with least privilege access.
Conclusion
By following these Terraform best practices for AWS, you ensure a secure, scalable, and efficient infrastructure. Keep your Terraform setup modular, automated, and well-documented.
---
Retrieved from your Terraform Wiki