Cloud computing is now the backbone of modern software — and cloud engineers are among the most in-demand (and best-paid) professionals in tech. But "cloud" covers a huge surface area: infrastructure, networking, security, automation, containers, serverless, and more. This roadmap cuts through the noise and shows you exactly what to learn, in what order, so you can go from zero to cloud-ready in 12–18 months.
At a glance
| Phase |
Topics |
Time estimate |
| 1 |
Foundations: networking and Linux |
6–8 weeks |
| 2 |
Cloud concepts and core services |
4–6 weeks |
| 3 |
Infrastructure as Code (Terraform) |
4–6 weeks |
| 4 |
Containers and Kubernetes |
6–8 weeks |
| 5 |
CI/CD and automation |
3–4 weeks |
| 6 |
Cloud security |
4–6 weeks |
| 7 |
Monitoring and observability |
3–4 weeks |
| 8 |
Scripting and automation (Python + Bash) |
4–6 weeks |
| 9 |
Databases and storage |
3–4 weeks |
| 10 |
Architecture and cost optimization |
3–4 weeks |
| 11 |
Certifications and portfolio |
4–8 weeks |
| Total to first role |
|
~12–18 months |
Phase 1 — Networking and Linux foundations
Cloud engineers spend their careers configuring virtual networks, SSH-ing into servers, and debugging traffic flows. You cannot automate what you do not understand.
Core networking
| Topic |
What to know |
| OSI / TCP-IP model |
7 layers vs 4 layers, which layer each cloud service maps to |
| IP addressing |
IPv4/IPv6, CIDR notation, subnetting (e.g. /24 = 256 addresses) |
| DNS |
A, CNAME, MX, TXT, NS records; TTL; Route 53/Cloud DNS/Azure DNS |
| HTTP/HTTPS |
Methods, status codes, TLS handshake, certificates |
| Firewalls |
Stateless vs stateful, security groups, NACLs |
| Load balancing |
Layer 4 vs Layer 7, health checks, sticky sessions |
| VPN / VPC peering |
Site-to-site VPN, VPC peering, Transit Gateway |
Linux essentials
# File system and navigation
ls -lah /var/log/ # list with hidden files + human sizes
find / -name "*.log" -mtime -7 # files modified in last 7 days
grep -r "ERROR" /var/log/nginx/ # recursive search
# User and permissions
chmod 755 deploy.sh # rwxr-xr-x
chown -R www-data:www-data /var/www/
sudo useradd -m -s /bin/bash devops
# Processes and services
ps aux | grep nginx
systemctl status nginx
journalctl -u nginx --since "1 hour ago"
top / htop # real-time resource usage
# Networking from CLI
curl -I https://example.com
ss -tlnp # listening TCP ports
netstat -rn # routing table
ip addr show # network interfaces
# Package management
apt update && apt upgrade -y # Debian/Ubuntu
yum update -y # RHEL/CentOS/Amazon Linux
| Topic |
Why it matters for cloud |
| systemd / services |
Managing app daemons on EC2/VM instances |
| File permissions |
IAM roles map to the same principle (least privilege) |
| Shell scripting |
Bash scripts automate AMI builds, cron jobs, startup tasks |
| Log files |
/var/log/ is the first stop when a cloud instance fails |
| SSH |
All cloud VMs are accessed via SSH; key pair management is critical |
cron / at |
Scheduling jobs on instances; Lambda cron is the cloud version |
Phase 2 — Cloud concepts and core services
All three major clouds (AWS, Azure, GCP) share the same conceptual building blocks. Learn the concepts once; the syntax differs between providers.
Universal cloud concepts
| Concept |
Description |
| Region |
Geographical location (e.g. us-east-1, westeurope) |
| Availability Zone (AZ) |
Isolated data centre within a region — design for multi-AZ |
| Virtual Private Cloud (VPC) |
Your private network inside the cloud |
| Subnet |
Subdivision of a VPC (public = internet-routable, private = internal only) |
| Security group |
Stateful firewall at the instance level |
| IAM |
Identity and access management — who can do what to which resource |
| Object storage |
S3, Azure Blob, GCS — infinitely scalable file storage |
| Block storage |
EBS, Azure Disk, GCP PD — like a hard drive attached to a VM |
| Serverless compute |
Lambda, Azure Functions, Cloud Functions — run code without managing servers |
| Managed database |
RDS, Azure SQL, Cloud SQL — database as a service |
| CDN |
CloudFront, Azure CDN, Cloud CDN — serve static assets from edge |
AWS core services (recommended first cloud)
# AWS CLI — the backbone of cloud automation
aws configure # set access key + region
# EC2 — virtual machines
aws ec2 run-instances \
--image-id ami-0c55b159cbfafe1f0 \
--instance-type t3.micro \
--key-name my-keypair \
--security-group-ids sg-12345
# S3 — object storage
aws s3 mb s3://my-bucket-name
aws s3 cp file.txt s3://my-bucket-name/
aws s3 sync ./dist s3://my-website-bucket --delete
# IAM
aws iam create-role --role-name EC2-S3-Role \
--assume-role-policy-document file://trust-policy.json
# Lambda — serverless
aws lambda create-function \
--function-name MyFunction \
--runtime python3.12 \
--handler index.handler \
--zip-file fileb://function.zip \
--role arn:aws:iam::123456789012:role/lambda-role
Cloud provider comparison
| Service category |
AWS |
Azure |
GCP |
| Virtual machines |
EC2 |
Virtual Machines |
Compute Engine |
| Object storage |
S3 |
Blob Storage |
Cloud Storage |
| Managed Kubernetes |
EKS |
AKS |
GKE |
| Serverless |
Lambda |
Azure Functions |
Cloud Functions / Cloud Run |
| Managed database (SQL) |
RDS |
Azure SQL |
Cloud SQL |
| NoSQL |
DynamoDB |
Cosmos DB |
Firestore / Bigtable |
| Container registry |
ECR |
ACR |
Artifact Registry |
| CI/CD |
CodePipeline |
Azure DevOps |
Cloud Build |
| Monitoring |
CloudWatch |
Azure Monitor |
Cloud Monitoring |
| Secret management |
Secrets Manager |
Key Vault |
Secret Manager |
| CDN |
CloudFront |
Azure CDN |
Cloud CDN |
| DNS |
Route 53 |
Azure DNS |
Cloud DNS |
| Message queue |
SQS |
Service Bus |
Pub/Sub |
Recommendation: Start with AWS (largest market share, most jobs, most learning resources). AWS certifications are the most recognized globally.
Phase 3 — Infrastructure as Code (Terraform)
Manual clicking in the cloud console does not scale. Infrastructure as Code (IaC) lets you define infrastructure in files, version it in git, and deploy it reliably every time.
Why Terraform
Terraform uses HCL (HashiCorp Configuration Language) and works across all three major clouds with the same toolchain.
# main.tf — a complete VPC + EC2 example
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "us-east-1"
}
}
provider "aws" {
region = var.aws_region
}
# VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "main-vpc", Environment = var.environment }
}
# Public subnet
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
}
# EC2 instance
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
subnet_id = aws_subnet.public.id
tags = { Name = "web-server" }
}
# Variables
variable "aws_region" { default = "us-east-1" }
variable "environment" { default = "prod" }
variable "instance_type" { default = "t3.micro" }
# Outputs
output "instance_public_ip" {
value = aws_instance.web.public_ip
}
# Terraform workflow
terraform init # download providers
terraform plan # show what will change (dry run)
terraform apply # create/update infrastructure
terraform destroy # tear everything down
terraform state list # see managed resources
terraform import aws_s3_bucket.existing my-bucket # import existing resources
Terraform best practices
| Practice |
Why |
| Remote state (S3 + DynamoDB lock) |
Prevents simultaneous runs corrupting state |
| Workspaces or separate state per env |
Keep dev and prod state isolated |
| Use modules |
Reuse patterns (VPC module, ECS module) |
| Version-pin providers |
~> 5.0 prevents unexpected breaking changes |
Use terraform plan -out=tfplan in CI |
Apply only the reviewed plan |
sensitive = true on secret outputs |
Prevents secrets appearing in logs |
prevent_destroy lifecycle rule |
Protects databases from accidental deletion |
Phase 4 — Containers and Kubernetes
Containers are the atomic unit of modern cloud deployments. You must understand Docker before you can understand Kubernetes.
Docker fundamentals
# Multi-stage Dockerfile — smaller final image
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
RUN addgroup -S app && adduser -S app -G app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER app
EXPOSE 3000
CMD ["node", "dist/index.js"]
# Docker essentials
docker build -t my-app:v1.0 .
docker run -d -p 3000:3000 --name my-app my-app:v1.0
docker logs my-app -f
docker exec -it my-app sh
docker ps -a
docker images
# Docker Compose — local multi-service setup
docker compose up -d
docker compose logs -f app
docker compose down --volumes
Kubernetes essentials
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: my-registry/web-app:v1.2.0
ports:
- containerPort: 3000
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
---
apiVersion: v1
kind: Service
metadata:
name: web-app-svc
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 3000
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-svc
port:
number: 80
# kubectl essentials
kubectl get pods -n production -w
kubectl describe pod web-app-abc123 -n production
kubectl logs web-app-abc123 -n production --previous
kubectl exec -it web-app-abc123 -n production -- sh
kubectl apply -f deployment.yaml
kubectl rollout status deployment/web-app -n production
kubectl rollout undo deployment/web-app -n production # rollback
kubectl scale deployment web-app --replicas=5 -n production
kubectl top pods -n production # resource usage
Key Kubernetes concepts
| Concept |
Description |
| Pod |
Smallest unit — one or more containers that share network/storage |
| Deployment |
Manages a set of identical Pods; handles rolling updates |
| Service |
Stable network endpoint for a set of Pods (ClusterIP/NodePort/LoadBalancer) |
| Ingress |
HTTP routing rules — path/host → Service |
| ConfigMap |
Non-sensitive configuration as key-value pairs |
| Secret |
Sensitive config (passwords, tokens) — base64 encoded |
| Namespace |
Virtual cluster isolation within one cluster |
| HPA |
Horizontal Pod Autoscaler — scale based on CPU/memory/custom metrics |
| PersistentVolume |
Storage that outlives a Pod |
| Helm |
Package manager for Kubernetes — reusable chart templates |
Managed Kubernetes (cloud)
| Provider |
Service |
Key difference |
| AWS |
EKS |
Node groups (EC2) + Fargate (serverless nodes) |
| Azure |
AKS |
Deep Azure AD integration; virtual nodes |
| GCP |
GKE |
Autopilot mode (fully managed node pools) — GKE is most feature-complete |
Phase 5 — CI/CD and automation
Every cloud team runs automated pipelines that build, test, and deploy code without human intervention.
GitHub Actions (most common)
# .github/workflows/deploy.yml
name: Build and Deploy
on:
push:
branches: [main]
env:
AWS_REGION: us-east-1
ECR_REPOSITORY: my-app
EKS_CLUSTER: my-cluster
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
- name: Deploy to EKS
run: |
aws eks update-kubeconfig --region $AWS_REGION --name $EKS_CLUSTER
kubectl set image deployment/my-app \
my-app=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \
-n production
kubectl rollout status deployment/my-app -n production
CI/CD tools comparison
| Tool |
Best for |
Notes |
| GitHub Actions |
GitHub repos, modern teams |
Free tier generous; marketplace has 10k+ actions |
| GitLab CI |
GitLab repos, self-hosted |
Built into GitLab; powerful but verbose YAML |
| Jenkins |
Legacy enterprise, self-hosted |
Most flexible; highest maintenance overhead |
| AWS CodePipeline |
AWS-native pipelines |
Tight AWS integration; less familiar syntax |
| Azure DevOps |
Microsoft shops |
Full ALM suite; YAML + classic editor |
| ArgoCD |
GitOps on Kubernetes |
Pull-based; syncs K8s state from git |
| Tekton |
Cloud-native CI/CD on K8s |
Kubernetes-native; steeper learning curve |
Phase 6 — Cloud security
Security is not optional — it is your responsibility as a cloud engineer.
IAM principles
// Least-privilege IAM policy example (AWS)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-specific-bucket/*"
},
{
"Effect": "Deny",
"Action": "s3:DeleteObject",
"Resource": "*"
}
]
}
Top cloud security misconfigurations
| Misconfiguration |
Risk |
Fix |
| Public S3 bucket |
Any data exposed to internet |
Block public access at account level |
Overly permissive IAM (*:*) |
Privilege escalation |
Grant least privilege; use resource ARNs |
| No MFA on root account |
Full account takeover |
Enable MFA on root; never use root for daily work |
| Hardcoded credentials in code |
Secret theft via git |
Use IAM roles, Secrets Manager, or environment variables |
| Open security group (0.0.0.0/0 port 22) |
SSH brute-force |
Restrict to known IPs; use SSM Session Manager instead |
| Unencrypted EBS volumes |
Data exposure if snapshot shared |
Enable encryption at rest by default |
| No CloudTrail / audit logging |
No forensic trail |
Enable CloudTrail + S3 access logs + VPC Flow Logs |
| Unused access keys |
Credential theft |
Rotate keys every 90 days; delete unused keys |
Key security tools (AWS)
| Tool |
Purpose |
| AWS IAM Access Analyzer |
Find policies granting external access |
| AWS Security Hub |
Aggregated security findings across services |
| AWS GuardDuty |
Threat detection via ML (unusual API calls, crypto mining) |
| AWS Config |
Track configuration changes; alert on violations |
| AWS Macie |
Detect PII in S3 buckets |
| AWS Inspector |
Vulnerability scanning for EC2 and Lambda |
| AWS KMS |
Managed key management for encryption |
| AWS Secrets Manager |
Store, rotate, and access secrets programmatically |
Phase 7 — Monitoring and observability
You cannot fix what you cannot see. Cloud engineers own the observability stack.
Three pillars of observability
| Pillar |
What it tells you |
AWS service |
OSS alternative |
| Metrics |
Numerical values over time (CPU, request count, error rate) |
CloudWatch Metrics |
Prometheus + Grafana |
| Logs |
Time-stamped text output from applications |
CloudWatch Logs |
ELK / OpenSearch |
| Traces |
Request flow across microservices |
AWS X-Ray |
Jaeger / Zipkin / OTLP |
# Structured logging with Python — CloudWatch parses JSON natively
import json
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def handler(event, context):
logger.info(json.dumps({
"message": "Order processed",
"order_id": event["order_id"],
"user_id": event["user_id"],
"amount_cents": event["amount"],
"request_id": context.aws_request_id,
}))
Alerting patterns
| Alert type |
Example |
Tool |
| Static threshold |
CPU > 80% for 5 min |
CloudWatch Alarm |
| Anomaly detection |
Traffic 2σ below baseline |
CloudWatch Anomaly Detection |
| Error rate |
5xx rate > 1% |
Application Load Balancer metric |
| Latency |
p99 > 2s |
CloudWatch + X-Ray |
| Cost |
Spend > $X/day |
AWS Budgets |
| Security event |
Root login, IAM key creation |
CloudTrail + EventBridge |
Phase 8 — Python and Bash for cloud automation
Cloud engineers automate everything. Python is the scripting language of AWS (boto3), while Bash handles glue scripts and CI steps.
Bash for cloud automation
#!/usr/bin/env bash
set -euo pipefail # fail fast, undefined vars = error, pipe errors caught
# Deploy all Lambda functions in a directory
FUNCTIONS_DIR="./lambdas"
REGION="us-east-1"
for dir in "$FUNCTIONS_DIR"/*/; do
func_name=$(basename "$dir")
echo "Deploying $func_name..."
cd "$dir"
zip -r /tmp/"$func_name".zip . -x "*.pyc"
aws lambda update-function-code \
--function-name "$func_name" \
--zip-file fileb:///tmp/"$func_name".zip \
--region "$REGION"
cd -
done
echo "All functions deployed."
Python + boto3 for AWS automation
import boto3
from botocore.exceptions import ClientError
def stop_idle_ec2_instances(cpu_threshold: float = 5.0, days: int = 7) -> list[str]:
"""Stop EC2 instances with average CPU < threshold% over the past N days."""
ec2 = boto3.client("ec2", region_name="us-east-1")
cw = boto3.client("cloudwatch", region_name="us-east-1")
response = ec2.describe_instances(
Filters=[{"Name": "instance-state-name", "Values": ["running"]}]
)
stopped = []
for reservation in response["Reservations"]:
for instance in reservation["Instances"]:
instance_id = instance["InstanceId"]
# Get average CPU over the past N days
metrics = cw.get_metric_statistics(
Namespace="AWS/EC2",
MetricName="CPUUtilization",
Dimensions=[{"Name": "InstanceId", "Value": instance_id}],
StartTime=datetime.utcnow() - timedelta(days=days),
EndTime=datetime.utcnow(),
Period=3600 * 24,
Statistics=["Average"],
)
if not metrics["Datapoints"]:
continue
avg_cpu = sum(d["Average"] for d in metrics["Datapoints"]) / len(metrics["Datapoints"])
if avg_cpu < cpu_threshold:
ec2.stop_instances(InstanceIds=[instance_id])
stopped.append(instance_id)
print(f"Stopped {instance_id} (avg CPU: {avg_cpu:.1f}%)")
return stopped
Phase 9 — Databases and storage
Cloud engineers provision and operate managed databases — they rarely manage raw database engines on VMs.
Cloud database options
| Category |
AWS |
Azure |
GCP |
When to use |
| SQL (managed) |
RDS |
Azure SQL |
Cloud SQL |
Relational workloads, ACID transactions |
| SQL (serverless) |
Aurora Serverless v2 |
Azure SQL Serverless |
AlloyDB Omni |
Spiky traffic, cost optimization |
| Key-value / NoSQL |
DynamoDB |
Cosmos DB (Table API) |
Firestore / Bigtable |
High-scale, flexible schema |
| Cache |
ElastiCache (Redis) |
Azure Cache for Redis |
Memorystore |
Session, leaderboard, rate limiting |
| Search |
OpenSearch |
Azure AI Search |
Vertex AI Search |
Full-text search, analytics |
| Data warehouse |
Redshift |
Azure Synapse |
BigQuery |
Analytics, reporting, 100M+ rows |
| Graph |
Neptune |
Cosmos DB (Gremlin) |
— |
Social graphs, fraud detection |
| Time series |
Timestream |
— |
BigQuery |
IoT, metrics |
S3 storage classes and tiers
| Tier |
Access frequency |
Retrieval time |
Cost/GB/month |
| S3 Standard |
Frequent (daily) |
Immediate |
~$0.023 |
| S3 Standard-IA |
Infrequent (monthly) |
Immediate |
~$0.0125 |
| S3 Intelligent-Tiering |
Unknown |
Immediate |
~$0.023 + monitoring fee |
| S3 Glacier Instant |
Quarterly |
Milliseconds |
~$0.004 |
| S3 Glacier Flexible |
Yearly |
1–5 minutes |
~$0.0036 |
| S3 Glacier Deep Archive |
Rarely |
12 hours |
~$0.00099 |
# Move old objects to Glacier automatically via lifecycle rule
aws s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--lifecycle-configuration '{
"Rules": [{
"ID": "archive-old-logs",
"Status": "Enabled",
"Filter": {"Prefix": "logs/"},
"Transitions": [
{"Days": 30, "StorageClass": "STANDARD_IA"},
{"Days": 90, "StorageClass": "GLACIER"},
{"Days": 365, "StorageClass": "DEEP_ARCHIVE"}
]
}]
}'
Phase 10 — Architecture and cost optimization
Cloud engineers must be able to design systems that are reliable, scalable, and cost-effective.
AWS Well-Architected Framework
| Pillar |
Key principle |
| Operational excellence |
Automate, make small reversible changes, learn from failures |
| Security |
Least privilege, encrypt everything, enable traceability |
| Reliability |
Multi-AZ, health checks, auto-recovery, backups |
| Performance efficiency |
Right-size instances, use managed services, cache aggressively |
| Cost optimization |
Right-sizing, Reserved Instances, Spot, auto-scaling |
| Sustainability |
Minimize idle resources, use serverless, choose efficient regions |
Common architectures
# Three-tier web architecture (AWS)
Internet → Route 53 (DNS)
→ CloudFront (CDN + WAF)
→ ALB (Application Load Balancer)
→ [EC2 Auto Scaling Group / ECS Fargate] (app tier)
→ [RDS Multi-AZ + ElastiCache] (data tier)
→ [S3] (static assets, logs, backups)
→ [CloudWatch + SNS] (monitoring + alerting)
# Serverless architecture
API Gateway → Lambda → DynamoDB
→ SQS → Lambda (async processing)
→ S3 → Lambda (event-driven)
→ EventBridge → multiple consumers
Cost optimization strategies
| Strategy |
Typical saving |
How |
| Right-size instances |
20–40% |
Use CloudWatch + Cost Explorer to find oversized instances |
| Reserved Instances / Savings Plans |
40–72% |
Commit 1 or 3 years for stable workloads |
| Spot Instances |
60–90% |
For fault-tolerant, batch, or stateless workloads |
| Auto Scaling |
30–60% |
Scale down at night/weekends; don't pay for unused capacity |
| S3 lifecycle policies |
50–80% |
Move infrequent data to cheaper tiers automatically |
| Delete unused resources |
100% |
Snapshots, unattached EBS, idle load balancers, old AMIs |
| Serverless for spiky traffic |
Variable |
No idle cost — pay only per request |
| Multi-region CDN |
Indirect |
Reduce origin load; cheaper than serving from single region |
Full cloud technology map
FOUNDATIONS
├── Linux (bash, systemd, cron, file permissions)
├── Networking (VPC, subnets, DNS, TLS, load balancing)
└── Programming (Python, Bash, YAML/JSON)
CLOUD PLATFORMS
├── AWS (primary) — EC2, S3, RDS, Lambda, EKS, IAM, CloudFront
├── Azure — VMs, Blob, Azure SQL, AKS, Azure AD, Key Vault
└── GCP — Compute Engine, GCS, Cloud SQL, GKE, BigQuery
INFRASTRUCTURE AS CODE
├── Terraform (multi-cloud standard)
├── AWS CDK / CloudFormation (AWS native)
├── Pulumi (TypeScript/Python IaC)
└── Ansible (configuration management)
CONTAINERS
├── Docker (build, run, push images)
├── Kubernetes (orchestrate containers)
├── Helm (K8s package manager)
└── Managed K8s: EKS / AKS / GKE
CI/CD
├── GitHub Actions
├── GitLab CI
├── Jenkins
└── ArgoCD (GitOps)
OBSERVABILITY
├── CloudWatch (AWS native)
├── Prometheus + Grafana (OSS)
├── ELK / OpenSearch (logs)
└── AWS X-Ray / Jaeger (traces)
SECURITY
├── IAM / RBAC
├── Secrets Manager / Key Vault
├── GuardDuty / Security Hub
└── VPC Security Groups + NACLs
Realistic 15-month timeline
| Month |
Focus |
Milestone |
| 1–2 |
Linux + networking + AWS fundamentals |
Launch EC2, create S3 bucket, set up VPC |
| 3–4 |
AWS core services + IAM + CLI |
Deploy a 3-tier web app manually |
| 5–6 |
Terraform |
Infrastructure the previous app; remote state |
| 7–8 |
Docker + Kubernetes basics |
Containerize the app; deploy to kind/minikube |
| 9–10 |
EKS / managed K8s + Helm |
Deploy to EKS; write a Helm chart |
| 11 |
CI/CD with GitHub Actions |
Automated build → push → deploy pipeline |
| 12 |
Cloud security + monitoring |
GuardDuty, CloudWatch dashboards, alerts |
| 13–14 |
Python automation + advanced architecture |
boto3 scripts; design a multi-AZ system |
| 15 |
Certifications + portfolio |
AWS Solutions Architect – Associate or CKA |
Portfolio projects
| Project |
Skills demonstrated |
Complexity |
| Static website on S3 + CloudFront |
S3, CloudFront, Route 53, ACM |
Beginner |
| 3-tier app: EC2 + RDS + ALB |
VPC, EC2, RDS, security groups, ALB |
Beginner |
| Serverless REST API |
Lambda, API Gateway, DynamoDB, IAM |
Intermediate |
| Terraform module library |
IaC, modules, remote state, CI |
Intermediate |
| EKS microservices with Helm |
EKS, Helm, Ingress, HPA, Secrets |
Advanced |
| GitOps pipeline with ArgoCD |
EKS, ArgoCD, GitHub Actions, ECR |
Advanced |
| Cost optimization bot |
Python, boto3, CloudWatch, Lambda |
Advanced |
Certifications
| Certification |
Level |
Provider |
Why get it |
| AWS Cloud Practitioner |
Beginner |
AWS |
Foundation cert; validates cloud basics |
| AWS Solutions Architect – Associate |
Intermediate |
AWS |
Most in-demand cloud cert globally |
| AWS DevOps Engineer – Professional |
Advanced |
AWS |
Pipeline + deployment mastery |
| CKA (Certified Kubernetes Administrator) |
Intermediate |
CNCF |
Proves real K8s skills; hands-on exam |
| CKAD (Certified Kubernetes App Developer) |
Intermediate |
CNCF |
App-focused K8s cert |
| Terraform Associate |
Beginner-Intermediate |
HashiCorp |
Validates IaC skills, vendor-neutral |
| Azure Administrator (AZ-104) |
Intermediate |
Microsoft |
Required for Azure roles |
| GCP Associate Cloud Engineer |
Intermediate |
Google |
Required for GCP roles |
| AWS Security Specialty |
Advanced |
AWS |
Security-focused cloud roles |
Recommendation: AWS SAA-C03 first, then CKA if you're on a Kubernetes-heavy team, then Terraform Associate.
Cloud engineer roles and salaries
| Role |
Focus |
Avg salary (US) |
Entry path |
| Cloud Engineer |
Provision + maintain cloud infrastructure |
$110–140k |
AWS SAA + portfolio |
| DevOps Engineer |
CI/CD, automation, reliability |
$115–145k |
AWS SAA + K8s + GitHub Actions |
| Site Reliability Engineer (SRE) |
Uptime, on-call, error budgets |
$130–160k |
2–3 years ops experience |
| Platform Engineer |
Internal developer platforms, K8s |
$125–155k |
K8s expert + IaC |
| Cloud Architect |
Design, not implement |
$150–200k |
5+ years cloud + multi-service expertise |
| Cloud Security Engineer |
IAM, compliance, vulnerability |
$130–165k |
Security + cloud certifications |
Common mistakes
| Mistake |
Why it hurts |
What to do instead |
| Clicking through the console instead of scripting |
Not repeatable, not auditable |
Write Terraform or CLI scripts from day one |
| Using the AWS root account for daily work |
Catastrophic if compromised |
Create an IAM admin user; lock root away |
| Skipping networking fundamentals |
Cannot debug VPC, security groups, or DNS |
Understand subnets, routing, NACLs before touching EKS |
| Learning a cloud service without the billing page |
Bill shock |
Always check Free Tier limits; set billing alerts |
| Going deep on one cloud, ignoring others |
Limits job opportunities |
Learn AWS first, then understand Azure/GCP parallels |
| Not practicing hands-on (watching tutorials only) |
Tutorial knowledge fades fast |
Deploy every concept you learn |
| Ignoring security until the end |
Security is a day-1 concern |
Apply least privilege and encryption from the start |
| Over-engineering with microservices early |
Complexity without benefit |
Start with a monolith; break it up when traffic justifies it |
Cloud vs related roles
| Role |
Overlap with cloud |
Key difference |
| Cloud Engineer |
— |
Provision and maintain cloud infra |
| DevOps Engineer |
High |
More focused on pipelines and developer experience |
| SRE |
High |
More focused on reliability and on-call rotations |
| Backend Developer |
Medium |
Writes application code; cloud is consumed, not configured |
| Data Engineer |
Medium |
Builds data pipelines; uses cloud storage and compute services |
| Network Engineer |
Medium |
Traditional network hardware; cloud networking is a subset |
FAQ
Do I need a computer science degree to become a cloud engineer?
No. Cloud engineering is highly skill-based. Certifications (AWS SAA, CKA) and a hands-on portfolio carry more weight in hiring than a degree. Many successful cloud engineers come from networking, sysadmin, or self-taught backgrounds.
Which cloud should I learn first — AWS, Azure, or GCP?
AWS. It has the largest market share (~33%), the most job listings, the most learning resources, and the most community support. Once you understand AWS deeply, Azure and GCP are much easier to pick up because the underlying concepts are the same.
Is Kubernetes necessary for a cloud engineering job?
Yes, for most mid-to-senior cloud roles. Kubernetes is the standard for container orchestration and appears in the majority of cloud job descriptions. Learn Docker first, then Kubernetes.
How long does it take to get the AWS Solutions Architect – Associate certification?
Most people with some cloud exposure pass in 6–10 weeks of study. Allow longer if you are starting from zero Linux/networking knowledge. The exam costs ~$150 USD and is available at Pearson Vue testing centres or online.
Is Terraform the only IaC tool I need to learn?
Terraform is the industry standard and the safest single tool to learn. AWS CDK (TypeScript/Python) is popular for AWS-only shops and is worth knowing. Pulumi is gaining traction. Ansible covers configuration management (not just provisioning). Start with Terraform.
What is the difference between a cloud engineer and a DevOps engineer?
In practice, the roles overlap significantly — many job postings use the terms interchangeably. A cloud engineer typically focuses on provisioning and managing cloud infrastructure (VPCs, managed services, IaC), while a DevOps engineer focuses more on CI/CD pipelines, developer workflows, and the deployment process. Most teams expect cloud engineers to know DevOps tools and vice versa.