WEEK 1 · LAB 1 (GUIDED)

Host Your Portfolio on AWS
with S3 + CloudFront

Get a real, public website live on the internet — in under an hour

7
Steps
~60 min
Estimated time
CLF-C02
Cert aligned
Free Tier
$0 if you clean up

What you'll build

📦

S3 Bucket

Your storage container — holds the files that make up your website

🌐

Static Hosting

S3's built-in feature that turns a bucket into a website

🔓

Bucket Policy

JSON rules that allow the world to read your files (read-only)

CloudFront

AWS's global CDN — serves your site fast from 400+ edge locations

🔗

Public URL

A shareable link to your portfolio you can put on your CV today

📸

Portfolio Site

A simple HTML page showcasing you — your name, skills, and CV link

Architecture

🌍 Visitor anywhere in the world
⚡ CloudFront CDNClosest edge location · 400+ worldwide
📦 Amazon S3 bucketindex.html · style.css · cv.pdf · images/
How it works: Visitor types your URL → CloudFront serves the cached copy from the nearest edge location → if not cached, CloudFront fetches it from S3 once, then caches it.
0

Before you start — what you need

Get everything ready before touching AWS

5 min

Read this first

This is your first AWS lab. The goal is one thing: get your portfolio live on the internet today. We'll teach the concepts as you go. Don't worry about understanding every detail on the first pass — the live session and the second lab will reinforce everything.

By the end of this lab you'll have a public URL you can share. That alone puts you ahead of 90% of people who say they're "learning the cloud" but have never deployed anything.

Requirements
  • 1
    AWS Account with Free Tier active Sign up at aws.amazon.com/free if you haven't already. Card required, but everything in this lab is FREE under the 12-month free tier.
  • 2
    Set your AWS Region Click the region name top-right of the AWS console. Choose one and stick with it for the whole bootcamp.
  • 3
    A simple HTML file (or two) You don't need to be a designer. We'll provide a template HTML file you can use. If you already have a portfolio HTML/CSS, even better — bring that.
  • 4
    A text editor VS Code, Sublime, Notepad++ — anything that lets you save .html files. Even Notepad works.
⚠️ Set a billing alarm before you do anything

Day-one habit: go to Billing → Budgets → Create budget → Zero-spend budget. Set it for $1. AWS will email you the moment any service starts charging. This habit will save you from horror stories.

✅ Ready to go when:

1

Prepare your portfolio files

Create a simple HTML page about yourself

5 min

Why we start here

S3 doesn't care what's in the file — it'll host any HTML you give it. So our first job is to have a file ready. Use the template below if you don't have your own. You can always upgrade the design later.

Create your portfolio file
  • 1
    Create a new folder on your computer Call it portfolio. This is where all your site files will live.
  • 2
    Open your text editor and create a file called index.html The filename matters — S3's static hosting looks for "index.html" by default.
  • 3
    Paste this template into index.html Replace the placeholders with your own info — name, role, skills, etc.
