Automate Angular SPA application deployment to Amazon S3 using GitHub Actions

In this post, we’ll show how to configure and deploy your Angular SPA application to Amazon S3 with GitHub Actions.

Prerequisites

This is the list of all the prerequisites for following this story:

  • Node
  • Angular CLI
  • An active AWS account
  • A GitHub repository
  • Git

What is Amazon S3?

Amazon S3 is a simple storage service that helps developers and IT teams to store, backup, archive, and retrieve data from anywhere on the web. It allows administrators to store data in categories, add tags to objects, configure access controls for multiple clients, perform high-volume data analysis, get insights into the storage usage, and measure trends based on activities.

https://aws.amazon.com/s3

Setting Up S3 bucket in AWS Console

Create s3 bucket

After you log in to the AWS Management Console (https://console.aws.amazon.com/console/home),

Go to Services -> Storage -> S3

Then press **Create bucket** button.

Add Bucket policy

Go to Bucket > Permissions Tab > Bucket policy

Add Bucket policy written in JSON


    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::angular-app-github-action/*"
        }
    ]
}

To fix “An error occurred (AccessControlListNotSupported) while calling the PutObject operation: The bucket does not allow ACLs”, we need to enable bucket ACLs

Go to Bucket > Permissions Tab > Object Ownership

Create an IAM User for Github

Go to https://console.aws.amazon.com/iam/. In the navigation pane, choose Users and then select **Add user**.

Press Next: Permissions button -> go to Set permissions for our new user.

Now, choose Attach existing policies directly -> filter policy type s3, then check **AmazonS3FullAccess**. Then click on “Next Review“.

Once you have successfully created the user, download .csv for downloading the credentials. {Access key ID, Secret access key}.

GitHub repository setup

Create a project repository

In your GitHub account, Create a public repository

Add Actions secrets

Click on the menu Settings > Secrets > Actions

Populate keys/values with access key ID and secret access key. ex: for ‘access key ID’ we will name the key AWS_ACCESS_KEY_ID and the values are those obtained from AWS. We will do the same for the secret access key (AWS_SECRET_ACCESS_KEY)

Creating and configuring the Angular application

Now, let’s create the angular project.

  • Clone project

git clone https://github.com/anicetkeric/angular-app-github-actions-s3.git

  • Create a new workspace and an initial application

ng new angular-app-github-actions-s3

  • Serve the application

ng serve --open

The --open (or just -o) option automatically opens your browser to http://localhost:4200/.

Create the .github/workflows/main-deploy.yml file in the project directory

name: deploy aws S3

# Controls when the action will run. Triggers the workflow on push
# events but only for the main branch
on:
  push:
    branches:
    - main

jobs:
  deploy-to-s3:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    
    - name: Check out Git repository
      uses: actions/checkout@v2 
    
      #install node and npm
    - name: Setup Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '14.x'

    # Allows for re-using node_modules caching, making builds a bit faster.
    - name: node_modules caching
      uses: actions/cache@v1 
      with:
        path: ~/.npm
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.os }}-node-   
    # Install the node modules
    - name: NPM Install
      run: npm install    

    # Run all tests
    - name: Run tests
      run: |
          npm test -- --no-watch --no-progress --browsers=ChromeHeadlessCI
    # Create dev build
    - name: NPM build Angular
      run: npm run build

    # Create production build
    #- name: Production Build
    # run: npm run build --prod 

    # Deploy to S3
    - name: Deploy to S3
      uses: jakejarvis/s3-sync-action@v0.5.1
      with:
          # --acl public read => makes files publicly readable(i.e. makes sure that your bucket settings are also set to public)
          # --delete => permanently deletes files in S3 bucket that are not present in latest build
        args: --acl public-read --follow-symlinks --delete  
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
        AWS_REGION: ${{ secrets.AWS_REGION }}
        SOURCE_DIR: 'dist/angular-app-github-actions-s3/'
  • AWS_ACCESS_KEY_ID: AWS Access Key
  • AWS_SECRET_ACCESS_KEY: AWS Secret Access Key
  • AWS_S3_BUCKET: The name of the bucket we’re syncing to.
  • AWS_REGION: The region in which the bucket was created.

Now, push the code to main branch.

As we can see in the image above, all the steps we created have been executed successfully.

Our application is available in the AWS S3 bucket, it can be accessed with the bucket website endpoint.

All done.

The complete source code is available on GitHub.

References

👉 Link to Medium blog

Related Posts