Toolmingo
Guides20 min read

AWS Tutorial for Beginners (2025): Learn Amazon Web Services Step by Step

Complete AWS tutorial for beginners. Learn EC2, S3, RDS, Lambda, IAM, VPC and more. Free guide with real examples and hands-on exercises.

Amazon Web Services (AWS) is the world's largest cloud platform, powering millions of companies from Netflix and Airbnb to NASA. Learning AWS opens doors to DevOps, backend, cloud architect, and SRE roles — and the free tier gives you enough resources to learn without paying a cent. This tutorial takes you from zero to deploying real infrastructure, step by step.

What you'll learn

Topic What you'll be able to do
Setup Create a free AWS account and configure the CLI
IAM Manage users, roles, and permissions securely
EC2 Launch, connect to, and manage virtual servers
S3 Store and serve files at massive scale
RDS Run managed relational databases
Lambda Run code without managing servers
VPC Build isolated network environments
CloudWatch Monitor and alert on your infrastructure
Deployment Build a real 3-tier web app on AWS

AWS vs other cloud providers

Feature AWS Azure Google Cloud
Market share ~32% ~22% ~12%
Services 200+ 200+ 150+
Best for Broadest ecosystem Microsoft/enterprise Data/ML
Free tier 12 months + always free 12 months + always free $300 credit
Certifications CCP, SAA, SAP, etc. AZ-900, AZ-104, etc. ACE, PCE, etc.
Job market Most jobs #2 #3
Learning curve Steep (most services) Moderate Moderate

1. Setting up AWS

