BeginnerCloud & Security 6 min read

What Is Terraform? Infrastructure as Code Explained

Provision cloud infrastructure declaratively with Terraform's IaC approach.

Terraform is an open-source Infrastructure as Code (IaC) tool created by HashiCorp that allows you to define and provision data center infrastructure using a declarative configuration language known as HashiCorp Configuration Language (HCL). Instead of manually clicking through cloud provider consoles, you write configuration files that describe the desired state of your resources—such as virtual machines, networks, and storage—and Terraform handles the creation, modification, and deletion of those resources across multiple providers like AWS, Azure, and Google Cloud. This approach ensures consistency, repeatability, and version control for your infrastructure, making it a critical skill for cloud engineers and DevOps professionals.

1

Install Terraform and Verify the Setup

Download the Terraform binary from the official HashiCorp website and place it in your system PATH. On Linux or macOS, you can use a package manager like Homebrew or apt. After installation, run 'terraform version' to confirm the installation and check the version. This command also displays the available providers and their versions.

Bash
terraform version
# Output example:
# Terraform v1.5.7
# on linux_amd64
# + provider registry.terraform.io/hashicorp/aws v5.17.0

Always use the latest stable version of Terraform to benefit from the newest features and security patches.

Do not use the root user for Terraform operations; create a dedicated service account with minimal required permissions.

2

Create a Terraform Configuration File

Create a new directory for your project and inside it create a file named 'main.tf'. This file will contain your infrastructure definition. Start by declaring the required provider—for example, AWS. Specify the region and any optional configuration like profile or access keys. Terraform uses HCL syntax which is human-readable and structured.

HCL
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

Use version constraints (like ~> 5.0) to avoid unexpected breaking changes when running terraform init.

Never hardcode AWS access keys in your .tf files. Use environment variables or IAM roles instead.

3

Define Your First Resource: An EC2 Instance

Add a resource block to your main.tf file to define an AWS EC2 instance. Specify the AMI ID, instance type, and tags. Terraform will compare this desired state with the current state of your AWS account and create the resource if it doesn't exist. Use 'terraform plan' to preview the changes before applying them.

HCL
resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags = {
    Name = "TerraformDemo"
  }
}

Use data sources to fetch the latest AMI dynamically instead of hardcoding AMI IDs.

t2.micro is eligible for the AWS Free Tier only in certain regions; verify your region's free tier eligibility.

4

Initialize the Working Directory

Run 'terraform init' in your project directory. This command downloads the provider plugins specified in your configuration and sets up the backend for storing state files. You'll see output indicating which providers were installed and their versions. This step must be run before any other Terraform command.

Bash
terraform init

# Output snippet:
# Initializing the backend...
# Initializing provider plugins...
# - Finding hashicorp/aws versions matching "~> 5.0"...
# - Installing hashicorp/aws v5.17.0...
# Terraform has been successfully initialized!

Use a remote backend like S3 or Terraform Cloud to store state files securely and enable team collaboration.

Local state files are stored in plain text and may contain sensitive information; never commit them to version control.

5

Preview and Apply the Configuration

Run 'terraform plan' to see what resources will be created, modified, or destroyed. Review the output carefully. Then run 'terraform apply' to execute the changes. Terraform will prompt for confirmation unless you use the -auto-approve flag. After apply, you can verify the resource in the AWS console or via the AWS CLI.

Bash
terraform plan

# Output snippet:
# Terraform will perform the following actions:
#   + aws_instance.web_server will be created
#       + ami                          = "ami-0c55b159cbfafe1f0"
#       + instance_type                = "t2.micro"
#       + tags.%                       = "1"
#       + tags.Name                    = "TerraformDemo"

terraform apply -auto-approve

# Output snippet:
# Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Always run 'terraform plan' before 'apply' to catch unintended changes, especially in production environments.

Using -auto-approve in production can lead to accidental resource deletion; use it only in non-production or CI/CD pipelines.

6

Modify Infrastructure and Observe State Drift

