
I gave my AWS portfolio a real domain and auto-deploys. Here are the errors that almost stopped me
I moved my AWS portfolio from a random CloudFront URL to my own domain and set up GitHub auto-deploys. Here are the certificate errors, DNS mix-ups and reload bugs I hit, and how I fixed each one.
In my last article, I put my portfolio on AWS with S3 and CloudFront. It worked, but I wasn't done. My URL was a random string ending in
.cloudfront.net, and every change meant building the site, uploading files by hand, and clearing the CloudFront cache. On Netlify I never had to think about any of that. I pushed to GitHub and the site was live.So I gave myself two goals: use my own domain, and make GitHub deploy for me. Both took longer than I expected, mostly because of error messages. Here's what actually happened.
Getting a domain for free
I'm a student, so I checked my GitHub Student Developer Pack and found a free domain offer from Namecheap. I picked
laveezajamshaid.me. It's free for the first year only.One surprise: Namecheap's student bundle had already pointed my domain's DNS at GitHub Pages, with four A records and a
www CNAME. Those had to go before CloudFront could take over.Error #1: the certificate region
For HTTPS on a custom domain, CloudFront needs a certificate from AWS Certificate Manager, and that certificate has to live in
us-east-1. My account is on the free plan, which keeps me in one region (Sydney). When I opened ACM in N. Virginia, a pop-up told me the region was unavailable and offered a button called "Activate advanced features". I didn't click it, because I had no idea what it would cost.What worked: I opened my CloudFront distribution, clicked Add domain, and let CloudFront create the certificate for me. It handled the region part by itself.
Error #2: "We couldn't find a certificate that covers your domain"
I had ticked the wildcard option, so my certificate was for
*.laveezajamshaid.me. Then CloudFront complained that no certificate covered the domain I had typed. A wildcard covers subdomains like www, but not the root domain itself.The quick fix was to make
www.laveezajamshaid.me my main address. After I pressed Refresh certificates, the red error went away.Two more oddities. The "View in ACM" link said the certificate was not found, because it opened the Sydney console while my certificate lived in
us-east-1. And I ended up with two identical certificates, probably because I got impatient while it was validating and clicked Create twice. Both are free, so I just picked one.DNS validation in Namecheap
To prove the domain is yours, AWS gives you a CNAME record to add. In Namecheap, the box called Target is where AWS's "value" goes, and for Host you only paste the first part of the name, without your domain at the end. It's easy to mix those up.
After validation, I deleted the GitHub Pages records and added one new CNAME: host
www, pointing to my CloudFront domain. Then I waited, because DNS is never instant. Eventually https://www.laveezajamshaid.me opened my portfolio, padlock and all.The bare domain without
www still doesn't work for me, so I always share the www link.Making GitHub deploy for me
Netlify rebuilt my site on every push. S3 doesn't do that, so I used GitHub Actions.
First, an IAM user only for deploying. I called it
github-actions-deploy and gave it a small custom policy: it can list, upload and delete files in my one bucket, and create CloudFront invalidations. Nothing else. On the permissions screen, "Copy permissions" is selected by default, but I had no other users to copy from, so I chose Attach policies directly.Then I created an access key for that user and saved the two values as GitHub repository secrets,
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. I didn't paste them anywhere else, not in code and not in screenshots.I made the workflow file on GitHub's website: Add file, then Create new file, and I typed
.github/workflows/deploy.yml as the name. GitHub creates the folders when you type the slashes. This is what's inside:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
name: Deploy to AWS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-southeast-2
- run: aws s3 sync dist/ s3://YOUR-BUCKET --delete
- run: aws cloudfront create-invalidation --distribution-id YOUR_DISTRIBUTION_ID --paths "/*"The last two lines do the manual work I used to do: upload the new build, then tell CloudFront to forget the old cached files. The first run got a green tick and my site updated.
Error #3: AccessDenied when I reload a page
Everything looked perfect until I reloaded a page like
/about. Instead of my site, I got a plain XML message saying AccessDenied.My portfolio is a single-page app. There's only one real file,
index.html, and JavaScript handles the routes. Clicking around works, but a reload sends the path to S3, and S3 has no file called about. Because my bucket is private, S3 answers with a 403 instead of a 404.On Netlify, a redirects file solved this. On CloudFront, the fix lives under Error pages. I created custom error responses for both 403 and 404, each returning
/index.html with a 200 status. After a few minutes, reloading any page worked.What I'd tell another beginner
- Read the error text twice. Half of my problems were written in plain words on the screen.
- Give your deploy user the smallest permissions it needs, and keep its keys in GitHub secrets.
- Don't click upgrade buttons you don't understand yet.
What's next
I'd like to replace the access keys with an OIDC role, which is the safer way to deploy from GitHub. After that I want to try something bigger: a Laravel and React project using RDS and S3.
If you've set up a custom domain on CloudFront and hit different errors, I'd love to hear about them in the comments.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article