TechSetupGuides
Intermediateterraforminfrastructure-as-codeiacdevopscloudhashicorpawsazuregcpgolangautomationprovisioningdeployment

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.

  1. 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:

    1. Write: Define infrastructure in .tf files using HCL
    2. Initialize: terraform init downloads providers and plugins
    3. Plan: terraform plan previews changes to be made
    4. Apply: terraform apply creates or updates infrastructure
    5. Destroy: terraform destroy removes all provisioned resources
  2. 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
  3. 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
  4. 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"
        }
      }
    }
  5. 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
    }
  6. 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
  7. 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"
        }
      }
    }
  8. 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"
    }
  9. 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
  10. 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:

    1. GitOps repository with Terraform code
    2. CI/CD validates syntax (terraform fmt, validate)
    3. Plan review in PR comments
    4. Apply on merge (or approved changes)
    5. 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
    }
  11. 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

0 people marked this as worked·Sign in to mark your own.

Sign in to join the discussion.

No comments yet.