AWS

This activity demonstrates how to create a CI/CD pipeline that will copy a GitHub repo to an S3 bucket whenever you run git push origin main. Once the code is moved to an S3 bucket you could build a pipeline in AWS to deploy it in many ways. The optional steps in the activity demonstrate how to publish the S3 bucket as a static website.

Set up a Repo

Create a GitHub repo and put a very simple index.html file in it.

Create an S3 Bucket

  1. Create a bucket

Optional - Configure the Bucket for Static Website Hosting

If you want to host a static website site from an S3 bucket, then you need to uncheck the box to Block All Public Access (you can do this when creating the bucket, or by going to the bucket properties tab)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid":"Allow Public Read",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::BUCKET-NAME-GOES-HERE/*"
    }
  ]
}

To serve a website from the bucket:

  1. Go to the bucket properties
  2. Scroll down to the Static Website Hosting section and click Edit
  3. Select Enable
  4. Set the Index Document to index.html
  5. Then you can get the URL for it by looking at the Bucket Website Endpoint

Create an Identity Provider

An Identity Provider allows you to let an external system handle authentication, and AWS trusts it. In this case we'll tell AWS to trust Github

  1. Go to the IAM dashboard
  2. Click on Identity Providers in the left nav
  3. Click Add Provider
  4. Select OpenID Connect
  5. For the Provider URL, enter https://token.actions.githubusercontent.com
  6. For the Audience, enter sts.amazonaws.com
  7. Click Add Provider

Create an IAM Role for GitHub Actions

  1. In the IAM dashboard, click Roles (in the left nav)
  2. Click Create Role
  3. Select Web Identity
  4. For the Provider, select the provider you created in the previous step (token.actions.githubusercontent.com)
  5. For the Audience, select sts.amazonaws.com
  6. For the GitHub Organization, enter your GitHub username
  7. Optional - for the GitHub Repository you could enter the name of your repo, but then I think the role could only be used for that repo
  8. Click Next
  9. You could add a managed policy that allows S3FullAccess, but it would be better to create a custom policy that allows only the permissions needed (do this after the role is created)
  10. Enter a role name (like GitHubAccessRole)
  11. Click Create Role
  12. In the Permissions tab of the new role, click the Add Permissions drop down and choose Create Inline Policy
  13. For the Service, select S3
  14. Click the JSON button (to add a JSON policy)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::BUCKET-NAME-GOES-HERE"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::BUCKET-NAME-GOES-HERE/*"
    }
  ]
}

Add a deploy.yml to the repository

  1. Create a .github folder in the repository folder
  2. Create a workflows folder in the .github folder
  3. Create a deploy.yml file in the workflows folder
  4. Put this in the deploy.yml file:
  5. Set the ARN of the role
  6. Set the region
  7. Set the bucket name
name: Deploy to S3

on:
  push:
    branches:
      - main # OR master ???

permissions:
  id-token: write  # Required for OIDC
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          # SET THIS TO THE ARN OF THE  ROLE:
          role-to-assume: PUT TH ARN OF YOUR GITHUB ROLE HERE
          # MAKE SURE THE REGION IS CORRECT:
          aws-region: us-east-2 
      
      # USE YOUR BUCKET NAME (below)
      - name: Sync to S3
        run: |
          aws s3 sync . s3://BUCKET-NAME-GOES-HERE/ --exclude ".git/*"