DevOps from Zero to Hero: AWS from Scratch
Support this blog
If you find this content useful, consider supporting the blog.
Introduction
Welcome to article six of the DevOps from Zero to Hero series. We have covered DevOps concepts, built a TypeScript API, learned version control, automated testing, and set up CI/CD. Now it is time to talk about the cloud. We will set up an AWS account the right way, configure IAM with least privilege, install the AWS CLI, understand VPC networking and security groups, and overview the key services we will use throughout the rest of this series.
Let’s get into it.
Creating your AWS account
Go to aws.amazon.com and click “Create an AWS Account.” You need an email, a credit card, and a phone number. AWS will not charge you for creating the account, and many services have a free tier for 12 months. When you create the account, you get a root user with unrestricted access to everything. Never use it for daily work. Here is what to do immediately:
- Enable MFA on root: Go to IAM, click on the root user, and set up multi-factor authentication with an authenticator app like Google Authenticator or Authy
- Create an IAM admin user: We will cover this next. From here on, you log in with the IAM user, not root
- Set up a billing alarm: Go to CloudWatch and create an alarm when estimated charges exceed $10
- Store root credentials securely: Save the password and MFA recovery codes in a password manager, then stop using root
IAM: Identity and Access Management
IAM controls who can do what in your AWS account. There are four main concepts:
- Users: Individual people or applications, each with their own credentials
- Groups: Collections of users. Attach permissions to the group, then add users to it
- Roles: Temporary identities assumed by users, services, or applications (e.g., an EC2 instance assuming a role to read from S3)
- Policies: JSON documents defining what actions are allowed or denied on which resources
The principle of least privilege: give every identity only the permissions it needs. If credentials get leaked, the blast radius is limited to what that identity was allowed to do.
Creating an IAM admin user:
- Go to IAM console, click “Users,” then “Create user.”
-
Name it
admin, check “Provide user access to the AWS Management Console.” -
Attach the
AdministratorAccesspolicy directly. - Save the sign-in URL and credentials, log in as this user, and enable MFA.
Writing a custom IAM policy:
Here is a least-privilege policy allowing upload and download from a specific S3 bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3ReadWrite",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-app-uploads",
"arn:aws:s3:::my-app-uploads/*"
]
}
]
}
- Version: Always
"2012-10-17"(the policy language version, not a date you change)- Effect:
"Allow"or"Deny". Deny always wins- Action: Specific API calls being permitted
- Resource: AWS resources identified by ARN. Note we need both the bucket and
/*for objects inside it
IAM best practices:
- Never use root except for billing and account emergencies
- Use groups to manage permissions, not individual user policies
- Use roles instead of access keys for EC2, Lambda, and ECS
- Enable MFA on every human user
- Rotate access keys every 90 days
AWS CLI setup and configuration
The AWS CLI lets you interact with AWS from your terminal. Install it:
# Linux
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version
# macOS
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /
aws --version
Create an access key in IAM for your admin user, then configure:
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
Named profiles let you manage multiple accounts (dev, staging, prod):
aws configure --profile dev
aws configure --profile staging
aws configure --profile prod
# Use a specific profile
aws s3 ls --profile dev
# Or set via environment variable
export AWS_PROFILE=dev
aws sts get-caller-identity
Set your default to dev so you never accidentally run commands against production.
VPC: Virtual Private Cloud
A VPC is your own isolated network inside AWS. Every resource you launch lives inside a VPC. You get a default VPC in each region, but for production create custom VPCs with explicit control.
Key concepts:
- CIDR block: The IP range for your VPC (e.g.,
10.0.0.0/16gives 65,536 IPs). Chosen at creation, cannot be changed later- Subnets: Subdivisions of your VPC, each in a specific availability zone
- Availability zones (AZs): Physically separate data centers within a region for fault tolerance
Public vs private subnets:
- Public subnets have a route to the internet through an Internet Gateway. Use for load balancers and bastion hosts
- Private subnets have no direct internet route. Use for app servers and databases. They reach the internet outbound through a NAT gateway
Route tables tell traffic where to go. Public subnets route 0.0.0.0/0 to the Internet
Gateway; private subnets route it through the NAT Gateway. Here is a typical production VPC:
Region: us-east-1
┌──────────────────────────────────────────────────────────┐
│ VPC: 10.0.0.0/16 │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ AZ: us-east-1a │ │ AZ: us-east-1b │ │
│ │ │ │ │ │
│ │ ┌─────────────────┐ │ │ ┌─────────────────┐ │ │
│ │ │ Public Subnet │ │ │ │ Public Subnet │ │ │
│ │ │ 10.0.1.0/24 │ │ │ │ 10.0.2.0/24 │ │ │
│ │ │ [Load Balancer] │ │ │ │ [NAT Gateway] │ │ │
│ │ └─────────────────┘ │ │ └─────────────────┘ │ │
│ │ ┌─────────────────┐ │ │ ┌─────────────────┐ │ │
│ │ │ Private Subnet │ │ │ │ Private Subnet │ │ │
│ │ │ 10.0.3.0/24 │ │ │ │ 10.0.4.0/24 │ │ │
│ │ │ [App Server] │ │ │ │ [App Server] │ │ │
│ │ │ [Database] │ │ │ │ [Database] │ │ │
│ │ └─────────────────┘ │ │ └─────────────────┘ │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ [Internet Gateway] │
└──────────────────────────────────────────────────────────┘
│
Internet
High availability (two AZs), security (databases in private subnets), and outbound access through NAT. We will build this VPC with Terraform in a later article.
Security groups
Security groups are virtual firewalls for your resources. They are stateful (allow inbound on port 80 and the response is automatically allowed outbound), allow-only (no deny rules, unlisted traffic is denied), and instance-level (attached to resources, not subnets).
Web server security group example:
Security Group: web-server-sg
Inbound Rules:
HTTP TCP 80 0.0.0.0/0 Allow HTTP from anywhere
HTTPS TCP 443 0.0.0.0/0 Allow HTTPS from anywhere
SSH TCP 22 203.0.113.50/32 Allow SSH from my IP only
Outbound Rules:
All All All 0.0.0.0/0 Allow all outbound
Database security group referencing the web server group:
Security Group: database-sg
Inbound Rules:
PostgreSQL TCP 5432 web-server-sg Allow Postgres from web servers only
Outbound Rules:
All All All 0.0.0.0/0 Allow all outbound
The database references web-server-sg as the source, so any instance with that group can reach
the database. No IP tracking needed. Best practices: never open SSH to 0.0.0.0/0, use security
group references instead of IPs for internal communication, and create separate groups per role.
Key AWS services overview
AWS has over 200 services. Here are the core ones for this series:
- EC2: Virtual servers. Choose OS, CPU, memory. Pay by the second
- S3: Object storage for files. Used for assets, backups, logs, static hosting. 99.999999999% durability
- RDS: Managed databases (PostgreSQL, MySQL, etc.). AWS handles backups, patching, failover
- ECS: Runs Docker containers on EC2 or Fargate (serverless). Handles scheduling and scaling
- Lambda: Serverless functions. Pay only for compute time consumed. Great for event-driven workloads
- Route 53: DNS service with health checks and routing policies
- ACM: Free SSL/TLS certificates. Attach to load balancers or CloudFront
- Secrets Manager: Stores passwords, API keys, tokens with automatic rotation
AWS Free Tier and surprise bills
Three free tier types:
- 12-month free: 750 hours/month t2.micro/t3.micro EC2, 5GB S3, 750 hours/month RDS single-AZ
- Always free: 1M Lambda requests/month, 25GB DynamoDB, 1M SNS notifications
- Short-term trials: Service-specific trials (e.g., 750 hours Redshift for 2 months)
How to avoid surprise bills:
- Set up billing alerts in CloudWatch and AWS Budgets with notifications at 50%, 80%, 100%
- Check billing dashboard weekly while learning
- Terminate unused resources: stopped EC2 instances still incur EBS charges
- Watch NAT gateways: ~$32/month even with zero traffic
- Watch data transfer: outbound data from AWS costs money
Set up a billing alarm with the CLI:
# Create an SNS topic for billing alerts
aws sns create-topic --name billing-alerts --profile dev
# Subscribe your email
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:123456789012:billing-alerts \
--protocol email \
--notification-endpoint [email protected] \
--profile dev
# Create CloudWatch alarm for charges over $10
aws cloudwatch put-metric-alarm \
--alarm-name "billing-alarm-10-usd" \
--alarm-description "Alarm when charges exceed $10" \
--metric-name EstimatedCharges \
--namespace AWS/Billing \
--statistic Maximum \
--period 21600 \
--threshold 10 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=Currency,Value=USD \
--evaluation-periods 1 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:billing-alerts \
--region us-east-1 \
--profile dev
Billing metrics are only available in us-east-1, regardless of where your resources live.
The AWS Well-Architected Framework
AWS defines six pillars for well-designed cloud systems:
- Operational Excellence: Automate operations, respond to events, define standards
- Security: Protect data with IAM, encryption, and detective controls
- Reliability: Recover from failures, meet demand, test recovery procedures
- Performance Efficiency: Right-size instances, choose correct storage, monitor performance
- Cost Optimization: Avoid waste with reserved/spot instances and right-sizing
- Sustainability: Minimize environmental impact, optimize utilization
We will apply these principles as we build real infrastructure in upcoming articles.
Closing notes
AWS can feel overwhelming, but most apps only use a handful of services. Once you understand IAM, VPC, and the core compute and storage services, you have the foundation for everything else. Key takeaways: never use root, always apply least privilege, understand public vs private subnets, and set up billing alerts before you forget. In the next article, we will start building real infrastructure with Terraform, defining VPCs, subnets, security groups, and EC2 instances as code.
Hope you found this useful and enjoyed reading it, until next time!
Errata
If you spot any error or have any suggestion, please send me a message so it gets fixed.
Also, you can check the source code and changes in the sources here
$ Comments
Online: 0Please sign in to be able to write comments.