index.html — paste & customise
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Your Name — Portfolio</title>
  <style>
    body { font-family: system-ui, sans-serif; max-width: 720px;
           margin: 60px auto; padding: 0 20px; color: #1a1a1a;
           line-height: 1.6; }
    h1 { font-size: 42px; margin-bottom: 4px; }
    .role { color: #00B4D8; font-weight: 600; margin-bottom: 30px; }
    .skill { background: #E8F4FD; color: #1565C0; padding: 4px 10px;
             border-radius: 14px; font-size: 13px; margin-right: 6px; }
    a { color: #1565C0; }
  </style>
</head>
<body>
  <h1>Your Name</h1>
  <p class="role">Aspiring Cloud Engineer · Accra, Ghana</p>
  <h2>About</h2>
  <p>I'm learning AWS through the cloudwithshad bootcamp.
     This site is hosted on S3 + CloudFront — built in week 1.</p>
  <h2>Skills</h2>
  <p>
    <span class="skill">AWS</span>
    <span class="skill">S3</span>
    <span class="skill">EC2</span>
    <span class="skill">Linux</span>
  </p>
  <h2>Contact</h2>
  <p>Email: <a href="mailto:you@example.com">you@example.com</a><br>
     LinkedIn: <a href="https://linkedin.com/in/your-handle">your-handle</a></p>
</body>
</html>
💡 Optional bonuses

If you have time, also drop these into your portfolio folder:

  • cv.pdf — your CV. We'll link to it.
  • profile.jpg — a photo of you. Add <img src="profile.jpg" width="160"> in your HTML.
  • error.html — a "page not found" page (any HTML). S3 will use it for 404s.

✅ Check before moving on:

2

Create your S3 bucket

This is where your portfolio files will live

8 min

What is an S3 bucket?

A bucket is a container for files in S3. Think of it like a folder in the cloud — but with global reach. Each file (S3 calls them "objects") lives inside a bucket and gets its own URL. Bucket names are globally unique across all of AWS, so you'll need a creative name.

Console steps
  • 1
    Navigate to the S3 service
  • 2
    Click "Create bucket" Big orange button, top-right of the buckets page.
Fill in these values
Bucket name
cloudwithshad-yourname-portfolio
AWS Region
Same as where you've been working (e.g. us-east-1)
Object Ownership
ACLs disabled (recommended) — leave default
Block Public Access
UNCHECK "Block all public access"
Acknowledgement
Check the warning box that appears
Bucket Versioning
Disable (we don't need this for the lab)
Encryption
Leave default (SSE-S3)
⚠️ The "Block all public access" toggle

By default, AWS blocks public access to S3 buckets — this is a GOOD default that prevents accidental data leaks. But for a public website, we need the world to read our files. We're explicitly opting in to public access. The acknowledgement box AWS shows is exactly the kind of safety prompt you want to see.

Important: only do this for buckets you intend to be public (websites, public images). NEVER for private data.

💡 Why the bucket name needs your name in it

Bucket names are globally unique across all AWS accounts on Earth. "portfolio" is taken. "my-bucket" is taken. "cloudwithshad-portfolio" might be taken too. Adding your-name in there makes it almost certainly available — and easier to find later.

  • 3
    Click "Create bucket" at the bottom If the name is taken, AWS will tell you. Try a different one.

✅ What you should see

  • Green success banner: "Successfully created bucket"
  • Your bucket name appears in the list of buckets
  • Region matches what you selected
  • Access shows "Objects can be public"
📝 Cloud Practitioner Exam Tip

Memorise: S3 bucket names are globally unique. They're DNS-compatible (no spaces, no underscores, lowercase only). They're tied to a region but the name is global. Bucket names appear in URLs.

✅ Check before moving on:

3

Upload your files

Put your portfolio into the bucket

5 min
  • 1
    Click on your bucket name This opens the bucket. You'll see an empty "Objects" tab.
  • 2
    Click "Upload" Either click the orange Upload button OR drag your files into the page.
  • 3
    Add your files Click "Add files" and select your index.html (and any others — cv.pdf, profile.jpg, etc.).
  • 4
    Leave all permissions/properties as default We'll set the public access via a bucket policy in Step 5 — that's cleaner than per-file permissions.
  • 5
    Click "Upload" at the bottom Wait for the green "Upload succeeded" message.

✅ What you should see

  • "Upload succeeded" green banner
  • Files listed in the Objects tab of your bucket
  • Each file shows a size, type, and last modified date
📸 Take a screenshot — show your S3 bucket with files uploaded. Great for your portfolio later.

✅ Check before moving on:

4

Enable static website hosting

Turn the bucket into a website

8 min

What "static hosting" actually does

By default, S3 is just a file store — each file has its own URL but they're not "linked together" as a website. Enabling static hosting tells S3: "this bucket is a website. When someone visits the bucket's root URL, serve them index.html. If a page is missing, show error.html."

  • 1
    Go to Properties tab Inside your bucket, click the Properties tab at the top.
  • 2
    Scroll all the way to the bottom Find "Static website hosting" at the very bottom of Properties.
  • 3
    Click "Edit"
Fill in these values
Static website hosting
Enable
Hosting type
Host a static website
Index document
index.html
Error document
error.html (optional — leave blank if you didn't create one)
  • 4
    Click "Save changes"
  • 5
    Copy the website endpoint URL After saving, scroll back down to the same section. You'll see "Bucket website endpoint" — copy that URL. It looks like: http://your-bucket.s3-website-us-east-1.amazonaws.com
  • 6
    Open the URL in a new tab You should see... wait for it...
⚠️ Expected error: 403 Forbidden

You'll get a 403 Forbidden right now — that's NORMAL and EXPECTED. The bucket allows public access in theory, but we haven't told it WHICH files to share with the public yet. That's the next step.

✅ Check before moving on:

5

Make your files public with a bucket policy

The JSON that grants the world read-only access

8 min

What is a bucket policy?

A bucket policy is a JSON document that tells AWS who can do what to the files in your bucket. It's part of IAM (Identity and Access Management) — one of the 4 services we covered in the lecture today.

We'll write a policy that says: "Everyone in the world can READ files from this bucket — but they can't write, delete, or list anything." That's exactly what a public website needs.

  • 1
    Go to Permissions tab Still inside your bucket, click the Permissions tab at the top.
  • 2
    Find "Bucket policy" section Scroll down → click Edit next to "Bucket policy".
  • 3
    Paste this policy — REPLACE the bucket name Change YOUR-BUCKET-NAME to your actual bucket name (twice in the policy).
Bucket Policy — public read access
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
    }
  ]
}
💡 Decoding the policy line by line
  • Effect: Allow — we're granting permission
  • Principal: * — to everyone (the asterisk means anonymous public)
  • Action: s3:GetObject — only the action of reading a file. Not deleting, not listing, not modifying.
  • Resource: arn:aws:s3:::your-bucket/* — applies to every file inside the bucket (the /* means "all objects")

This is the same JSON-with-Effect/Principal/Action/Resource pattern used everywhere in AWS IAM. Learn it once — use it forever.

  • 4
    Click "Save changes" If you get a syntax error, you probably forgot to replace YOUR-BUCKET-NAME. AWS will tell you what's wrong.
  • 5
    Refresh your S3 website URL in the browser Now visit your bucket website endpoint again — the one from Step 4.

✅ What you should see

  • Your portfolio page is LIVE on the public internet 🎉
  • Your name, role, skills — all rendered as a real website
  • The URL bar shows your S3 bucket website endpoint
📸 Take a screenshot — share it in the bootcamp group chat! Your first cloud-hosted website. This is a real moment.
📝 Cloud Practitioner Exam Tip

Bucket policies vs ACLs vs IAM policies — all three control S3 access. Bucket policies are the modern, recommended approach for bucket-wide rules. Memorise: Effect, Principal, Action, Resource.

✅ Check before moving on:

6

Add CloudFront CDN for global speed

Serve your site from 400+ edge locations worldwide

12 min

Why we add CloudFront

Right now your site lives in ONE region (e.g. Virginia). A visitor from Tokyo has to fetch every file from Virginia — slow. CloudFront is AWS's Content Delivery Network (CDN): it caches your site at 400+ edge locations globally, so visitors get served from the closest one.

Bonus: CloudFront also gives you HTTPS for free, hides your S3 URL from visitors, and makes the site faster everywhere — including West Africa.

Create the CloudFront distribution
  • 1
    Navigate to CloudFront
  • 2
    Click "Create distribution"
Origin settings
Origin domain
Click the dropdown — select your S3 bucket from the list
Origin path
Leave blank
Name
Auto-filled — leave it
Origin access
Public — Use this if your bucket is already public (which ours is)
ℹ️ "Origin Access Control (OAC)" alternative

You'll see an option for OAC (Origin Access Control). That's the more secure pattern — it makes CloudFront the ONLY way to access your bucket, and re-locks the bucket to private. We're using the simpler "Public" path for this lab — we'll cover OAC in Week 3.

Default cache behavior
Viewer protocol policy
Redirect HTTP to HTTPS
Allowed HTTP methods
GET, HEAD (default — leave it)
Cache policy
CachingOptimized (default)
Settings
Price class
Use only North America and Europe (cheapest, still global enough)
WAF
Do not enable security protections (saves cost for now)
Default root object
index.html
💡 Why "Default root object" matters

Without it, visiting your-distribution.cloudfront.net/ (with no file specified) will return an error. Setting it to "index.html" makes CloudFront serve your homepage when someone hits the root URL — exactly like a normal website.

  • 3
    Click "Create distribution" CloudFront takes 5–10 minutes to deploy globally. Status will show "Deploying" then change to "Enabled".
  • 4
    Copy your CloudFront domain Once status = Enabled, copy the Distribution domain name — looks like d1234abc.cloudfront.net
  • 5
    Open it in a NEW browser tab (not refreshed S3 tab) You should see your portfolio — but now served via HTTPS, from a CloudFront edge location near you.

✅ What you should see

  • URL starts with https:// (not http)
  • The CloudFront domain in the address bar (d-something.cloudfront.net)
  • Your portfolio loads — possibly faster than the S3 URL
  • Browser shows a lock icon (HTTPS = secure)
📸 Take a screenshot — your CloudFront-hosted, HTTPS-secured portfolio. This is the link you put on your CV.

✅ Check before moving on:

7

Test, share, and update

Make sure it really works — and learn how to push updates

5 min
  • 1
    Test on your phone Open your CloudFront URL on your phone (not on your laptop's WiFi network — use mobile data to really test). It should load and look correct.
  • 2
    Share it with a friend Send the link to a friend on a different continent if you can. Ask them: "is it fast?" — that's CloudFront working.
  • 3
    Update your portfolio (the workflow) Edit your local index.html → upload the new version to S3 (replaces the old) → wait ~1 minute → refresh CloudFront. Your changes appear.
💡 CloudFront caching gotcha

If you update index.html and the new version doesn't show up after refresh, CloudFront might still be serving the old cached copy. To force a refresh:

  • Quick fix: open in incognito mode (bypasses your local cache)
  • Proper fix: CloudFront → Distribution → Invalidations tab → Create invalidation → path /* (this clears the CDN cache)
🚀 What you've actually learned

You've now used 3 of the most important AWS services: S3 (storage), IAM via bucket policies (permissions), and CloudFront (global delivery). This same architecture pattern hosts millions of real-world websites — yours is technically the same setup as the marketing pages of major SaaS companies. That's not nothing.

✅ Final check:

🎉 Lab 1 Complete!

You just hosted a real website on AWS using S3 + CloudFront. The same architecture used by major SaaS marketing sites. You're officially in the cloud.

Final checklist:
🗑️ Cleanup — only if you don't want to keep the site

Most students keep the site running — it's basically free under free tier and looks great on a CV. But if you want to delete everything, follow these steps in order.

1
Disable & delete CloudFront distribution
CloudFront → select distribution → Disable → wait until "Disabled" → Delete
CloudFront takes 5–15 minutes to disable before it can be deleted.
2
Empty the S3 bucket
S3 → click your bucket → "Empty" button (top-right) → type "permanently delete" → Empty
You can't delete a bucket that contains files.
3
Delete the bucket
S3 → select your empty bucket → Delete → type bucket name → Delete
⚠️ Why most students keep it

S3 charges ~$0.023 per GB stored per month. Your portfolio is probably under 5 MB = effectively $0. CloudFront's free tier covers up to 1 TB/month outbound. For a portfolio site with normal traffic, this is permanently free. Keep it. Show it off.

What's next — Lab 2

🖥️

Launch EC2

Spin up a real Linux server you can SSH into from your laptop

🔑

SSH Access

Connect to your server with a key pair — like a real engineer

⚙️

Deploy a Web App

Install Nginx, host a dynamic page on YOUR server