How to set up Terraform and create your first EC2 instance
Terraform lets you define infrastructure in code and apply it with a single command. This walkthrough gets you from zero to a running EC2 instance. You’ll need an AWS account and the AWS CLI installed and configured before starting.
Install Terraform
Pick your OS. All four methods install the same binary from HashiCorp.
macOS
Install via Homebrew:
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
If you don’t have Homebrew, install it first from brew.sh.
Windows
Install via Chocolatey:
choco install terraform
Or with winget:
winget install Hashicorp.Terraform
For manual installation, download the zip from hashicorp.com/downloads, extract it, and add the folder to your PATH.
Ubuntu / Debian
Add the HashiCorp APT repository and install:
sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | \
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
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-get update && sudo apt-get install terraform
RHEL / Amazon Linux
Add the HashiCorp YUM repository and install:
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo \
https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install terraform
Verify the installation on any OS:
terraform -version
You should see Terraform v1.x.x. If you get “command not found,” the binary isn’t in your PATH.
Create your project
Create a new directory and move into it:
mkdir my-first-ec2 && cd my-first-ec2
Create a file called main.tf. This is where Terraform reads your infrastructure definition.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-south-1"
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"]
}
}
resource "aws_instance" "first" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
tags = {
Name = "my-first-ec2"
}
}
A few things worth noting:
- The
datablock finds the latest Ubuntu 24.04 AMI automatically, so you don’t need to hardcode AMI IDs that go stale. t3.microis free-tier eligible, good enough for testing.- Change
regionto wherever your AWS CLI is configured. Check withaws configure get region.
Initialize and apply
Initialize the project. This downloads the AWS provider plugin:
terraform init
Preview what Terraform will create:
terraform plan
Plan: 1 to add, 0 to change, 0 to destroy.
Apply the configuration:
terraform apply
Type yes when prompted. Terraform creates the instance and prints its details. The whole process takes about 30 seconds.
Verify the instance in the AWS console or with the CLI:
aws ec2 describe-instances \
--filters "Name=tag:Name,Values=my-first-ec2" \
--query "Reservations[].Instances[].{ID:InstanceId,State:State.Name,IP:PublicIpAddress}" \
--output table
Clean up
Destroy the instance if you’re just testing:
terraform destroy
Type yes to confirm. Terraform terminates the instance and removes all the resources it created.
What’s next
This is the simplest possible Terraform setup: one file, one resource, no remote state. For a real project, you’d add:
- A remote backend (S3 + DynamoDB) so your state file isn’t sitting on your laptop
- Variables for region, instance type, and tags
- A security group to control inbound/outbound traffic
- An SSH key pair if you need to connect to the instance
I’ll cover those in future posts.