cloudwithshad
BUILD-ON-YOUR-OWN ยท ~75 MINUTES

Build a CI/CD pipeline โ€” GitHub โ†’ AWS

Push code to GitHub. GitHub Actions builds it. AWS deploys it. All in 90 seconds โ€” automatically, every time. The same workflow used by every dev team in the world.

5
PHASES
75 min
DURATION
FREE
TIER OK
GitHub + S3
SERVICES
๐Ÿ› ๏ธ

This one's on you

Lab 6 is a build-on-your-own challenge. We give you the goal, the YAML, and the IAM setup โ€” you wire it together. By the end, you'll have a portfolio-grade pipeline you can show employers. Stuck? Expand the hints (๐Ÿ’ก).

1
The goal

By the end of this lab, every git push to your main branch will automatically deploy your website to AWS S3. No manual upload. No "let me redeploy". Pure automation.

You git push GitHub your-repo webhook GitHub Actions build ยท test ยท deploy aws sync S3 Bucket static hosting ๐ŸŒ Live
Push to GitHub โ†’ Actions runs โ†’ AWS S3 updates โ†’ world sees it. 90 seconds total.

What you'll build:

  • A GitHub repo containing a simple HTML/CSS site (or use your Week 1 portfolio)
  • An S3 bucket configured for static website hosting
  • An IAM user with limited permissions for GitHub to use
  • A .github/workflows/deploy.yml file that auto-deploys on every push
  • Bonus: a CloudFront distribution for a real custom domain feel
2
Phase 1 โ€” Create the GitHub repo
1
Sign in to GitHub. Click the + in the top-right โ†’ New repository.
2
Repository name: cloudwithshad-week3-site (or whatever you prefer)
3
Visibility: Public (so employers can see your work)
4
Tick Add a README file. Click Create repository.
5
Clone the repo locally: git clone https://github.com/YOUR-USERNAME/cloudwithshad-week3-site.git
6
Add an index.html file with simple content (or copy your Week 1 portfolio in)

Here's a minimal index.html to get started:

<!-- index.html --> <!DOCTYPE html> <html> <head><title>cloudwithshad CI/CD demo</title></head> <body style="font-family: sans-serif; background: #0A1628; color: #fff; text-align: center; padding: 80px;"> <h1>Deployed by GitHub Actions โ˜๏ธ</h1> <p>Last updated: <strong>Day 1</strong></p> <p style="opacity:0.7">cloudwithshad ยท Week 3 Lab 6</p> </body> </html>

Commit and push:

git add . git commit -m "Initial site" git push origin main
3
Phase 2 โ€” Create an S3 bucket for hosting

This is similar to Week 1 Lab 1 โ€” but quicker, because you've done it before.

