Terraform Journey: From Zero to Launching EC2 on AWS
đź§ Why I Chose Terraform
Coming from a project management and academic background, I wanted to actually build things — infrastructure included. I chose Terraform because:
- Declarative Syntax: Write what you want, not how to get there
- Multi-Cloud Ready: Works with AWS, Azure, GCP and more
- DevSecOps Integration: Fits perfectly in CI/CD pipelines
- Community Support: 1,000+ providers and modules available
🛠️ Core Concepts I Learned
1. Infrastructure as Code Fundamentals
- Providers: The
aws
provider connects Terraform to AWS API - Resources: Building blocks like
aws_instance
,aws_vpc
- State Management: The critical
.tfstate
file - Plan/Apply Cycle:
terraform plan
→ review →terraform apply
2. AWS Networking Basics
# Network Foundation
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "Terraform-VPC"
}
}
đź”§ EC2 Deployment Walkthrough
Step 1: Configure AWS Provider
provider "aws" {
region = "eu-central-1"
# Never hardcode credentials!
# Use environment variables or AWS CLI config
}
Step 2: Create Security Group
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh"
description = "Allow SSH inbound traffic"
vpc_id = aws_vpc.main.id
ingress {
description = "SSH from anywhere"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Restrict this in production!
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Step 3: Launch EC2 Instance
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2
instance_type = "t2.micro"
key_name = "terraform-key"
vpc_security_group_ids = [aws_security_group.allow_ssh.id]
tags = {
Name = "Terraform-EC2"
}
}
đźš§ Challenges & Solutions
Challenge | Symptom | Root Cause | Solution |
---|---|---|---|
SSH Timeout | Connection refused | Missing Internet Gateway | Added IGW and route table |
State File Lost | “Resource doesn’t exist” errors | Accidental deletion | Configured S3 backend |
Cost Surprise | Unexpected AWS charges | Left instances running | Added terraform destroy to workflow |
đź”’ Security Lessons
- Secrets Management:
- Never commit
.tfvars
files with credentials - Use AWS Secrets Manager or environment variables
- Never commit
- Least Privilege:
# Bad cidr_blocks = ["0.0.0.0/0"] # Good cidr_blocks = ["203.0.113.12/32"] # Your IP only
- State Protection:
- Enable S3 bucket versioning
- Use DynamoDB for state locking
✅ What’s Next
- Advanced Terraform:
- Modules for reusability
- Workspaces for environments
- Sentinel policies for governance
- DevSecOps Integration:
graph LR A[Terraform Code] --> B[GitHub PR] B --> C[Checkov Scan] C --> D[Jenkins Pipeline] D --> E[AWS Deployment]
đź”— Resources
💬 Let’s Connect
Have Terraform tips to share? Found a better approach?
Open an issue on this blog’s repo or
Connect on LinkedIn
“Infrastructure as Code isn’t just about automation - it’s about bringing engineering discipline to operations.” - Kief Morris ```
Comments