DevOps.Academy
CoursesCurriculumPricing

    Loading…

    ↑ ↓ move · ↵ open · Ctrl K anywhere

    ◔My learningSign in
    Join the waitlist
    DevOps.Academy

    Free, hands-on DevOps lessons. Made with care in India.

    Learn

    All coursesLinux roadmapCurriculumMy learning

    Academy

    PricingCertificates

    Legal

    PrivacyTermsContact

    devops.rajeev.pro

    TerraformLesson 1 of 16
    Your progress · 0%
    On this page
    1. Why clicking in the console doesn't scale
    2. Infrastructure as code
    3. How Terraform works
    4. What teams use it for
    5. Terraform vs Ansible
    6. Install it and run your first plan
    ↖ Course roadmap
    Lesson 1 · Introduction

    Infrastructure as code, and where Terraform fits

    Why clicking in the console stops working, what infrastructure as code gives you, how Terraform works, how it differs from Ansible, and your first plan and apply.

    25 min read · intermediate · hands-on

    By the end of this lesson you'll be able to

    0 of 5 complete

    Why clicking in the console doesn't scale

    The first server is easy: open the AWS console, click through the wizard, done. Six months later you have 40 resources, and:

    • Nobody remembers which settings staging was built with, so production is "almost the same".
    • Rebuilding after a bad day means following a wiki page that's three changes out of date.
    • A security group was opened "just for a minute" in March, and it's still open.
    • There's no review: one wrong click goes straight to production, and there's no history of who did it.

    None of that is anyone's fault. It's what happens when the only record of your infrastructure is the infrastructure itself.

    Infrastructure as code

    Infrastructure as code (IaC) means describing servers, networks, databases and permissions in text files, and letting a tool create them from those files. The files live in Git, next to the app. That gives you four things:

    1. Repeatable. Run the same code and get the same environment, for staging, production or a new region.
    2. Reviewed. A change is a pull request. Teammates read it, and CI checks it, before it touches anything real.
    3. Versioned. git log tells you who changed the firewall, when and why, and git revert takes it back.
    4. Documented. The code is always an up-to-date description of what exists.

    Most IaC tools are declarative: you describe the end result ("one bucket, versioning on"), not the steps. The tool works out what to create, change or delete to get there.

    How Terraform works

    Terraform is the most widely used IaC tool. You write configuration in HCL, a readable language made of blocks, and Terraform talks to cloud APIs for you.

    Write, init, plan, apply. The state file is how Terraform remembers what it built.© Diagram: DevOps Academy

    Write, init, plan, apply. The state file is how Terraform remembers what it built.© Diagram: DevOps Academy
    PieceWhat it does
    ConfigurationYour .tf files: the resources you want
    ProvidersPlugins that know one API: AWS, Azure, Google Cloud, Kubernetes, GitHub and hundreds more
    Stateterraform.tfstate: which real object each resource in your code belongs to
    PlanA preview of every create, change and destroy, before anything happens
    ApplyMakes the plan real through the provider, then updates the state

    The workflow is the same for every provider, which is the main reason Terraform spread: learn it once for AWS and you can manage DNS, GitHub repos or Kubernetes the same way.

    Terraform or OpenTofu?

    In 2023 HashiCorp moved Terraform from an open-source licence to the Business Source Licence. The community forked it as OpenTofu, now a Linux Foundation project. The two use the same language and workflow, and everything in this course works in both: swap terraform for tofu.

    What teams use it for

    • Building whole environments in the cloud: networks, servers, load balancers, databases.
    • Creating the same setup in several regions or accounts from one module.
    • Managing things around the cloud, too: DNS records, monitoring alerts, GitHub repositories and team permissions.
    • Short-lived environments: a full copy of the stack for each pull request, destroyed when it merges.

    Terraform vs Ansible

    People often ask "Terraform or Ansible?" They mostly do different jobs:

    Terraform (provisioning)Ansible (configuration management)
    BuildsThe infrastructure: VMs, networks, bucketsWhat's inside a server: packages, files, services
    Works throughCloud and service APIsSSH into existing machines
    StyleDeclarative, with a state fileOrdered tasks in playbooks, no state file
    Typical use"Create 3 VMs, a load balancer and a database""Install nginx, write its config, restart it"

    A common split: Terraform creates the servers, and Ansible, cloud-init or a pre-built image sets them up. With containers, there's often nothing left to configure inside the server at all.

    Install it and run your first plan

    # Ubuntu / Debian: add HashiCorp's signed package repository, then install
    $ wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
    $ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
    $ sudo apt update && sudo apt install terraform
    
    # macOS
    $ brew tap hashicorp/tap && brew install hashicorp/tap/terraform
    
    $ terraform version
    Terraform v1.x.x          # your version will be newer or older; any recent 1.x works
    
    wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
    • wgetdownload a file
    • -Osave to this file (- = print it)
    • -the previous directory
    • https://apt.releases.hashicorp.com/gpga URL
    • |pipe: send output to the next command
    • sudorun the next command as root
    • gpgencrypt, sign and manage keys
    • --dearmorconvert a key to binary
    • -ooutput file
    • /usr/share/keyrings/hashicorp-archive-keyring.gpga path
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
    • echoprint text
    • "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main"text, kept together by the quotes
    • |pipe: send output to the next command
    • sudorun the next command as root
    • teewrite input to a file and pass it on
    • /etc/apt/sources.list.d/hashicorp.lista path
    sudo apt update && sudo apt install terraform
    • sudorun the next command as root
    • aptDebian/Ubuntu package manager
    • updatea value the command works on
    • &&run the next command only if this one worked
    • sudorun the next command as root
    • aptDebian/Ubuntu package manager
    • installa value the command works on
    • terraforma value the command works on
    brew tap hashicorp/tap && brew install hashicorp/tap/terraform
    • brewmacOS package manager
    • tapa value the command works on
    • hashicorp/tapa value the command works on
    • &&run the next command only if this one worked
    • brewmacOS package manager
    • installa value the command works on
    • hashicorp/tap/terraforma value the command works on
    terraform version
    • terraforminfrastructure as code
    • versionprint the version

    Your first configuration doesn't need a cloud account. The local provider manages files on your own machine, which is perfect for learning the workflow:

    # ~/tf-hello/main.tf
    terraform {
      required_providers {
        local = {
          source  = "hashicorp/local"
          version = "~> 2.9"
        }
      }
    }
    
    resource "local_file" "hello" {
      filename = "${path.module}/hello.txt"
      content  = "Built by Terraform"
    }
    
    $ cd ~/tf-hello
    $ terraform init               # downloads the providers into .terraform/
    Terraform has been successfully initialized!
    $ terraform plan
      # local_file.hello will be created
      + resource "local_file" "hello" {
          + content  = "Built by Terraform"
          + filename = "./hello.txt"
          ...
        }
    
    Plan: 1 to add, 0 to change, 0 to destroy.
    $ terraform apply              # shows the plan again and waits for you to type yes
    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
    $ cat hello.txt
    Built by Terraform
    
    cd ~/tf-hello
    • cdchange directory
    • ~/tf-helloa path
    terraform init
    • terraforminfrastructure as code
    • initdownload providers, set up the folder
    terraform plan
    • terraforminfrastructure as code
    • planpreview changes
    terraform apply
    • terraforminfrastructure as code
    • applymake the changes
    cat hello.txt
    • catprint a file
    • hello.txta value the command works on

    Read every plan before you apply it. The last line, Plan: 1 to add, 0 to change, 0 to destroy, is the one to check first: an unexpected number in the destroy column is how outages start.

    State holds secrets

    terraform.tfstate can contain passwords and keys in plain text. Never commit it to Git. Add .terraform/, *.tfstate and *.tfstate.* to .gitignore in every Terraform project. The State stage shows how teams store it remotely, encrypted and locked.

    In production

    Once Terraform manages something, change it only through Terraform. Teams run terraform plan on every pull request and apply only from the pipeline after merge, so every change is reviewed and recorded.

    ⌘
    Mini mission

    Let Terraform repair what you broke

    Terraform manages ~/tf-hello/hello.txt. Someone deletes it by hand. Use Terraform to notice the drift and put the file back, without editing main.tf.

    Input: ~/tf-hello/main.tf from this lesson, already appliedOutput: ~/tf-hello/hello.txt
    Reveal one safe solution
    $ cd ~/tf-hello
    $ rm hello.txt                     # the "manual change"
    $ terraform plan
      # local_file.hello will be created
    ...
    Plan: 1 to add, 0 to change, 0 to destroy.
    $ terraform apply -auto-approve
    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
    $ cat hello.txt
    Built by Terraform
    
    cd ~/tf-hello
    • cdchange directory
    • ~/tf-helloa path
    rm hello.txt
    • rmdelete files, with no undo
    • hello.txta value the command works on
    terraform plan
    • terraforminfrastructure as code
    • planpreview changes
    terraform apply -auto-approve
    • terraforminfrastructure as code
    • applymake the changes
    • -auto-approveskip the yes prompt
    cat hello.txt
    • catprint a file
    • hello.txta value the command works on

    Before planning, Terraform refreshes what it knows from the real world, sees the file is missing, and plans to recreate it. That's drift detection, and on a real cloud account it's how you catch the security group someone opened by hand. Use -auto-approve only when you have just read the plan yourself.

    Try it yourself

    0 of 6 steps done

    Run each task in your own account or terminal, then tick it off.

    Knowledge check

    Quick check

    Question 1 of 4

    What does terraform plan do?

    Go deeper

    Official reading for this lesson

    • DocsWhat is Terraform?HashiCorp ↗
    • GuideInstall TerraformHashiCorp ↗
    • DocsThe Terraform languageHashiCorp ↗
    • Docsterraform initHashiCorp ↗
    • DocsThe local providerTerraform Registry ↗
    • ArticleInfrastructure as codeMartin Fowler ↗
    • ToolOpenTofu, the open-source forkOpenTofu ↗

    Or get every quiz answer right and it completes itself.

    Next lesson →HCL