Edit the main.tf file to change the instance type from t2.micro to t3.micro. Run 'terraform plan' again. Terraform will detect the drift between the desired state (t3.micro) and the current state (t2.micro) and propose an update. Apply the change. This demonstrates how Terraform manages incremental updates without manual intervention.

HCL / Bash
resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"  # changed from t2.micro

  tags = {
    Name = "TerraformDemo"
  }
}

terraform plan
# Output snippet:
#   ~ update in-place
#   ~ instance_type: "t2.micro" -> "t3.micro"

Use 'terraform show' to inspect the current state file and understand what Terraform tracks.

Changing instance type may cause a reboot; plan maintenance windows accordingly for production workloads.

7

Destroy Resources to Avoid Unnecessary Costs

When you no longer need the infrastructure, run 'terraform destroy' to remove all resources defined in your configuration. Terraform will show a destruction plan and ask for confirmation. This is essential for avoiding ongoing charges, especially when learning or testing. Always double-check that you are in the correct workspace.

Bash
terraform destroy

# Output snippet:
# Terraform will perform the following actions:
#   - aws_instance.web_server will be destroyed
# Plan: 0 to add, 0 to change, 1 to destroy.

# Do you really want to destroy all resources?
#   Enter a value: yes

# Destroy complete! Resources: 1 destroyed.

Use Terraform workspaces to manage multiple environments (dev, staging, prod) and avoid accidental destruction of production resources.

Running 'terraform destroy' is irreversible; always review the plan and ensure you have backups of critical data.

Key tips

  • Always use remote state backends (e.g., S3 with DynamoDB locking) for team environments to prevent state file corruption and enable collaboration.

  • Leverage Terraform modules to reuse common infrastructure patterns—like VPC setups or web server clusters—across multiple projects.

  • Use 'terraform validate' to check your configuration syntax before running plan or apply; it catches many common errors early.

  • Store sensitive variables (e.g., API keys, database passwords) in a secure vault or using Terraform Cloud's variable sets, never in plain text .tfvars files.

  • Implement a CI/CD pipeline that runs 'terraform plan' on pull requests and 'terraform apply' only after approval to enforce infrastructure governance.

  • Regularly run 'terraform refresh' to update the state file with the real-world infrastructure, especially if changes were made outside Terraform.

Frequently asked questions

What is the difference between Terraform and Ansible?

Terraform is a declarative IaC tool focused on provisioning infrastructure (e.g., VMs, networks), while Ansible is a configuration management tool that configures software on existing servers. Terraform is ideal for creating and destroying cloud resources, whereas Ansible excels at installing packages and managing application state. They are often used together.

Do I need to know a programming language to use Terraform?

No, Terraform uses HCL (HashiCorp Configuration Language), which is designed to be human-readable and declarative. You define what you want, not how to do it. Basic familiarity with YAML or JSON helps, but no programming experience is required. However, understanding cloud concepts like VPCs, subnets, and IAM is beneficial.

How does Terraform handle state locking?

Terraform uses state locking to prevent concurrent modifications to the state file, which can cause corruption or conflicts. When using a remote backend like S3 with DynamoDB, Terraform acquires a lock before running operations like plan or apply. If another process holds the lock, Terraform will wait or fail, depending on configuration.

Can Terraform manage resources across multiple cloud providers?

Yes, Terraform supports over 1,000 providers, including AWS, Azure, Google Cloud, and many others. You can define resources from different providers in the same configuration file, allowing you to orchestrate multi-cloud or hybrid infrastructure. Each provider is declared separately with its own configuration block.

What is the Terraform state file and why is it important?

The state file (terraform.tfstate) is a JSON file that maps your configuration to real-world resources. It tracks resource IDs, metadata, and dependencies. Terraform uses this file to determine what to create, update, or delete. Without it, Terraform cannot manage existing resources. Always store state files securely and use remote backends for team use.

Practice with real exam questions

Apply what you just learned with exam-style practice questions.

Related guides