What is Terraform?
Terraform is an open-source tool used to manage and automate infrastructure. It helps developers define and provision cloud and on-premises resources using a simple, human-readable configuration language. Instead of manually creating servers, databases, and networks, Terraform allows you to write code that describes what your infrastructure should look like, and it takes care of creating, updating, and deleting resources accordingly.
For more details, visit the official Terraform documentation.
Why Do We Need Terraform?
- Infrastructure as Code (IaC) – Terraform enables managing infrastructure using code, making it repeatable and version-controlled.
- Automation – Reduces manual intervention and human errors.
- Consistency – Ensures the same configuration is applied everywhere.
- Multi-Cloud Support – Works with AWS, Azure, Google Cloud, and many other providers.
- Scalability – Easily scale infrastructure up or down as needed.
- Dependency Management – Automatically manages dependencies between resources.
What is Provisioning?
Provisioning refers to the process of setting up IT infrastructure, such as servers, databases, and networks, automatically rather than manually. Terraform allows infrastructure provisioning using declarative code, ensuring reproducibility and reducing errors.
Challenges in IT Infrastructure Management
- Manual Errors – Managing resources manually can lead to mistakes.
- Scaling Issues – Difficult to scale manually.
- Inconsistency – Different environments may have different configurations.
- Lack of Documentation – Manual setups often lack proper documentation.
- Long Deployment Times – Manual provisioning can take a lot of time.
Terraform vs Ansible
Feature | Terraform | Ansible |
---|---|---|
Purpose | Infrastructure provisioning | Configuration management |
State Management | Maintains state | No state management |
Declarative/Imperative | Declarative | Imperative and declarative |
Best Use Case | Creating cloud resources | Configuring and managing software |
Multi-cloud Support | Yes | Yes |
Agent-based | No | No |
Terraform File Extension
Terraform configuration files use the .tf
extension.
Which Language Does Terraform Use?
Terraform uses HCL (HashiCorp Configuration Language), which is a declarative language designed for defining infrastructure in a human-readable format.
What Can We Provision with Terraform? (Examples)
- Cloud Resources – AWS EC2, Azure Virtual Machines, Google Compute Engine.
- Networking – Load balancers, DNS records, VPCs, subnets.
- Databases – PostgreSQL, MySQL, MongoDB.
- Storage – S3 buckets, Azure Blob Storage, Google Cloud Storage.
- Containers – Kubernetes, Docker, ECS, EKS, AKS.
- Monitoring – CloudWatch, Prometheus.
HCL (HashiCorp Configuration Language) – All Details
Syntax Block
HCL uses blocks to define resources, providers, and configurations. Each block consists of:
- Type (e.g.,
resource
,provider
) - Label(s) (e.g., name, type identifier)
- Body (contains attributes and values)
Example:
resource "aws_instance" "web" {
ami = "ami-123456"
instance_type = "t2.micro"
}
Arguments
Arguments are key-value pairs inside blocks. Example:
variable "region" {
default = "us-east-1"
}
HCL Features Table
Feature | Description | Example |
Providers | Defines cloud/platform-specific APIs | provider "aws" { region = "us-east-1" } |
Resources | Defines infrastructure components | resource "aws_instance" "example" { ami = "ami-123456" instance_type = "t2.micro" } |
Variables | Stores values to make code reusable | variable "region" { default = "us-east-1" } |
Outputs | Displays values after execution | output "instance_ip" { value = aws_instance.example.public_ip } |
Modules | Reusable components to structure infrastructure | module "network" { source = "./modules/network" } |
Data Sources | Fetches existing cloud resources | data "aws_ami" "latest" { most_recent = true owners = ["amazon"] } |
Different Structures to Manage a Terraform Repository
- Flat Structure – This structure keeps all Terraform files in a single directory without any modularization. It is suitable for small projects but can become difficult to manage as infrastructure grows.
Example:
project/
├── main.tf
├── variables.tf
├── outputs.tf
├── terraform.tfvars
In this approach, all Terraform configurations are in one directory, making it easy to start with but less scalable for large environments.
- Modular Structure – This approach organizes Terraform configurations into reusable modules, making it easier to manage and scale infrastructure. Each module contains its own configuration files for specific components, such as networking or compute resources. This structure promotes code reusability and maintainability, particularly for large-scale projects.
Example:
project/
├── modules/
│ ├── network/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ ├── compute/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
├── main.tf
In this approach, infrastructure is broken into smaller, manageable components, improving maintainability and scalability.
- Environment-based Structure – This structure separates Terraform configurations into different directories for each environment, such as development (
dev
), staging (staging
), and production (prod
). This approach helps isolate infrastructure changes across different environments, reducing the risk of accidental modifications to production.
Each environment has its own Terraform configuration files to manage specific resources and settings. This method is particularly useful for teams handling multiple environments with different configurations.
Example:
environments/
├── dev/
│ ├── main.tf
│ ├── variables.tf
├── staging/
│ ├── main.tf
│ ├── variables.tf
├── prod/
│ ├── main.tf
│ ├── variables.tf
Each directory contains its respective configuration files, ensuring that changes in one environment do not impact others.
- Workspace-based Structure – Terraform workspaces allow managing multiple environments within the same configuration. Instead of maintaining separate directories for different environments, workspaces enable switching between different states dynamically. This is useful when handling development, staging, and production setups without duplicating configuration files.
Example:
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "workspace/terraform.tfstate"
region = "us-east-1"
}
}
To create and switch between workspaces, use the following commands:
terraform workspace new dev
terraform workspace select dev
terraform workspace list
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "workspace/terraform.tfstate"
region = "us-east-1"
}
}
What is State in Terraform?
Terraform keeps track of managed infrastructure using a state file (terraform.tfstate
). It helps Terraform understand what resources exist and what needs updating.
How Different Developers Can Work on One Terraform Repository
- Remote State Storage – Use AWS S3, Azure Blob, or Terraform Cloud for shared state.
- Locking Mechanism – Use state locking to prevent conflicts.
- Branch-based Development – Work on separate branches and merge changes.
- Workspaces – Separate infrastructure environments within the same configuration.
How to Handle Sensitive Data in Terraform
- Environment Variables
variable "db_password" {} export TF_VAR_db_password="supersecurepassword"
- Terraform Vault Integration
provider "vault" {}
- AWS Secrets Manager
data "aws_secretsmanager_secret" "example" { name = "my-secret" }
Nginx Docker Container with Terraform
This project demonstrates how to deploy an Nginx container using Terraform step by step.
To begin, create a new directory and navigate into it:
mkdir terraform-nginx && cd terraform-nginx
Create a main.tf
file with the following content:
If the Docker provider is not available by default, initialize Terraform to install it:
terraform init
Ensure that Docker is installed on your machine. If not, install it from Docker’s official website.
provider "docker" {}
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.latest
name = "nginx_container"
ports {
internal = 80
external = 8080
}
}
Initialize Terraform:
terraform init
Preview the planned changes:
terraform plan
Apply the configuration to create the container:
terraform apply -auto-approve
Verify the running container:
docker ps
Expected output:
CONTAINER ID IMAGE COMMAND PORTS NAMES
abc12345 nginx:latest "nginx -g 'daemon off;" 0.0.0.0:8080->80/tcp nginx_container
Test the Nginx server by opening a browser and navigating to http://localhost:8080
. You should see the default Nginx welcome page.
If you need to remove the resources, destroy the container:
Local File Creation Project
This project demonstrates how to create a local file using Terraform.
Terraform Configuration:
resource "local_file" "example" {
content = "Hello, Terraform!"
filename = "hello.txt"
}
To execute the project, first initialize the directory by running the following command:
terraform init
Next, plan the changes to verify the execution plan:
terraform plan
Apply the configuration to create the file:
terraform apply
Once applied, check if the file hello.txt
has been created in your working directory.
If you no longer need the file, clean up by running:
terraform destroy