Serverless AWS CICD with Github Actions


Setting up continuous development and deployment (CI/CD) to automatically deploy your serverless project can get really confusing. There are so many tools out there and each of them has its pros and cons and all of them are configured differently.

Luckily I’m going to be explaining to you how to set up my favourite – Github actions.

Why use Github Actions

Github Actions is super easy to set up super powerful. I use it on every project I can and encourage my clients to do the same.

In our repo there are a couple of things that we need to make sure are set up before we try and implement Github actions.

  • The first is that we’ve got to have a serverless repo. In this article we’ll us a basic serverless repo just that was set up using the aws-nodejs-typescript template.
  • The second is to have that connected to a Github account.

Github Actions Workflow Setup

With those two things set up we can start talking about how to get the actions working. There are two steps to getting a serverless repo deploying with github actions.

  1. Creating the github actions workflow. This is the file that describes the steps that it Github will use to actually do the deployment
  2. Adding AWS credentials to the action so that it is able to deploy to AWS.

We’re going to start with the workflow. Go into our folder structure and create a new folder called .github/workflows. In here we can create a new file called deploy-master.yaml.

Now, you can manually write these scripts, they’re just yaml commands using bash. But what we can also do is copy get an example one from github itself. Go to This Link and find the workflow example.

We can just copy this file head back into our editor and paste that all in.

name: Deploy master branch

on:
  push:
    branches:
      - master

jobs:
  deploy:
    name: deploy
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14.x]
    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm ci
    - name: serverless deploy
      uses: serverless/github-action@v3
      with:
        args: deploy
      env:
        SERVERLESS_ACCESS_KEY: ${{ secrets.SERVERLESS_ACCESS_KEY }}
        # or if using AWS credentials directly
        # AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        # AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Lets break this file down a bit.

on:
  push:
    branches:
      - master

This bit means that whenever someone pushes to the branch of master, Github actions will run this job. That means if I push to a dev branch nothing will happen.

jobs:
  deploy:
    name: deploy
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [14.x]

Now we are defining the job that will run. We’re calling the job deploy, setting it to run on Ubuntu we’re just using node 14.

steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm ci

Now we’re defining the steps that will run when the job is triggered. It starts by checking out the latest code, sets up NodeJS using the version we defined earlier, and finally installs dependancies with npm ci.

    - name: serverless deploy
      uses: serverless/github-action@v3
      with:
        args: deploy
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

The last step is running serverless deploy. By default it will just run the serverless deploy command but you specify further flags ing the args section.

It’s definitely worth taking note that by default this deployment workflow will use the serverless version 3. If you want to use the serverless version 2 or version 1, all you need to do is change this serverless/github-action@v3 to v2 from version 3. Github will then use the correct framework version.

Adding AWS Credentials to Environment Variables

The last part is the environment variables. This is how we are going to give access to deploy to our aws account. We need to pass an AWS access key and secret access keys to the action. We need to create a user in our aws account to do the deployment. If we head over to our aws account and go to IAM, we need to find the users section and add a new user.

Give this user a name. I usually go with something like githubActionsUser and set them to have programmatic access. We want to attach an existing policy directly to this user of administrator access. That means that give up actions has the ability to do whatever it needs. We can hit continue until we create the user and you get to this page. Make sure you do not close it because we need this access key and secret key but is only shown at this point and disappears afterwards.

If we look in our code it says that the environment of AWS_ACCESS_KEY_ID is defined by secrets.AWS_ACCESS_KEY_ID. Go into our github account and then go to repo settings. Then scroll down to secrets and actions where we can create some secrets on this repo. Copy the access key id from the AWS console and paste that as the value

Repeat this but for the AWS_SECRET_ACCESS_KEY.

Now we can see that there is an AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY both available inside this repo for CICD. When a deployment is triggered, these environment variables will be used to deploy to our aws account.

Testing the Action Workflow

We can now actually save this change to our master branch, commit it and push it to Github. To see it working, we can go back into our github account and the actions menu. We can see that we have one action that has just started running it takes a minute or two to complete.

Once finished running, there are two ways we can check what has happened. Go into the workflow and you can see there is one job completed. In that one job there was a single deployment using node 14. Here you can see the logs that happened at each stage. The interesting stage for us is the serverless deploy one. At the bottom there is the final output, the url for the endpoint as well as the function that was generated

The other way that we can check is by going back into our aws account and searching for lambda. Inside our lambdas we should find githubactions-dev-hello.

Now you know how to set up automatic deployment of your serverless project using github actions. This makes your life so much easier all you need to do is make a change and to merge it or push it to a branch and it will be automatically deployed.

To take this to the next level you can have multiple scripts for deploying to different environments.

  • A development account can be pushed to from your dev branch
  • A QA or integration branch you can then deploy to your account and then also do some smoke tests to it
  • A production branch runs all tests and does smoke tests too.

This gives you the flexibility to both develop quickly, especially when you’ve got an agile team, but also have security knowing anything that is going into QA or Production is really robust.

Sam Williams

Sam is a Serverless Obsessive who runs Complete Coding, helping developers learn Serverless and companies make the most of the competitive advantage that Serverless gives them. Previous projects include: - Designing a chat platform that currently resolves over 250,000 customer inquiries a month for international retailers and local government - Architecting a backend system to support a 3D clothing visualisation tool - Building a solution to manage millions of dollars of communication software - Designing a "Video Editing in the Cloud" platform, enabling everyone from movie studios to indie film makers to harness the power of the Cloud - without needing to be cloud experts. - Launching a profitable Serverless Startup in under 30 days He has also been teaching cloud-based software development for 5 years and has taught Serverless development to thousands of people. The Complete Coding Youtube channel now has over 15,000 subscribers and over 1 million views

Recent Posts