This Portfolio: Static Hosting on S3, CloudFront and Route 53
The site you are reading started here: S3 for the files, CloudFront for HTTPS and edge caching, an ACM certificate, and a domain I registered and run in Route 53.
- When
- December 2025
- Context
- Project 1, my first AWS build, still serving ismailoyeleke.com
- Role
- Solo build
- Amazon S3
- CloudFront
- Route 53
- AWS Certificate Manager
The problem
I needed a portfolio of my own that was fast anywhere, served over HTTPS on a real domain, and cost almost nothing to run. A portfolio does not need a server, so I built it without one.
Loads from YouTube when you press play. Watch on YouTube.
Storage
- An S3 bucket named after the domain, in us-east-1, with static website hosting switched on and index.html as the index document.
- The HTML, CSS and JavaScript uploaded to the bucket, with a bucket policy allowing public read of the site files.
Domain and DNS
- ismailoyeleke.com registered through Route 53, with a public hosted zone to manage its records.
- An A record set as an alias to the CloudFront distribution, so the apex domain resolves without a fixed IP address.
Delivery and HTTPS
- A CloudFront distribution in front of the bucket, with the domain as an alternate name and HTTP redirected to HTTPS.
- A public certificate from AWS Certificate Manager, validated through DNS in Route 53 and attached to the distribution.
Decisions
- No server at all
- S3 and CloudFront serve static files without an instance to patch, scale or pay for while idle. The monthly bill is cents plus the domain.
- CloudFront in front of S3, not the bucket alone
- An S3 website endpoint cannot serve HTTPS on a custom domain. CloudFront adds the certificate, enforces HTTPS and caches the site close to visitors outside the region.
- Keep the domain and DNS in AWS
- With the domain registered in Route 53, the certificate validates through a DNS record in the same account, and the alias record can point straight at CloudFront.
What went wrong, and what fixed it
- Edits to index.html did not appear until I invalidated the CloudFront cache, so an invalidation is part of every deploy, not an afterthought.
- DNS changes take time to propagate. The fix was to check the records once and wait, not to keep changing them.
- A custom domain on HTTPS needs a validated certificate first. DNS validation through Route 53 made that a single record.
The result
- ismailoyeleke.com served over HTTPS from CloudFront, with no server to run.
- Every page cached at the edge, so the site loads quickly from Lagos and from abroad.
- The setup is documented step by step in the repository and on YouTube.
This rebuild is version two of the same project. The bucket is now private behind Origin Access Control, security headers come from CloudFront, and every change deploys from GitHub Actions through an OIDC role instead of a manual upload.