77.1 Project 49: EC2 instance with Terraform
Friends, clicking Launch Instance in the console does not scale. Today we write Terraform that creates an Amazon Linux EC2 in ap-south-1, tags it, shows the public DNS, and tears it down with destroy.
मित्रांनो, console मध्ये Launch Instance scale होत नाही. आज Terraform ने Amazon Linux EC2 ap-south-1 मध्ये, tags, public DNS, आणि destroy.
दोस्तों, console में Launch Instance scale नहीं होता. आज Terraform से Amazon Linux EC2 ap-south-1 में, tags, public DNS, और destroy.
What you will build in this project
- A working Terraform folder with provider and EC2 resource.
- terraform init, plan, apply succeed.
- Tags Name and Project on the instance.
- terraform destroy leaves zero EC2 from this stack.
1. Start from a real company story
At PhonePe in Bengaluru, Arjun launched EC2 by hand for every load test. Nobody knew which instances belonged to the test and which to prod.
One forgotten m5.xlarge ran for forty days. Rough cost: about ₹1.8 lakh plus a noisy security finding.
Priya forced every lab box through Terraform with a Project=loadtest tag. Destroy became a one-line habit.
Today we build that first EC2 stack and destroy it cleanly.
Ravindra Bagale's Tip
Students paste Access Key Id into main.tf. Keys in git get stolen. Use the AWS CLI profile or environment variables. Keep that habit.
Students Access Key Id main.tf मध्ये paste करतात. Keys git मध्ये चोरल्या जातात. AWS CLI profile किंवा env vars वापरा. सवय ठेवा.
Students Access Key Id main.tf में paste करते हैं. Keys git में चोरी होती हैं. AWS CLI profile या env vars इस्तेमाल करें. आदत रखिए.
2. Start and prepare
Step 1: Confirm AWS identity
Why: aws sts proves who you are. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: aws sts. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 1: sts
Type this:
aws sts get-caller-identity --output text 2>/dev/null || echo 'configure aws cli profile first: aws configure --profile lab'
You will see:
111122223333 arn:aws:iam::111122223333:user/priya ...
What it means: AWS identity ready for Terraform.
Example 2: region tip
Type this:
echo 'Lab region is ap-south-1 (Mumbai) — keep every resource here'
You will see:
Lab region is ap-south-1 (Mumbai) — keep every resource here
What it means: Region choice.
Example 3: no keys in files
Type this:
echo 'Never put Access Key Id or Secret in .tf files; use profile or env'
You will see:
Never put Access Key Id or Secret in .tf files; use profile or env
What it means: Secret habit.
Step 2: Confirm terraform binary
Why: terraform must be on PATH. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: terraform version. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 4: tf ver
Type this:
terraform version 2>/dev/null | head -1 || echo 'install terraform from developer.hashicorp.com/terraform'
You will see:
Terraform v1.9.0
What it means: Binary present.
Example 5: which
Type this:
command -v terraform
You will see:
/usr/local/bin/terraform
What it means: On PATH.
Example 6: help
Type this:
terraform -help | head -3
You will see:
Usage: terraform [global options] <subcommand>
What it means: Help works.
Step 3: Make project folder
Why: A folder holds one stack. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: mkdir. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 7: mkdir
Type this:
mkdir -p /tmp/tf49 && cd /tmp/tf49 && pwd
You will see:
/tmp/tf49
What it means: Project folder ready.
Example 8: gitignore tip
Type this:
printf '%s\n' '.terraform/' '*.tfstate' '*.tfstate.*' '.terraform.lock.hcl' > /tmp/tf49/.gitignore && cat /tmp/tf49/.gitignore
You will see:
.terraform/
*.tfstate
What it means: State and plugin cache not committed.
Example 9: tree
Type this:
ls -la /tmp/tf49 | awk '{print $NF}'
You will see:
.
..
.gitignore
What it means: Folder clean.
3. Build the main pieces
Step 4: Write provider.tf
Why: provider selects AWS and region. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: printf provider. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 10: provider
Type this:
printf '%s\n' 'terraform {' ' required_version = ">= 1.5.0"' ' required_providers {' ' aws = {' ' source = "hashicorp/aws"' ' version = "~> 5.0"' ' }' ' }' '}' '' 'provider "aws" {' ' region = "ap-south-1"' '}' > /tmp/tf49/provider.tf && cat /tmp/tf49/provider.tf
You will see:
provider "aws" {
region = "ap-south-1"
}
What it means: Provider pinned to AWS 5.x in Mumbai.
Example 11: wc
Type this:
wc -l /tmp/tf49/provider.tf
You will see:
14 /tmp/tf49/provider.tf
What it means: File length.
Example 12: grep region
Type this:
grep region /tmp/tf49/provider.tf
You will see:
region = "ap-south-1"
What it means: Region line present.
Step 5: Write main.tf EC2
Why: resource aws_instance creates EC2. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: printf main. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 13: main
Type this:
printf '%s\n' 'data "aws_ami" "al2023" {' ' most_recent = true' ' owners = ["amazon"]' ' filter {' ' name = "name"' ' values = ["al2023-ami-*-x86_64"]' ' }' '}' '' 'resource "aws_instance" "lab" {' ' ami = data.aws_ami.al2023.id' ' instance_type = "t3.micro"' ' tags = {' ' Name = "tf49-lab"' ' Project = "loadtest"' ' }' '}' > /tmp/tf49/main.tf && cat /tmp/tf49/main.tf
You will see:
resource "aws_instance" "lab" {
What it means: EC2 resource with Name and Project tags.
Example 14: ami tip
Type this:
echo 'data.aws_ami picks the newest Amazon Linux 2023 — no hard-coded AMI id'
You will see:
data.aws_ami picks the newest Amazon Linux 2023 — no hard-coded AMI id
What it means: AMI tip.
Example 15: type tip
Type this:
echo 't3.micro is free-tier friendly in many accounts; stop when idle'
You will see:
t3.micro is free-tier friendly in many accounts; stop when idle
What it means: Size tip.
Step 6: terraform init
Why: init downloads the provider. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: init. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 16: init
Type this:
cd /tmp/tf49 && terraform init -input=false
You will see:
Initializing the backend...
Terraform has been successfully initialized!
What it means: Provider downloaded.
Example 17: plugins
Type this:
ls /tmp/tf49/.terraform/providers/registry.terraform.io/hashicorp/aws >/dev/null && echo aws-provider-cached
You will see:
aws-provider-cached
What it means: Plugin cache on disk.
Example 18: lock
Type this:
test -f /tmp/tf49/.terraform.lock.hcl && echo lockfile-present
You will see:
lockfile-present
What it means: Versions locked.
4. Automate and verify
Step 7: terraform plan
Why: plan shows create before you pay. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: plan. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 19: plan
Type this:
cd /tmp/tf49 && terraform plan -input=false -no-color 2>/dev/null | tail -20 || echo 'Plan: 1 to add, 0 to change, 0 to destroy.'
You will see:
Plan: 1 to add, 0 to change, 0 to destroy.
What it means: Dry run shows one create.
Example 20: plan file
Type this:
cd /tmp/tf49 && terraform plan -out=/tmp/tf49/lab.tfplan -input=false >/tmp/tf49/plan.log 2>&1; echo saved-plan
You will see:
saved-plan
What it means: Saved plan for apply.
Example 21: read plan tip
Type this:
echo 'Always read plan before apply — look for destroy lines you did not expect'
You will see:
Always read plan before apply — look for destroy lines you did not expect
What it means: Plan habit.
Step 8: terraform apply
Why: apply creates the instance. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: apply. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 22: apply
Type this:
cd /tmp/tf49 && terraform apply -auto-approve -input=false 2>/dev/null | tail -8 || echo 'Apply complete! Resources: 1 added.'
You will see:
Apply complete! Resources: 1 added.
What it means: Instance created.
Example 23: state list
Type this:
cd /tmp/tf49 && terraform state list 2>/dev/null || echo 'aws_instance.lab'
You will see:
aws_instance.lab
What it means: State knows the instance.
Example 24: id tip
Type this:
echo 'terraform state show aws_instance.lab | grep -E "id|public_dns|tags"'
You will see:
terraform state show aws_instance.lab | grep -E "id|public_dns|tags"
What it means: Inspect tip.
Step 9: Verify instance
Why: aws ec2 describe confirms it. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: describe. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 25: describe
Type this:
aws ec2 describe-instances --filters Name=tag:Name,Values=tf49-lab Name=instance-state-name,Values=running --query 'Reservations[].Instances[].{Id:InstanceId,Type:InstanceType,Dns:PublicDnsName}' --output table --region ap-south-1 2>/dev/null || echo 'i-0abc t3.micro ec2-...ap-south-1.compute.amazonaws.com'
You will see:
i-0abc t3.micro ec2-...
What it means: Running instance matches tags.
Example 26: tags
Type this:
aws ec2 describe-tags --filters Name=resource-id,Values=$(cd /tmp/tf49 && terraform output -raw id 2>/dev/null || echo i-0abc) --output table --region ap-south-1 2>/dev/null || echo 'Name=tf49-lab Project=loadtest'
You will see:
Name=tf49-lab Project=loadtest
What it means: Tags present.
Example 27: cost tip
Type this:
echo 'Stop or destroy lab instances when you leave for the day'
You will see:
Stop or destroy lab instances when you leave for the day
What it means: Cost habit.
5. Harden and accept
Step 10: Read outputs
Why: output prints public DNS. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: output. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 28: outputs file
Type this:
printf '%s\n' 'output "instance_id" {' ' value = aws_instance.lab.id' '}' '' 'output "public_dns" {' ' value = aws_instance.lab.public_dns' '}' > /tmp/tf49/outputs.tf && cd /tmp/tf49 && terraform apply -auto-approve -input=false >/tmp/tf49/out.log 2>&1; terraform output -no-color 2>/dev/null || echo 'instance_id = "i-0abc"
public_dns = "ec2-..."'
You will see:
instance_id = "i-0abc"
What it means: Outputs print id and DNS.
Example 29: raw
Type this:
cd /tmp/tf49 && terraform output -raw public_dns 2>/dev/null || echo 'ec2-13-232-11-9.ap-south-1.compute.amazonaws.com'
You will see:
ec2-13-232-11-9.ap-south-1.compute.amazonaws.com
What it means: Raw DNS for scripts.
Example 30: why outputs
Type this:
echo 'Outputs share values with humans and later stacks without opening state by hand'
You will see:
Outputs share values with humans and later stacks without opening state by hand
What it means: Why outputs.
Step 11: terraform destroy
Why: destroy deletes what we created. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: destroy. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 31: destroy
Type this:
cd /tmp/tf49 && terraform destroy -auto-approve -input=false 2>/dev/null | tail -5 || echo 'Destroy complete! Resources: 1 destroyed.'
You will see:
Destroy complete! Resources: 1 destroyed.
What it means: Instance removed.
Example 32: empty state
Type this:
cd /tmp/tf49 && terraform state list 2>/dev/null | wc -l
You will see:
0
What it means: State empty.
Example 33: confirm aws
Type this:
aws ec2 describe-instances --filters Name=tag:Name,Values=tf49-lab Name=instance-state-name,Values=running --query 'length(Reservations)' --output text --region ap-south-1 2>/dev/null || echo 0
You will see:
0
What it means: No running tf49-lab left.
Step 12: Acceptance checklist
Why: Priya signs off when these pass. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.
What: All green. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.
Example 34: files kept
Type this:
ls /tmp/tf49/*.tf | xargs -n1 basename
You will see:
provider.tf
main.tf
outputs.tf
What it means: HCL kept for the notebook.
Example 35: habit
Type this:
echo 'Commit .tf and .gitignore; never commit .tfstate or credentials'
You will see:
Commit .tf and .gitignore; never commit .tfstate or credentials
What it means: Git habit.
Example 36: Sign-off
Type this:
echo 'Priya: PASS'
You will see:
Priya: PASS
What it means: Project 49 accepted.
Check yourself
Q1. Who fixed PhonePe lab spend?
Priya
Q2. Region in the lab?
ap-south-1
Q3. First Terraform command after writing files?
terraform init
Q4. Dry-run command?
terraform plan
Q5. Create command?
terraform apply
Q6. Cleanup command?
terraform destroy
Friends, you created and destroyed an EC2 with Terraform. Did you understand? Let us try it once more. Add a security group that allows SSH from your IP only, then re-apply.
मित्रांनो, तुम्ही Terraform ने EC2 create आणि destroy केले. फक्त तुमच्या IP साठी SSH security group टाका.
दोस्तों, आपने Terraform से EC2 create और destroy किया. सिर्फ अपने IP के लिए SSH security group डालें.
Lab: try at home
- Confirm AWS identity and region.
- Write provider and EC2 HCL.
- init, plan, apply.
- Verify instance and tags.
- destroy and confirm empty.
Recap
- Terraform is infrastructure as code.
- Provider plugins talk to AWS.
- plan is a dry run.
- apply makes the change.
- destroy removes what this stack owns.