Create a free account

  1. Go to aws.amazon.com and click Create a Free Account
  2. Enter email, choose account name, set password
  3. Enter payment info (required, but free tier won't charge you)
  4. Verify phone number
  5. Select Basic Support (free)
  6. Choose your nearest region (US East N. Virginia = most services available)

AWS Free Tier highlights

Service Free tier
EC2 750 hrs/mo t2.micro or t3.micro (12 months)
S3 5 GB storage, 20k GET, 2k PUT requests
RDS 750 hrs/mo db.t3.micro (12 months)
Lambda 1M requests/mo + 400k GB-seconds (always free)
CloudWatch 10 custom metrics, 5 GB logs (always free)
DynamoDB 25 GB storage, 25 RCU/WCU (always free)

Install and configure AWS CLI

# macOS (Homebrew)
brew install awscli

# Windows (download installer from aws.amazon.com/cli)
# Or via winget:
winget install Amazon.AWSCLI

# Linux
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

# Verify
aws --version
# aws-cli/2.x.x Python/3.x.x ...

Configure with your credentials (IAM user access key — we'll create one in the next section):

aws configure
# AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
# AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# Default region name [None]: us-east-1
# Default output format [None]: json

2. IAM — Identity and Access Management

IAM is how AWS controls who can do what to which resources. Get this wrong and you either lock yourself out or leave the account wide open.

Core IAM concepts

Concept What it is Example
Root user Account owner, all permissions Only for billing and initial setup
IAM user A person or app with credentials alice@company.com
Group Collection of users with shared permissions developers, admins
Policy JSON document defining permissions AmazonS3FullAccess
Role Temporary permissions assumed by services/users EC2 role to read S3
MFA Multi-factor authentication App-based TOTP

Create your first IAM user (for daily work — never use root)

# In AWS console: IAM → Users → Add users
# Or via CLI (after root configures CLI):

# Create a user
aws iam create-user --user-name myuser

# Attach a policy
aws iam attach-user-policy \
  --user-name myuser \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

# Create access keys for CLI
aws iam create-access-key --user-name myuser

Least-privilege policy example

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::my-bucket/*"
    },
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::my-bucket"
    }
  ]
}

IAM roles (for services)

Roles let AWS services (like EC2 or Lambda) access other services without embedding credentials:

# Create a role that EC2 can assume
aws iam create-role \
  --role-name EC2-S3-ReadOnly \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

# Attach S3 read policy to the role
aws iam attach-role-policy \
  --role-name EC2-S3-ReadOnly \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

IAM security best practices

  • Enable MFA on root and all IAM users
  • Never use root for daily work
  • Grant least privilege — only what's needed
  • Use roles for services, not access keys
  • Rotate access keys every 90 days
  • Use IAM Access Analyzer to find overly-permissive policies

3. EC2 — Elastic Compute Cloud

EC2 gives you virtual servers (called instances) in the cloud. You choose the OS, size, and configuration.

EC2 instance types

Family Use case Example sizes
t3/t4g General purpose, burstable (dev/test) t3.micro, t3.small
m7i Balanced CPU/memory (web servers) m7i.large, m7i.xlarge
c7i Compute-intensive (video encoding, HPC) c7i.2xlarge
r7i Memory-intensive (databases, caches) r7i.4xlarge
p4d GPU instances (ML training) p4d.24xlarge
i4i Storage-optimized (high I/O DBs) i4i.large

Launch your first EC2 instance (CLI)

# Find the latest Amazon Linux 2023 AMI
aws ec2 describe-images \
  --owners amazon \
  --filters "Name=name,Values=al2023-ami-*-x86_64" \
  --query "Images | sort_by(@, &CreationDate) | [-1].ImageId" \
  --output text

# Create a key pair for SSH access
aws ec2 create-key-pair \
  --key-name my-key \
  --query "KeyMaterial" \
  --output text > my-key.pem

chmod 400 my-key.pem

# Launch an instance
aws ec2 run-instances \
  --image-id ami-0c02fb55956c7d316 \
  --instance-type t3.micro \
  --key-name my-key \
  --count 1 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=my-server}]'

# Get the public IP
aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=my-server" \
  --query "Reservations[0].Instances[0].PublicIpAddress" \
  --output text

# Connect via SSH
ssh -i my-key.pem ec2-user@<PUBLIC_IP>

Security Groups (EC2 firewall)

Security groups control inbound and outbound traffic to your instances:

# Create a security group
aws ec2 create-security-group \
  --group-name web-sg \
  --description "Web server security group"

# Allow SSH from your IP
aws ec2 authorize-security-group-ingress \
  --group-name web-sg \
  --protocol tcp \
  --port 22 \
  --cidr YOUR_IP/32

# Allow HTTP from anywhere
aws ec2 authorize-security-group-ingress \
  --group-name web-sg \
  --protocol tcp \
  --port 80 \
  --cidr 0.0.0.0/0

# Allow HTTPS from anywhere
aws ec2 authorize-security-group-ingress \
  --group-name web-sg \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

Install a web server on EC2

# After SSHing into the instance:
sudo dnf update -y
sudo dnf install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# Your site is now live at http://PUBLIC_IP

EC2 pricing models

Model How it works Best for Savings
On-Demand Pay per second, no commitment Dev, unpredictable load
Reserved 1 or 3 year commitment Steady baseline load Up to 72%
Spot Use unused AWS capacity Batch, fault-tolerant Up to 90%
Savings Plans Flexible commitment by $/hr Mix of instance types Up to 66%
Dedicated Hosts Physical server for you Compliance Varies

4. S3 — Simple Storage Service

S3 stores any file at virtually unlimited scale. It's object storage — not a file system.

Core S3 concepts

Concept What it is
Bucket Top-level container (globally unique name)
Object A file + metadata stored in a bucket
Key The object's full path (e.g. images/cat.jpg)
Prefix Folder-like grouping (not real folders)
ACL Access control list for bucket/object
Versioning Keep multiple versions of objects

Create a bucket and upload files

# Create a bucket (name must be globally unique)
aws s3 mb s3://my-unique-bucket-name-2025

# Upload a single file
aws s3 cp ./photo.jpg s3://my-unique-bucket-name-2025/

# Upload an entire folder
aws s3 sync ./my-folder s3://my-unique-bucket-name-2025/my-folder/

# List bucket contents
aws s3 ls s3://my-unique-bucket-name-2025/

# Download a file
aws s3 cp s3://my-unique-bucket-name-2025/photo.jpg ./downloaded.jpg

# Delete an object
aws s3 rm s3://my-unique-bucket-name-2025/photo.jpg

# Delete a bucket and all contents
aws s3 rb s3://my-unique-bucket-name-2025 --force

Host a static website on S3

# Enable static website hosting
aws s3 website s3://my-site-bucket/ \
  --index-document index.html \
  --error-document error.html

# Make objects publicly readable (bucket policy)
aws s3api put-bucket-policy \
  --bucket my-site-bucket \
  --policy '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-site-bucket/*"
    }]
  }'

# Upload your site
aws s3 sync ./dist s3://my-site-bucket/

# URL format: http://my-site-bucket.s3-website-us-east-1.amazonaws.com

S3 storage classes

Class Use case Retrieval Cost
Standard Frequently accessed data Instant High
Standard-IA Infrequent access Instant Medium
One Zone-IA Infrequent, single AZ Instant Lower
Glacier Instant Archive, rare access Instant Low
Glacier Flexible Archive, occasional Minutes–hours Very low
Glacier Deep Archive Long-term archive Hours Lowest
Intelligent-Tiering Unknown access pattern Instant Auto

Lifecycle rules (auto-archive old objects)

{
  "Rules": [
    {
      "ID": "archive-old-logs",
      "Status": "Enabled",
      "Filter": {"Prefix": "logs/"},
      "Transitions": [
        {"Days": 30, "StorageClass": "STANDARD_IA"},
        {"Days": 90, "StorageClass": "GLACIER"}
      ],
      "Expiration": {"Days": 365}
    }
  ]
}

5. RDS — Relational Database Service

RDS runs managed databases so you don't have to patch, backup, or set up replication yourself.

Supported database engines

Engine Best for
MySQL Web apps, WordPress
PostgreSQL Advanced SQL features, JSON, extensions
MariaDB MySQL-compatible, open-source
SQL Server Windows/.NET applications
Oracle Enterprise legacy systems
Aurora MySQL MySQL-compatible, 5× faster
Aurora PostgreSQL PostgreSQL-compatible, 3× faster

Create a PostgreSQL RDS instance

# Create a subnet group first
aws rds create-db-subnet-group \
  --db-subnet-group-name my-db-subnet \
  --db-subnet-group-description "My DB subnet group" \
  --subnet-ids subnet-abc123 subnet-def456

# Launch an RDS instance (free tier eligible)
aws rds create-db-instance \
  --db-instance-identifier my-postgres \
  --db-instance-class db.t3.micro \
  --engine postgres \
  --engine-version "15.4" \
  --master-username admin \
  --master-user-password MyPassword123! \
  --allocated-storage 20 \
  --no-publicly-accessible \
  --db-subnet-group-name my-db-subnet \
  --backup-retention-period 7

# Check status
aws rds describe-db-instances \
  --db-instance-identifier my-postgres \
  --query "DBInstances[0].DBInstanceStatus"

Connect to RDS from EC2

# Get the endpoint
aws rds describe-db-instances \
  --db-instance-identifier my-postgres \
  --query "DBInstances[0].Endpoint.Address" \
  --output text

# Connect with psql (on EC2 in same VPC)
psql -h <ENDPOINT> -U admin -d postgres

# From Python application
import psycopg2
conn = psycopg2.connect(
    host="my-postgres.xxxx.us-east-1.rds.amazonaws.com",
    database="mydb",
    user="admin",
    password="MyPassword123!"
)

RDS key features

Feature What it does
Multi-AZ Automatic failover to standby in another AZ
Read Replicas Scale reads across multiple replicas
Automated backups Daily snapshots, point-in-time recovery
Encryption AES-256 at rest, TLS in transit
Performance Insights Query-level performance monitoring
Enhanced Monitoring OS-level metrics every second

6. Lambda — Serverless Functions

Lambda runs your code in response to events without you managing any servers. You pay only for execution time.

Lambda basics

Concept Detail
Function Your code + configuration
Handler Entry point (e.g. lambda_function.lambda_handler)
Event JSON input that triggers the function
Runtime Python 3.12, Node.js 20, Java 21, Go, etc.
Memory 128 MB to 10 GB
Timeout Max 15 minutes
Invocation Synchronous (API GW) or async (S3, SQS)

Your first Lambda function

# lambda_function.py
import json

def lambda_handler(event, context):
    name = event.get("name", "World")
    return {
        "statusCode": 200,
        "body": json.dumps({"message": f"Hello, {name}!"})
    }

Deploy via CLI:

# Package the function
zip function.zip lambda_function.py

# Create the function
aws lambda create-function \
  --function-name hello-world \
  --runtime python3.12 \
  --zip-file fileb://function.zip \
  --handler lambda_function.lambda_handler \
  --role arn:aws:iam::ACCOUNT_ID:role/lambda-basic-role

# Invoke it
aws lambda invoke \
  --function-name hello-world \
  --payload '{"name": "AWS"}' \
  response.json

cat response.json
# {"statusCode": 200, "body": "{\"message\": \"Hello, AWS!\"}"}

Lambda triggers

Trigger Use case
API Gateway / Function URL HTTP endpoints
S3 Process uploads (resize images, parse CSVs)
SQS Process queued messages
EventBridge Scheduled tasks (cron)
DynamoDB Streams React to DB changes
SNS Fan-out notifications
Cognito Custom auth flows

S3-triggered Lambda (resize images on upload)

import boto3
from PIL import Image
import io

s3 = boto3.client('s3')

def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']

    # Download original
    response = s3.get_object(Bucket=bucket, Key=key)
    image_data = response['Body'].read()

    # Resize
    image = Image.open(io.BytesIO(image_data))
    image.thumbnail((800, 800))

    # Save resized version
    buffer = io.BytesIO()
    image.save(buffer, format='JPEG')
    buffer.seek(0)

    # Upload to thumbnails bucket
    s3.put_object(
        Bucket='my-thumbnails',
        Key=key,
        Body=buffer,
        ContentType='image/jpeg'
    )

    return {'statusCode': 200}

7. VPC — Virtual Private Cloud

A VPC is your own isolated network inside AWS. All other services run inside a VPC.

VPC components

Component What it is
VPC Your private network (CIDR e.g. 10.0.0.0/16)
Subnet Subdivision of a VPC (public or private)
Internet Gateway Connects VPC to the internet
NAT Gateway Lets private subnets reach the internet (not vice versa)
Route Table Rules for directing network traffic
Security Group Stateful instance-level firewall
NACL Stateless subnet-level firewall
VPC Peering Connect two VPCs together
Endpoint Private connection to AWS services (no internet)

Security Group vs NACL

Feature Security Group NACL
Level Instance Subnet
State Stateful Stateless
Rules Allow only Allow and deny
Evaluation All rules evaluated Rules evaluated in order (lowest number first)
Default Deny all in, allow all out Allow all in and out
Use case Primary firewall Subnet-level blocking

Create a VPC with public and private subnets

# Create VPC
VPC_ID=$(aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --query "Vpc.VpcId" --output text)

aws ec2 create-tags \
  --resources $VPC_ID \
  --tags Key=Name,Value=my-vpc

# Create public subnet
PUBLIC_SUBNET=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --query "Subnet.SubnetId" --output text)

# Create private subnet
PRIVATE_SUBNET=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.2.0/24 \
  --availability-zone us-east-1b \
  --query "Subnet.SubnetId" --output text)

# Create and attach internet gateway
IGW=$(aws ec2 create-internet-gateway \
  --query "InternetGateway.InternetGatewayId" --output text)

aws ec2 attach-internet-gateway \
  --vpc-id $VPC_ID \
  --internet-gateway-id $IGW

# Create route table for public subnet
RT=$(aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --query "RouteTable.RouteTableId" --output text)

aws ec2 create-route \
  --route-table-id $RT \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id $IGW

aws ec2 associate-route-table \
  --subnet-id $PUBLIC_SUBNET \
  --route-table-id $RT

8. CloudWatch — Monitoring and Logging

CloudWatch collects metrics, logs, and events from your AWS resources.

Key CloudWatch features

Feature Use case
Metrics CPU, memory, request count, latency
Alarms Alert when metric crosses threshold
Logs Collect and search log streams
Log Insights Query logs with SQL-like syntax
Dashboards Custom metrics dashboards
Events / EventBridge Trigger actions on schedule or events
Synthetics Synthetic canary monitoring

Create an alarm for EC2 CPU

aws cloudwatch put-metric-alarm \
  --alarm-name "high-cpu" \
  --alarm-description "CPU above 80%" \
  --metric-name CPUUtilization \
  --namespace AWS/EC2 \
  --statistic Average \
  --period 300 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2 \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --alarm-actions arn:aws:sns:us-east-1:ACCOUNT:my-topic

Query CloudWatch Logs with Log Insights

-- Find all 5xx errors in the last hour
fields @timestamp, @message
| filter @message like /5[0-9][0-9]/
| sort @timestamp desc
| limit 100

-- Count errors by minute
fields @timestamp
| filter @message like /ERROR/
| stats count() as errors by bin(1m)
| sort @timestamp desc

-- Find slowest Lambda executions
fields @timestamp, @duration, @requestId
| filter @type = "REPORT"
| sort @duration desc
| limit 20

9. Project: Deploy a 3-Tier Web App on AWS

Let's put it all together — a Node.js API + PostgreSQL + S3 for static assets.

Architecture

Internet
   │
   ▼
[CloudFront] ──── [S3 Static Site]
   │
   ▼
[Application Load Balancer] (public subnet)
   │
   ▼
[EC2 Auto Scaling Group] (private subnet)
   │
   ├── [RDS PostgreSQL] (private subnet)
   └── [S3 Bucket] (via VPC Endpoint)

Step 1: Create the VPC

Use the VPC wizard in the console:

  • VPC CIDR: 10.0.0.0/16
  • 2 public subnets (for ALB): 10.0.1.0/24, 10.0.2.0/24
  • 2 private subnets (for EC2+RDS): 10.0.3.0/24, 10.0.4.0/24
  • Enable NAT Gateway in one public subnet

Step 2: Launch RDS in private subnet

aws rds create-db-instance \
  --db-instance-identifier app-db \
  --db-instance-class db.t3.micro \
  --engine postgres \
  --master-username appuser \
  --master-user-password "SecurePass123!" \
  --allocated-storage 20 \
  --vpc-security-group-ids sg-rds-id \
  --db-subnet-group-name my-private-db-subnet \
  --no-publicly-accessible

Step 3: Create an EC2 launch template

cat > user-data.sh << 'EOF'
#!/bin/bash
dnf update -y
dnf install -y nodejs npm
npm install -g pm2

# Clone your app
git clone https://github.com/yourrepo/api.git /app
cd /app
npm install
pm2 start app.js --name api
pm2 startup systemd
pm2 save
EOF

aws ec2 create-launch-template \
  --launch-template-name app-lt \
  --launch-template-data '{
    "ImageId": "ami-0c02fb55956c7d316",
    "InstanceType": "t3.micro",
    "IamInstanceProfile": {"Name": "app-instance-profile"},
    "SecurityGroupIds": ["sg-app-id"],
    "UserData": "'$(base64 -w0 user-data.sh)'"
  }'

Step 4: Create Auto Scaling Group

aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name app-asg \
  --launch-template LaunchTemplateName=app-lt,Version='$Latest' \
  --min-size 2 \
  --max-size 10 \
  --desired-capacity 2 \
  --target-group-arns arn:aws:elasticloadbalancing:... \
  --vpc-zone-identifier "subnet-private1,subnet-private2"

Step 5: Host frontend on S3 + CloudFront

# Build and deploy frontend
npm run build
aws s3 sync dist/ s3://my-app-frontend/

# Create CloudFront distribution pointing to S3
# (use console or CloudFormation for complex config)

10. Other Essential AWS Services

DynamoDB (NoSQL)

import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('users')

# Put item
table.put_item(Item={
    'user_id': 'u001',
    'name': 'Alice',
    'email': 'alice@example.com'
})

# Get item
response = table.get_item(Key={'user_id': 'u001'})
user = response['Item']

# Query (requires index on email)
response = table.query(
    IndexName='email-index',
    KeyConditionExpression='email = :email',
    ExpressionAttributeValues={':email': 'alice@example.com'}
)

SQS (Message Queue)

import boto3

sqs = boto3.client('sqs')
queue_url = 'https://sqs.us-east-1.amazonaws.com/123456789012/my-queue'

# Send a message
sqs.send_message(
    QueueUrl=queue_url,
    MessageBody='{"job": "resize-image", "key": "uploads/photo.jpg"}'
)

# Receive and process messages
response = sqs.receive_message(
    QueueUrl=queue_url,
    MaxNumberOfMessages=10,
    WaitTimeSeconds=20  # Long polling
)

for msg in response.get('Messages', []):
    print(msg['Body'])
    sqs.delete_message(
        QueueUrl=queue_url,
        ReceiptHandle=msg['ReceiptHandle']
    )

SNS (Pub/Sub)

import boto3

sns = boto3.client('sns')

# Create a topic
topic = sns.create_topic(Name='alerts')
topic_arn = topic['TopicArn']

# Subscribe an email
sns.subscribe(
    TopicArn=topic_arn,
    Protocol='email',
    Endpoint='admin@example.com'
)

# Publish a message
sns.publish(
    TopicArn=topic_arn,
    Message='High CPU alert on instance i-1234567890',
    Subject='AWS Alert'
)

API Gateway

API Gateway turns Lambda functions into HTTP APIs:

# Create a REST API
aws apigateway create-rest-api --name my-api

# Or use HTTP API (simpler, cheaper)
aws apigatewayv2 create-api \
  --name my-http-api \
  --protocol-type HTTP \
  --target arn:aws:lambda:us-east-1:ACCOUNT:function:my-function

AWS services quick reference

Service Category What it does
EC2 Compute Virtual machines
ECS / EKS Compute Docker / Kubernetes managed
Lambda Compute Serverless functions
Fargate Compute Serverless containers
S3 Storage Object storage
EBS Storage Block storage for EC2
EFS Storage Shared file system
RDS Database Managed relational DB
DynamoDB Database Managed NoSQL
ElastiCache Database Managed Redis/Memcached
VPC Networking Private network
Route 53 Networking DNS + health checks
CloudFront Networking CDN
ALB / NLB Networking Load balancers
IAM Security Identity + access management
KMS Security Key management
Secrets Manager Security Store and rotate secrets
CloudWatch Monitoring Metrics, logs, alarms
CloudTrail Auditing API call history
SQS Messaging Message queue
SNS Messaging Pub/sub notifications
EventBridge Messaging Event bus
CodePipeline DevOps CI/CD pipeline
CodeBuild DevOps Build service
CloudFormation DevOps Infrastructure as code
Cognito Auth User pools + identity

AWS regions and availability zones

Region (e.g. us-east-1 / N. Virginia)
├── Availability Zone A (us-east-1a)
│   ├── Data Center 1
│   └── Data Center 2
├── Availability Zone B (us-east-1b)
│   └── Data Center 3
└── Availability Zone C (us-east-1c)
    └── Data Center 4
Region Code Notes
US East (N. Virginia) us-east-1 Cheapest, most services
US West (Oregon) us-west-2 Good West Coast option
EU (Ireland) eu-west-1 Popular for Europe
EU (Frankfurt) eu-central-1 GDPR-friendly
Asia Pacific (Singapore) ap-southeast-1 SEA/ANZ
Asia Pacific (Tokyo) ap-northeast-1 Japan

Rule of thumb: Deploy in the region closest to your users. Use us-east-1 for learning (cheapest and most services).


AWS learning path

Stage Topics Timeline
1. Foundations Console navigation, IAM, S3, EC2 basics Week 1–2
2. Core services RDS, Lambda, VPC, CloudWatch Week 3–4
3. Application deployment ALB, Auto Scaling, ECS/Fargate Week 5–6
4. DevOps CodePipeline, CloudFormation, Terraform Week 7–8
5. Security & cost KMS, WAF, Cost Explorer, Trusted Advisor Week 9–10
6. Certification AWS Cloud Practitioner (CCP) or SAA Month 3
7. Specialisation Databases / Machine Learning / Security path Month 4–6

AWS Certification roadmap

Cert Code Level Who it's for
Cloud Practitioner CLF-C02 Foundational Everyone starting AWS
Solutions Architect Associate SAA-C03 Associate Architects, engineers
Developer Associate DVA-C02 Associate Developers
SysOps Administrator SOA-C02 Associate Ops/SRE
Solutions Architect Professional SAP-C02 Professional Senior architects
DevOps Engineer Professional DOP-C02 Professional DevOps engineers

Common mistakes

Mistake Problem Fix
Using root account for daily work Full access compromise = game over Create IAM user immediately
Public S3 buckets Data breaches Default deny, use signed URLs
Hardcoded AWS credentials Keys leaked to GitHub Use IAM roles, Secrets Manager
Single Availability Zone One outage kills everything Deploy to 2+ AZs
No VPC for databases DB exposed to internet RDS in private subnet only
Default security groups Too permissive by default Create custom security groups
No backups configured Data loss is permanent Enable automated backups on RDS
Not monitoring costs Surprise bill at month end Set billing alarms in CloudWatch

AWS vs related terms

Term What it is
AWS Amazon's cloud platform (the whole thing)
EC2 Virtual machines on AWS
S3 Object storage on AWS
IAM Access control for AWS
VPC Private network on AWS
CloudFormation AWS-native Infrastructure as Code
Terraform Open-source IaC that supports AWS (and others)
Kubernetes (EKS) Container orchestration on AWS
Serverless Lambda + API Gateway pattern
IaC Code that defines infrastructure (CloudFormation, Terraform)
Azure Microsoft's cloud platform (competitor to AWS)
GCP Google's cloud platform (competitor to AWS)

Frequently asked questions

Is AWS free to learn? Yes — the AWS Free Tier gives 12 months of free EC2 (t2.micro), S3, RDS and more. Set billing alarms immediately and keep resources small. Always terminate instances and delete data when done experimenting.

Which AWS services should I learn first? Start with IAM (security foundation), then S3 (simplest service), then EC2 (virtual machines). Once comfortable, add RDS and Lambda. Everything else builds on those five.

How long does it take to learn AWS? 2–4 weeks to get comfortable with core services. 2–3 months to pass the AWS Solutions Architect Associate exam. 6+ months to feel confident architecting production systems.

Do I need Linux knowledge for AWS? Yes — EC2 instances typically run Linux. Learn basic navigation, file management, and systemd before diving into EC2. You can also start with managed services (Lambda, RDS) to delay the Linux learning curve.

What's the difference between AWS regions and availability zones? A region is a geographic area (e.g. us-east-1 / North Virginia). Each region has 2–7 availability zones (AZs), which are separate data centres a few miles apart. Deploy across 2+ AZs for high availability — if one data centre fails, the other keeps running.

Should I use the AWS Console or CLI? Learn both. The console is great for exploring and understanding services visually. The CLI is essential for automation and repeatable deployments. AWS CloudFormation or Terraform takes you further — they let you define entire infrastructure in code.

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools