As cloud environments grow complex, manually managing the infrastructure becomes error-prone and pretty hard to scale. This is where the Infrastructure as Code (IaC) comes into play. Terraform is an open source IaC tool that is one of the best fit for automating infrastructure across cloud providers.
When used with the right cloud providers, such as Amazon Web Services (AWS), Terraform empowers teams to provision cloud resources using declarative configuration files. From spinning up the EC2 instances to setting up the VPCs and IAM roles, Terraform allows you to version, reuse, and scale the infrastructure reliably.
This starters guide will help you learn how to use Terraform on AWS.
Benefits of Using Terraform on AWS
Using Terraform to manage AWS infrastructure offers multiple key advantages, such as:
- Quick automation from provisioning, updating, and destroying AWS resources with a single command.
- Track infrastructure changes via Git for version control.
- Reuse configuration blocks using modules for much better scalability.
- Terraform’s plan command will help preview changes before applying.
- Eliminates manual steps that will lead to misconfigurations.
- Easy team collaboration.
Prerequisites for Setting Up Terraform on AWS
Before you start the initial installation of Terraform on AWS, you need to make sure that you fulfil the following prerequisites.
- Sign up for an AWS account at aws.amazon.com.
- Assign preferred permissions like AdministratorAccess or least privilege.
- Make sure you have local terminal access for local development.
- Installed tools:
- Terraform CLI
- AWS CLI
Your team should also be familiar with the AWS services that you are managing, command-line knowledge, and IaC concepts.
Get exclusive access to all things tech-savvy, and be the first to receive
the latest updates directly in your inbox.
Installing Terraform and AWS CLI
Install Terraform
- On macOS (Homebrew):
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
- On Linux:
sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg –dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo “deb [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
- On Windows:
Download the Terraform binary from the official site, extract it, and add it to your system PATH.
Install AWS CLI
- macOS / Linux (using pip):
pip install awscli –upgrade –user
- Windows:
Use the installer from the official AWS CLI page.
Setting Up AWS Credentials for Terraform
Once you have installed the AWS CLI, you can configure the credential by using:

aws configure
This will prompt you for:
- AWS Access Key ID
- AWS Secret Access Key
- Default region name (e.g., us-east-1)
- Default output format (optional; use json, table, or text)
Terraform on AWS uses these credentials under the hood when provisioning resources.
Related Article: Terraform Backend: How to Manage and Store Terraform State Securely
Writing Your First Terraform Script for AWS
Here’s a simple example that launches a basic EC2 instance on AWS.
- Step 1: Create a Terraform config file (main.tf)
provider “aws” {
region = “us-east-1”
}
resource “aws_instance” “example” {
ami = “ami-0c55b159cbfafe1f0”
instance_type = “t2.micro”
tags = {
Name = “TerraformExample”
}
}
- Step 2: Initialize Terraform
terraform init
- Step 3: Preview the changes
terraform plan
- Step 4: Apply the configuration
terraform apply
You’ll be prompted to confirm before Terraform provisions the EC2 instance.
Provisioning AWS Resources with Terraform
Terraform on AWS allows you to define and deploy resources with reusable configurations. Here is how to provision some core AWS services step by step.
- EC2 Instance
Provisioning a basic EC2 instance:
provider “aws” {
region = “us-east-1”
}
resource “aws_instance” “web_server” {
ami = “ami-0c55b159cbfafe1f0”
instance_type = “t2.micro”
tags = {
Name = “TerraformEC2”
}
}
Run:
terraform init
terraform apply
- VPC
Define a custom Virtual Private Cloud (VPC):
resource “aws_vpc” “custom_vpc” {
cidr_block = “10.0.0.0/16”
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = “TerraformVPC”
}
}
You can further add subnets, route tables, and gateways to make it production-ready.
- S3 Bucket
Create a versioned S3 bucket:
resource “aws_s3_bucket” “my_bucket” {
bucket = “terraform-example-bucket-1234”
force_destroy = true
tags = {
Name = “TerraformS3”
}
}
resource “aws_s3_bucket_versioning” “versioning” {
bucket = aws_s3_bucket.my_bucket.id
versioning_configuration {
status = “Enabled”
}}This will provision an S3 bucket with versioning turned on.
- IAM Roles
Provision a basic IAM role with a trust relationship:
resource “aws_iam_role” “example_role” {
name = “TerraformExampleRole”
assume_role_policy = jsonencode({
Version = “2012-10-17”
Statement = [{
Action = “sts:AssumeRole”
Effect = “Allow”
Principal = {
Service = “ec2.amazonaws.com”
}
}]
})
tags = {
Name = “TerraformIAMRole”
}
}
You can then attach policies like so:
resource “aws_iam_role_policy_attachment” “attach_policy” {
role = aws_iam_role.example_role.name
policy_arn = “arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess”
Managing State with Terraform Backend on AWS (e.g., S3 + DynamoDB)
Terraform tracks the infrastructure changes with a state file. In team environments or production setups, storing the file can lead to a security breach. Instead, use a remote backend server, such as DynamoDB.
Here is how you can set it up.
- Create an S3 bucket to store the state file:
resource “aws_s3_bucket” “tf_state” {
bucket = “my-terraform-state-bucket”
versioning {
enabled = true
}
tags = {
Name = “TerraformState”
}
}
- Create a DynamoDB table for state locking:
resource “aws_dynamodb_table” “tf_locks” {
name = “terraform-locks”
hash_key = “LockID”
billing_mode = “PAY_PER_REQUEST”
attribute {
name = “LockID”
type = “S”
}
}
- Configure the backend in main.tf:
terraform {
backend “s3” {
bucket = “my-terraform-state-bucket”
key = “global/s3/terraform.tfstate”
region = “us-east-1”
dynamodb_table = “terraform-locks”
encrypt = true
}
}
Terraform Modules for AWS
Terraform modules enable you to group and reuse Terraform code across multiple environments and projects.
Basic Module Structure
/modules
/ec2-instance
main.tf
variables.tf
outputs.tf
main.tf (root)
Example Usage
module “web_instance” {
source = “./modules/ec2-instance”
instance_type = “t2.micro”
ami_id = “ami-0c55b159cbfafe1f0”
tags = {
Name = “ModuleEC2”
}
}
Modules can be local or pulled from a Git repo, Terraform Registry, or even a remote path.
Common Errors and Troubleshooting Guide For Terraform on AWS
Error Message | Likely Cause | Solution |
No valid credential sources found | AWS credentials missing or misconfigured | Run aws configure or check environment variables |
Error acquiring the state lock | DynamoDB lock already held | Ensure no other Terraform process is running |
Invalid AMI ID | AMI ID doesn’t exist in selected region | Use a region-specific, updated AMI |
403 Access Denied from S3 | Insufficient S3 bucket permissions | Check IAM policies and bucket permissions |
Unsupported backend | Missing backend block or syntax error | Check terraform block and backend config |
Resource already exists | Terraform trying to create a resource that already exists | Import the resource using terraform import |
Module not found | Incorrect source path | Verify local/remote module path or repo URL |
terraform apply stuck or fails silently | State lock not released | Manually remove lock from DynamoDB (use with caution) |
Terraform vs AWS CloudFormation
Feature | Terraform | AWS CloudFormation |
Multi-cloud Support | Yes (AWS, Azure, GCP, more) | No (AWS-only) |
Language | HCL (HashiCorp Configuration Language) | JSON or YAML |
Modularity | Strong (Modules, Registry) | Supports nested stacks |
State Management | External (local, S3, etc.) | Managed by AWS |
Learning Curve | Easier syntax, widely adopted | Tied to AWS, more verbose |
Community & Ecosystem | Large, open-source driven | AWS-managed, tightly integrated |
Wrapping Up – Is Terraform on AWS The Right Solution For Your Team?
Terraform on AWS is a powerful tool to automate the infrastructure, allowing teams to build, manage, deploy, and scale environments. By leavering important features, like modules, you can create reliable infrastructure that will scale with your team needs.
Frequently Asked Questions
Why should I use Terraform instead of the AWS Management Console?
Terraform offers automation, version control, consistency, and reusability. It helps eliminate manual errors and makes infrastructure changes more reliable and repeatable, especially in team environments.
Can I use Terraform modules for AWS resources?
Yes. Modules let you reuse and organize code for common resource patterns like VPCs, EC2 instances, and IAM roles, promoting DRY (Don’t Repeat Yourself) principles and maintainability.
What’s the difference between Terraform and AWS CloudFormation?
Terraform is cloud-agnostic and uses HCL, while CloudFormation is AWS-native and uses JSON/YAML. Terraform provides a more flexible and consistent experience across multi-cloud environments.