1
Go to S3 โ†’ Create bucket
2
Bucket name: cloudwithshad-week3-yourname-12345 (must be globally unique)
3
Uncheck "Block all public access" (we're hosting a public site)
4
Acknowledge the warning. Click Create bucket.
5
Open the bucket โ†’ Properties โ†’ scroll to Static website hosting โ†’ Edit โ†’ Enable โ†’ Index document: index.html โ†’ Save
6
Switch to the Permissions tab โ†’ Bucket policy โ†’ paste the policy below (replace BUCKET-NAME)
{ "Version": "2012-10-17", "Statement": [{ "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::BUCKET-NAME/*" }] }

Save the policy. Copy the Bucket website endpoint (from the Properties tab) โ€” looks like http://YOUR-BUCKET.s3-website-region.amazonaws.com. Save it.

4
Phase 3 โ€” Create an IAM user for GitHub Actions

GitHub Actions needs AWS credentials to deploy your site. We'll create a dedicated IAM user with the minimum permissions needed โ€” never share your personal AWS credentials!

1
IAM โ†’ Users โ†’ Create user
2
User name: github-actions-deploy
3
Do NOT tick "Provide user access to the AWS Management Console" (we only need API access)
4
Permissions: Attach policies directly โ†’ search for and tick AmazonS3FullAccess
5
Click through to Create user
6
Open the user โ†’ Security credentials tab โ†’ Create access key
7
Use case: Third-party service โ†’ Next โ†’ Create
8
CRITICAL: Copy both the Access key ID and Secret access key. The secret is shown ONCE only.
DANGER ZONE

NEVER commit these AWS keys to git. NEVER share them publicly. If they leak, attackers can spin up servers on your account and bill you thousands. If you accidentally expose them, delete them immediately from IAM and create new ones.

Production best practice

In production, you'd use OIDC (OpenID Connect) to let GitHub assume an IAM role without storing keys. For learning, access keys are fine. We'll cover OIDC in the advanced course.

5
Phase 4 โ€” Add secrets & create the workflow

Now we tell GitHub about the AWS keys (securely!) and write the workflow file that runs on every push.

Step 4a โ€” Add the AWS keys as GitHub Secrets

  1. Open your GitHub repo
  2. Click Settings tab โ†’ Secrets and variables โ†’ Actions
  3. Click New repository secret
  4. Add three secrets, one at a time:
    • AWS_ACCESS_KEY_ID โ†’ paste your access key ID
    • AWS_SECRET_ACCESS_KEY โ†’ paste your secret key
    • S3_BUCKET โ†’ paste your bucket name (just the name, no s3://)

Step 4b โ€” Create the workflow file

In your local repo, create the file .github/workflows/deploy.yml (you'll need to create the .github/workflows/ folders first):

# .github/workflows/deploy.yml name: Deploy to S3 on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v4 - name: Configure AWS credentials 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: af-south-1 # change to your region - name: Deploy to S3 run: aws s3 sync . s3://${{ secrets.S3_BUCKET }} --delete --exclude ".git/*" --exclude ".github/*" --exclude "*.md"

Save the file, then commit + push:

git add .github/workflows/deploy.yml git commit -m "Add CI/CD pipeline" git push origin main
What the YAML says, in English

"When someone pushes to the main branch, spin up an Ubuntu runner. Check out the code. Configure AWS using the secrets I gave you. Then sync all the files to my S3 bucket โ€” except the .git folder, the workflow files, and any markdown files."

6
Phase 5 โ€” Watch it deploy

The moment of truth.

  1. Open your GitHub repo in the browser
  2. Click the Actions tab
  3. You should see your "Deploy to S3" workflow running (yellow circle) or completed (green check)
  4. Click into it to see live logs
  5. Once green, open the S3 bucket website URL from Phase 2 โ€” your site is live!

Now the magic test โ€” change something and push again:

# Edit index.html, change "Day 1" to "Day 2" or anything else git add index.html git commit -m "Update homepage" git push origin main

Watch the Actions tab โ€” within 90 seconds, the workflow runs again. Refresh your S3 URL. The site updates automatically. No SSH. No FTP. No clicking "deploy" in any console.

Submission

Take a screenshot of: (1) the green checkmark in GitHub Actions, AND (2) the live S3 URL showing your updated content. Post both in the cohort WhatsApp group. Your shareable GitHub repo URL is your portfolio piece โ€” drop it on LinkedIn too. ๐Ÿš€

Hint: what to do when the workflow fails

Click into the failed run in the Actions tab. The error is at the bottom of the logs. Most common issues:

  • Access Denied: Bucket policy not set, or IAM user missing S3 permissions
  • Invalid credentials: Secret was pasted with extra spaces. Re-add it carefully.
  • Bucket not found: Region in workflow YAML doesn't match where the bucket lives
  • Workflow didn't run at all: Wrong path โ€” must be .github/workflows/, all lowercase, no typos

๐Ÿš€ Bonus challenges

Want to take it further? Try one of these โ€” each is portfolio gold:

  • CloudFront in front: Add a CloudFront distribution pointing to your S3 bucket. Now you have HTTPS, a CDN, and a real-looking URL.
  • Invalidate cache on deploy: Add an aws cloudfront create-invalidation step so users see new content immediately.
  • Run tests before deploy: Add a npm test step (or any test runner). If tests fail, the deploy is skipped โ€” this is true CI.
  • Environments: Make pushes to develop deploy to a staging bucket, pushes to main deploy to production.
  • Slack/Discord notification: Add a step that posts to your team channel after a successful deploy.
7
Clean up

S3 buckets in the free tier cost almost nothing, but it's good hygiene. Also: rotate your access keys.

  1. Empty the S3 bucket, then Delete the bucket
  2. Delete the IAM user (IAM โ†’ Users โ†’ github-actions-deploy โ†’ Delete)
  3. OR rotate the keys: if you want to keep the pipeline working, just delete the old access key and create a new one โ€” update the GitHub Secret
  4. Keep the GitHub repo! โ€” it's a portfolio piece
Why keep the repo

This is genuinely employer-impressive. Add it to your LinkedIn under Projects with the line: "Built a CI/CD pipeline that auto-deploys to AWS using GitHub Actions and S3." Employers love seeing this.

๐Ÿ”„

Lab 6 complete!

You just built the same CI/CD pattern used by Fortune 500 companies. Every push to main = automatic deploy. This is what makes "ship fast" possible.

Next week: AI services + capstone โ€” Textract, Comprehend, and your final project