A practical walkthrough for deploying a static portfolio, resume, or about-me page the cloud-native way with HTTPS, global delivery, and zero server maintenance.
Every cloud engineer needs a live portfolio. It proves you can ship not just talk theory. This project is deceptively simple on the surface, but underneath it teaches you S3 permissions, CDN architecture, bucket policies, and origin access control all concepts that show up on AWS certifications and real-world cloud jobs.
In this guide, I'll walk you through exactly how I deployed my own static website using Amazon S3 for storage and Amazon CloudFront as the content delivery network no EC2, no server patching, no midnight alerts. Just clean, fast, globally distributed HTML.
"The best infrastructure is the kind you don't have to babysit at 2am."
Why S3 + CloudFront?
Before we touch a single AWS console screen, let's understand the architecture we're building and why it makes sense.
| 💰 Near-zero cost | S3 storage for a personal site costs pennies. CloudFront's free tier covers 1TB/month of data transfer. |
| ⚡ Global speed | CloudFront caches your content at 400+ edge locations worldwide your site loads fast from Lagos to London. |
| 🔒 HTTPS by default | CloudFront provides a free SSL certificate your visitors get a padlock icon without buying anything extra. |
| 🛠️ Zero servers | No EC2, no patching, no SSH keys. AWS manages all the infrastructure underneath. |
How the Architecture Works
Here's the request flow from browser to your HTML file:
🧑💻 Visitor ──HTTPS──▶ ☁️ CloudFront (CDN Edge) ──cache miss only──▶ 🪣 S3 Bucket (private origin)
CloudFront sits in front of your S3 bucket as a CDN. When a visitor hits your URL, CloudFront checks if it has a cached copy at the nearest edge location. On a cache hit, it serves instantly. On a miss, it fetches from S3, caches it, and serves the response.
Your S3 bucket can remain private only CloudFront talks to it directly, which is far more secure than opening the bucket to the entire internet.
Let's Build It Step-by-Step
Step 1 — Create Your S3 Bucket
Log into the AWS Management Console and navigate to S3 → Create bucket.
- Choose a globally unique bucket name (e.g.
yourname-portfolio-2024) - Select your preferred AWS Region
- Leave "Block all public access" checked — we'll handle access through CloudFront, not by making the bucket fully public
- Leave versioning off for simplicity; enable it later if you want rollback support
⚠️ Common mistake: Beginners often unblock all public access immediately and make the bucket fully public. This works, but it's not best practice. The cleaner and more secure approach is to keep the bucket private and let CloudFront access it via an Origin Access Control (OAC) policy which is exactly what we'll do.
Step 2 — Upload Your HTML Files
Build or gather your static website files. At minimum, you need an index.html. A basic portfolio structure might look like:
my-portfolio/
├── index.html
├── style.css
├── script.js
└── assets/
├── profile-photo.jpg
└── resume.pdf
In the S3 console, open your bucket and click Upload. Drag your files in, keeping the folder structure intact, then click Upload to confirm.
✅ Pro tip: If you have the AWS CLI set up, you can sync your local folder with:
aws s3 sync ./my-portfolio s3://your-bucket-nameMuch faster for future updates.
Step 3 — Enable Static Website Hosting
In your S3 bucket, go to Properties → Static website hosting → Edit.
- Enable static website hosting
- Set Index document to
index.html - Optionally set Error document to
404.html
Save changes. AWS will give you an S3 website endpoint URL. Don't share this publicly it's HTTP only and bypasses CloudFront. Think of it as a staging preview.
Step 4 — Create a CloudFront Distribution
Navigate to CloudFront → Create distribution. This is where the magic happens.
Origin settings:
- Origin domain: Select your S3 bucket from the dropdown (use the REST endpoint, not the website endpoint)
- Origin access: Choose Origin access control settings (recommended)
- Click Create new OAC give it a name and leave signing behaviour as "Sign requests"
Default cache behaviour:
-
Viewer protocol policy: Set to
Redirect HTTP to HTTPS -
Cache policy: Use
CachingOptimized(AWS managed)
Settings:
-
Default root object: Enter
index.html -
Price class:
Use all edge locationsfor best global performance, or restrict to a region to reduce cost
Click Create distribution. CloudFront will take a few minutes to deploy globally the status changes from "Deploying" to a green "Enabled".
Step 5 — Add the Bucket Policy for CloudFront OAC
After creating the distribution, the console will show a banner prompting you to update your S3 bucket policy. Click Copy policy, then navigate back to your S3 bucket → Permissions → Bucket policy → Edit and paste it in.
The generated policy looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bucket-name/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::ACCOUNT_ID:distribution/DIST_ID"
}
}
}
]
}
🔍 What this policy does: It grants the CloudFront service principal read access (
s3:GetObject) to every object in your bucket but only from your specific CloudFront distribution. Not from anyone else's CloudFront. Not from the public internet. Just yours.
Step 6 — Test Your Live Site
Go back to CloudFront and copy your Distribution domain name it looks like d1abc2defgh3ij.cloudfront.net. Paste it in your browser.
You should see your index.html rendered, served over HTTPS, with a valid SSL certificate for free.
🎉 You're live! Your personal website is now globally distributed across AWS's edge network. Whether someone visits from Lagos, London, or Los Angeles they're getting a fast, secure experience.
Optional But Recommended: Use Your Own Domain
The CloudFront URL works fine, but yourname.com looks far more professional. Here's the short version:
- Register a domain via Route 53 (or bring your own from Namecheap, GoDaddy, etc.)
- Request a free SSL certificate via AWS Certificate Manager (ACM) in the us-east-1 region (required for CloudFront)
- Add your custom domain as an Alternate domain name (CNAME) in your CloudFront distribution settings and attach the ACM certificate
- In Route 53, create an A record (alias) pointing to your CloudFront distribution
What I Learned From This Project
When I first completed this as part of the Cloud Engineering Program, I thought it was going to be a simple file-upload exercise. It turned out to be a surprisingly rich lesson in cloud fundamentals:
- IAM and resource-based policies — the bucket policy taught me how AWS evaluates permissions at the resource level, not just the user level
- The principle of least privilege — keeping the S3 bucket private and exposing it only through CloudFront OAC is a real-world security pattern, not just textbook advice
- CDN architecture — understanding cache hits vs. misses, TTLs, and edge locations made CloudFront feel less magical and more engineerable
- DNS and SSL — hooking up Route 53 and ACM demystified how HTTPS actually works end-to-end
These aren't just resume bullet points. They're the building blocks of almost every AWS architecture you'll work on professionally.
Quick Reference: Services Used
| Service | Role in This Project |
|---|---|
| Amazon S3 | Object storage for your HTML/CSS/JS/assets |
| S3 Static Hosting | Turns the bucket into a web server (origin) |
| Bucket Policy | JSON policy granting CloudFront read access |
| CloudFront | CDN that caches and delivers content globally |
| OAC | Origin Access Control secure S3↔CloudFront connection |
| ACM | Free SSL/TLS certificate (optional, custom domain) |
| Route 53 | DNS routing (optional, custom domain) |
What's Next?
Once your static site is live, try extending it:
- Add a CI/CD pipeline with GitHub Actions to auto-deploy on every push to your repo
- Enable CloudFront invalidations (
aws cloudfront create-invalidation) to clear the cache when you update your content - Explore S3 access logging to see who's visiting your site
- Deploy a React or Next.js build the same S3 + CloudFront pattern scales directly to frontend frameworks
The static web hosting pattern is one of the most reusable skills in your AWS toolkit. Once you have it down, you'll reach for it constantly.
I’m also excited to share that I’ve been able to secure a special discount, in partnership with Sanjeev Kumar’s team, for the DevOps & Cloud Job Placement / Mentorship Program.
For those who may not be familiar, Sanjeev Kumar brings over 20 years of hands-on experience across multiple domains and every phase of product delivery. He is known for his strong architectural mindset, with a deep focus on Automation, DevOps, Cloud, and Security.
Sanjeev has extensive expertise in technology assessment, working closely with senior leadership, architects, and diverse software delivery teams to build scalable and secure systems. Beyond industry practice, he is also an active educator, running a YouTube channel dedicated to helping professionals successfully transition into DevOps and Cloud careers.
This is a great opportunity for anyone looking to level up their DevOps/Cloud skills with real-world mentorship and career guidance.
Do refer below for the link with a dedicated discount automatically applied at checkout;
DevOps & Cloud Job Placement / Mentorship Program.
If you also found this interesting and would love to take the next steps in the application process with AltSchool Africa do use my referral link below;
Apply here or use this Code: W2jBG8 during the registration process and by so doing, you will be supporting me and also getting a discount!
Special Offer: By signing up through the link and using the code shared, you’ll receive a 10% discount!
Don’t miss out on this opportunity to transform your future and also save while doing it! Let’s grow together in the tech space. Also feel free to reach out if you need assistance or clarity regarding the program.
I’m Ikoh Sylva, a passionate cloud computing enthusiast with hands-on experience in AWS. I’m documenting my cloud journey here from a beginner’s perspective, aiming to inspire others along the way.
If you find my contents helpful, please like and follow my posts, and consider sharing this article with anyone starting their own cloud journey.
Let’s connect on social media. I’d love to engage and exchange ideas with you!
Top comments (0)