AWS From Zero to Deployed
A complete beginner path: account setup, budgets, EC2, SSH from your PC, running an app, ports, and cost safety
Purpose: Follow this document in order with zero prior AWS experience and end with a working web application on a public URL — without surprise bills.
What you will build
Your laptop | | 1) SSH (port 22) with your private key v EC2 instance (t2.micro, free tier) | | 2) runs Nginx or your app (port 80 / 8080) v Your browser <--- http://PUBLIC_IP --- anyone on the Internet
By the end you will have: a secured AWS account with MFA and budget alerts; AWS CLI configured on your PC; an EC2 server you can SSH into; a web app serving traffic on a public IP; and a cleanup plan so experiments do not cost money.
1. What you need before starting
| Item | Notes |
|---|---|
| Email address | Preferably one dedicated to AWS; the root account will use it. |
| Phone number | AWS sends a verification code during signup. |
| Credit or debit card | Required for identity verification. You are not charged if you stay inside the free tier and stop unused resources. |
| A PC with internet | Windows 10/11, macOS, or Linux. |
| Terminal access | PowerShell/CMD on Windows, Terminal on macOS/Linux. |
| ~2 hours | Account setup + first deployment in one sitting. |
No prior cloud or Linux experience is required. Every command is provided.
2. Cloud and AWS in plain English
Traditionally, to run a web app you buy a server, put it in a data center, and pay for it whether you use it or not. Cloud computing means renting computers, storage, and networking over the internet, minute by minute, and paying only for what you use. Amazon Web Services (AWS) is the largest cloud provider.
| Traditional hosting | AWS cloud |
|---|---|
| Buy hardware weeks in advance | Server in ~2 minutes |
| Fixed monthly cost | Pay per second/hour of use |
| One data center | Regions worldwide |
| You fix broken disks | AWS manages the hardware; you manage your data and config |
3. Create your AWS account
- Open https://aws.amazon.com/free/ (or aws.amazon.com → Create an AWS Account).
- Enter email → verify with the code AWS sends → password (this is the root account) → account name.
- Contact information: Personal or Business, full name, phone, country, address.
- Payment information: card for verification; AWS may place a small temporary authorization hold (refunded).
- Identity verification: phone OTP by SMS or call.
- Support plan: choose Basic Support — Free.
Signup flow
|
v
Email + password --> Contact info --> Card --> Phone OTP
|
v
Support plan (Basic/Free)
|
v
Root console accessWhat happens next
- You land in the AWS Management Console at
https://console.aws.amazon.com/. - Your account has a unique 12-digit Account ID (top-right account menu) — used in ARNs like
arn:aws:iam::123456789012:role/.... - New accounts typically get 12 months of selected free-tier usage (e.g. 750 hours/month of
t2.micro/t3.microin most regions). Limits change — bookmark https://aws.amazon.com/free/.
Store root email + password in a password manager immediately. The root user must never be used for daily work.
4. Lock down the root account
The root account = your signup email + password. It can do everything, including deleting your whole account. Secure it before creating anything.
Enable MFA on root — today
- Log in as root (account email → Root user).
- Top-right account menu → Security credentials.
- Multi-factor authentication (MFA) → Assign MFA device.
- Choose Virtual MFA device → next.
- Install an authenticator app (Google Authenticator, Authy, Microsoft Authenticator).
- Scan the QR code → enter two consecutive codes → Activate.
Login: email + password + 6-digit code from phone
\______________/ \___________________/
something something
you know you haveRoot hygiene: enable MFA; do not create access keys for root; use root rarely (billing, account close, some support cases); do daily work as IAM.
5. Billing and budgets (do this on day one)
Budgets are your safety net for the day you forget a running server. Nothing in this guide should cost real money if you stay on free-tier shapes and stop or terminate unused resources.
Create a cost budget with alerts
- Billing → Budgets → Create budget.
- Choose Use a template → Zero-spend budget or Custom cost budget.
- Custom example: name
monthly-learning, amount $5, alert at 80% and 100% to your email. - Confirm email → Create budget.
Spend $0.00 $4.00 (80%) $5.00 (100%)
|--------------------|---------------------|
OK Warning email Critical email
(stop non-free resources)Free-tier usage alerts
Billing → Preferences → enable Receive Free Tier Usage Alerts → confirm email.
Cost Explorer
Billing → Cost Explorer → enable if prompted. Use later to see which service drove a charge.
The 12-month free tier starts at account creation. Build the habit: stop instances when idle.
6. Console tour: regions, services, CloudShell
Region: us-east-1 (N. Virginia) <-- pick one and stay there while learning | +-- AZ: us-east-1a (data center cluster) +-- AZ: us-east-1b +-- AZ: us-east-1c
| Concept | Meaning | Beginner rule |
|---|---|---|
| Region | Geographic area (us-east-1, eu-west-1, ap-southeast-1). | Pick one region; keep everything there while learning. |
| Availability Zone | Isolated data centers inside a region. | Single-AZ is fine for learning; production uses 2+ AZs. |
Region selector: top-right of the console. Resources are regional — an EC2 instance in us-east-1 is invisible from eu-west-1. Global services (IAM, Route 53) appear the same from every region.
Services search: top bar — type EC2, IAM, S3…
AWS CloudShell (icon >_ in the top bar): a browser terminal with AWS CLI pre-authenticated as your current console user.
7. Create your daily-use admin identity
Never work as root. Classic beginner path:
- Search IAM → Users → Create user.
- Username:
admin. - Permissions options → Attach policies directly → check
AdministratorAccess. - Create user → open it → Security credentials → Create access key → use case Command Line Interface (CLI) → Download the .csv (secret shown only once).
- Also set a console password for this user and assign MFA (same as root).
Root (email + MFA)
|-- used rarely: billing changes, account close, some support
|
+-- IAM user: admin (AdministratorAccess + MFA + CLI access keys)
|-- daily console + CLI work while learning
|
+-- later: narrow policies / roles per project (see IAM guide)For org-grade access, prefer IAM Identity Center — see the IAM guide.
8. Install the AWS CLI on your PC
| OS | Method |
|---|---|
| Windows | Download MSI from aws.amazon.com/cli → run → reopen PowerShell. |
| macOS | curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o AWSCLIV2.pkg && sudo installer -pkg AWSCLIV2.pkg -target / (or brew install awscli). |
| Ubuntu/Debian | sudo apt update && sudo apt install -y awscli (or official .zip from AWS docs). |
| Amazon Linux | sudo yum install -y awscli. |
aws --version
aws configure
# AWS Access Key ID: AKIA... (from the CSV)
# AWS Secret Access Key: wJal... (hidden while typing)
# Default region name: us-east-1
# Default output format: json
aws sts get-caller-identity
# Arn should be arn:aws:iam::123456789012:user/admin (NOT root)
Keys are stored in ~/.aws/credentials — protect this file; never commit it.
9. Mental map of core services
| Service | What it does | Used in this guide? |
|---|---|---|
| IAM | Identities and permissions | Yes (setup) |
| EC2 | Virtual servers | Yes (the app host) |
| VPC | Private network (defaults are fine) | Yes (defaults) |
| Security Groups | Virtual firewall around instances | Yes (SSH + HTTP) |
| EBS | Disk volumes for EC2 | Yes (root volume) |
| CloudWatch | Metrics, logs, alarms | Glance |
| S3 / RDS / Route 53 / ALB | Storage / databases / DNS / load balancer | Not yet |
10. Launch your first EC2 instance
EC2 Dashboard → Launch instance. Region top-right must be your chosen one.
| Setting | First-time choice | Why |
|---|---|---|
| Name | first-server | Easy to spot in the list. |
| AMI | Amazon Linux 2023 or Ubuntu 24.04 LTS | Free-tier eligible. |
| Instance type | t3.micro or t2.micro | Free-tier (750 hrs/month, 12 months — verify current terms). |
| Key pair | Create new, download .pem | Your SSH password file. Do not lose it. |
| Network | Default VPC + public IP enabled | Works out of the box with internet access. |
| Storage | 8–30 GiB gp3 | Free tier includes up to 30 GB EBS. |
| Security group | SSH (22) from My IP only | Safer than 0.0.0.0/0. |
Key pair rules
| Rule | Reason |
|---|---|
The .pem is the only way in (without password) | Lose it → simplest fix is rebuild. |
Never commit .pem to git | Keys in repos get scraped. |
| Permissions must be private | chmod 400 on macOS/Linux. |
Click "Launch"
|
+--> EC2 boots your AMI in the chosen AZ
+--> AWS attaches an EBS root volume
+--> Places it in your subnet (private IP)
+--> With auto-assign public IP: maps a public IPv4
+--> Security group: only port 22 from your IP so far
|
v
Instance state: running Status checks: 2/2 passed (wait ~1–3 min)11. Connect from your PC with SSH
You need five things:
- Instance running + 2/2 status checks
- Reachable public IPv4 (console → select instance)
- Correct username for the AMI
- Private key matching the key pair
- Security group allows TCP 22 from your current IP
| AMI | Username |
|---|---|
| Amazon Linux 2023 / AL2 | ec2-user |
| Ubuntu | ubuntu |
| Debian | admin |
| RHEL / Fedora / SUSE | ec2-user |
macOS / Linux
mkdir -p ~/aws-keys
mv ~/Downloads/first-server-key.pem ~/aws-keys/
chmod 400 ~/aws-keys/first-server-key.pem
ssh -i ~/aws-keys/first-server-key.pem ubuntu@3.94.12.34
First connection: type yes to trust the host fingerprint.
Windows (OpenSSH built into 10/11)
mkdir C:\aws-keys
move $env:USERPROFILE\Downloads\first-server-key.pem C:\aws-keys\
icacls C:\aws-keys\first-server-key.pem /inheritance:r /grant:r "$env:USERNAME:R"
ssh -i C:\aws-keys\first-server-key.pem ubuntu@3.94.12.34
PuTTY alternative: convert .pem → .ppk with PuTTYgen.
Success looks like: ubuntu@ip-10-0-1-45:~$ — the 10.x host is the private IP (normal).
12. First ten minutes on the server
Commands assume Ubuntu; on Amazon Linux use sudo dnf update -y instead.
whoami
hostname
sudo apt update
sudo apt upgrade -y
sudo apt install -y curl git jq ufw
# Optional non-root app user
sudo adduser deploy
sudo usermod -aG sudo deploy
echo 'deploy ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/deploy
sudo chmod 440 /etc/sudoers.d/deploy
UFW note
AWS security groups are your primary firewall for this guide. If you enable UFW, allow SSH first or you will lock yourself out:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw --force enable
sudo ufw status
13. Run your first web application
Path A — Nginx static page
sudo apt install -y nginx
sudo systemctl enable --now nginx
echo '<h1>Hello from my first AWS server</h1>' \
| sudo tee /var/www/html/index.html
curl -I http://localhost
# HTTP/1.1 200 OK
Path B — Node.js app on port 8080
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
mkdir -p ~/myapp && cd ~/myapp
cat > server.js <<'EOF'
const http = require('http');
const port = process.env.PORT || 8080;
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`<h1>It works!</h1><p>Path: ${req.url}</p>`);
});
server.listen(port, '0.0.0.0', () => {
console.log(`Listening on 0.0.0.0:${port}`);
});
EOF
node server.js
# then in another SSH session or after detaching:
# curl http://127.0.0.1:8080
127.0.0.1 is local-only. 0.0.0.0 accepts network traffic — required for public access, dangerous without locked security groups.Keep it running after disconnect
sudo apt install -y tmux
tmux new -s app
node server.js
# Detach: Ctrl+b then d Reattach: tmux attach -t app
14. Open the app to the world (ports and security groups)
| Port | Service | Open to Internet? |
|---|---|---|
| 22 | SSH | No — only your IP or VPN |
| 80 | HTTP | Yes, if public website |
| 443 | HTTPS | Yes, with certificates later |
| 8080 | Common app port | Prefer Nginx on 80 in front |
| 5432 / 3306 | Postgres / MySQL | Never 0.0.0.0/0 |
Add inbound rule: EC2 → Instances → select server → Security tab → security group → Edit inbound rules → HTTP, source Anywhere-IPv4 → Save.
Browser --HTTP:80--> Public IPv4 --NAT--> EC2 :80
^
Security group must allow 80 from 0.0.0.0/0
(SSH rule stays limited to your IP)Then open http://<Public IPv4>. If local curl works but the browser fails: security group, app bind address, then UFW — in that order.
15. Port forwarding explained
For private services (databases, internal dashboards), tunnel through SSH instead of opening ports to the internet.
Local port forwarding (most common)
# On YOUR laptop:
ssh -i ~/aws-keys/first-server-key.pem \
-L 8080:127.0.0.1:8080 \
ubuntu@3.94.12.34
# Then browse: http://127.0.0.1:8080
Laptop browser: http://127.0.0.1:8080
|
v
Local port 8080 ===SSH tunnel=== EC2 --> app on server 127.0.0.1:8080Forward to a private database
ssh -i key.pem -L 15432:10.0.3.25:5432 ubuntu@BASTION_PUBLIC_IP
psql -h 127.0.0.1 -p 15432 -U appuser appdb
Remote forwarding (reverse)
ssh -i key.pem -R 9000:127.0.0.1:3000 ubuntu@SERVER
# On server: curl http://127.0.0.1:9000 reaches your laptop's :3000
Session Manager alternative
No open port 22, no key on disk — attach instance profile with AmazonSSMManagedInstanceCore, then:
aws ssm start-session --target i-0123456789abcdef0
| Method | Needs public SSH? | Needs key on disk? |
|---|---|---|
| Direct SSH | Yes (restricted) | Yes |
| SSH + port forward | Yes (SSH only) | Yes |
| SSM Session Manager | No | No |
16. Elastic IPs and stable addresses
A normal public IPv4 changes on stop/start. An Elastic IP is static and reassignable.
- EC2 → Elastic IPs → Allocate Elastic IP address.
- Select → Associate → choose
first-server.
17. Storage and snapshots
Instance lifecycle
running <----start---- stopped
| |
reboot EBS volume persists
| |
+---- terminate --> volume deleted (default)Snapshots are point-in-time EBS backups (EC2 → Volumes → Create snapshot). Take one before big upgrades; delete old experiment snapshots (they cost money). Instance store (local NVMe on some types) is ephemeral — never your only copy of data.
18. Monitoring and billing checks while you work
EC2 → Monitoring tab: CPU, network, disk, status checks (free basic metrics). CloudWatch is the service behind these.
Weekly cost check (2 minutes): Billing Dashboard → month-to-date; Cost Explorer group by Service; stop forgotten Running instances; release unattached Elastic IPs; prune EBS snapshots.
19. Deploying updates to your app
| Method | Command sketch | When |
|---|---|---|
| SSH + nano/vim | nano ~/myapp/server.js | Tiny fixes |
| scp | scp -i key.pem app.js ubuntu@IP:~/myapp/ | Single file |
| rsync | rsync -avz -e "ssh -i key.pem" ./app/ ubuntu@IP:~/myapp/ | Project tree |
| Git on server | git clone / git pull | Recommended habit |
| CI/CD | GitHub Actions → deploy | Production (later) |
20. What you built: architecture recap
+---------------- AWS Account (12-digit ID) ----------------+ | Root (MFA) IAM admin user (MFA, CLI keys) | | Budgets: $5 alert Free-tier email alerts | | | Region (e.g. us-east-1) | +-- Default VPC | | +-- Public subnet | | +-- EC2 t3.micro "first-server" | | AMI: Ubuntu 24.04 | | EBS gp3 root volume | | Public IPv4 (or Elastic IP) | | SG: 22 from YourIP, 80 from Anywhere | | App: Nginx :80 or Node :8080 | | SSH key pair on your laptop | +-- (unused for now: S3, RDS, ALB, multi-AZ...)
You now understand the entire beginner loop: account → identity → budget → server → key → firewall → app → port → browser.
21. Stop vs terminate: avoiding surprise bills
| Action | Compute billing | Disk (EBS) | Public IPv4 | Data |
|---|---|---|---|---|
| Running | Yes | Yes | Yes | Live |
| Stop | No | Yes | Released (unless Elastic IP) | EBS persists |
| Reboot | Yes | Yes | Kept | Kept |
| Terminate | No | Root deleted (default) | Released | Gone unless AMI/snapshot |
End of day: Stop instance -> pay only for EBS pennies End of project: Terminate + cleanup -> pay ~zero
22. Cleanup checklist
- EC2 → Instances → Terminate all learning instances.
- Release unassociated Elastic IPs.
- Delete orphaned volumes (state “available”).
- Delete old experiment snapshots.
- Delete key pairs for terminated instances.
- Delete unused security groups (keep default).
- Review IAM users / rotate or delete stale keys.
- Keep the budget — it protects future work.
- Delete local .pem files for instances that no longer exist.
23. Troubleshooting common errors
| Symptom | Likely cause | Fix |
|---|---|---|
Permission denied (publickey) | Wrong username, wrong .pem, bad permissions | Verify AMI username; chmod 400; match key pair. |
Connection timed out | SG blocks your IP (ISP change); wrong IP; instance stopped | SG source = curl https://checkip.amazonaws.com; instance Running. |
Connection refused | Nothing listening; app on 127.0.0.1 | ss -tulpn; bind 0.0.0.0; open SG port. |
| Browser spins; curl works on server | SG missing HTTP rule; UFW | Add inbound rule; sudo ufw status. |
Host key verification failed | IP reused; stale known_hosts | ssh-keygen -R 3.94.12.34. |
CLI ExpiredToken / InvalidClientTokenId | Wrong/expired keys | aws configure again; IAM access keys. |
AccessDenied from CLI | Wrong identity / missing policy | aws sts get-caller-identity; see IAM guide. |
| Locked out after UFW enable | UFW blocked SSH | Instance Connect / rebuild; allow OpenSSH before enabling UFW. |
Three diagnostic commands (memorize)
# On your laptop
aws sts get-caller-identity
curl https://checkip.amazonaws.com
# On the server
ss -tulpn
24. What is free and what is not
Verify current terms at https://aws.amazon.com/free/.
| Typically free-tier (12 months) | Not free / easy to forget |
|---|---|
| 750 hrs/month t2.micro/t3.micro (one instance) | A second running instance doubles hours |
| 30 GB EBS storage | Snapshots beyond free limits |
| Limited S3 storage + requests | Large S3 data + transfer |
| Limited data transfer out | Large downloads, backups |
| — | All public IPv4 / Elastic IP (small hourly) |
| — | ELB, NAT Gateway (real $/hr) |
| — | RDS, Route 53, paid AMIs |
Common beginner bill sources EC2 left running ████████████ EBS volumes/snapshots ████ Public IPv4 charges ██ NAT/ALB (if you "advance") ██████████
Rule of thumb: if you did not click “launch” on it this week, it should not be Running.
25. Where to go next
| Topic | Guide |
|---|---|
| EC2 in depth | EC2 Instance guide |
| IAM policies, roles, SSO | IAM guide |
| VPC, S3, RDS, HTTPS | Add as next topics in this repo |
This guide (account + first server + first app)
|
v
EC2 guide (production patterns, Session Manager)
|
+--> VPC guide --> ALB/ASG
+--> IAM guide (roles, boundaries)
+--> S3 + RDS + HTTPS guides
|
v
CI/CD to AWS + backups/alerts26. Final beginner checklist
- AWS account created; card verified; root password in a password manager.
- MFA enabled on root.
- Budget + free-tier email alerts enabled; test that emails arrive.
- IAM admin user with MFA + CLI access keys stored safely.
- AWS CLI installed;
aws sts get-caller-identityshows the IAM user. - Region chosen and consistent.
- EC2 launched: free-tier type, key pair (
chmod 400), SG = SSH from My IP. - SSH works; packages updated.
- Web app runs bound to
0.0.0.0. - SG allows HTTP as needed; page loads via public IP.
- Understood port forwarding for private services.
- Instance stopped at end of day; terminate + cleanup when done.
- Billing dashboard checked after first day of experiments.