Automate Application deployment using GitHub Actions
Tags: github, automation, aws, serverless
Published: 2020-09-02 23:26:03



GitHub Actions makes it easy to automate all your software workflows. You can Build, test, and deploy your code right from GitHub. In this post we will explore how you can use GitHub Actions to automate serverless application deployment on AWS. You can also use AWS's own CI/CD services to achieve the same. But here we are going to keep our discussion limited to GitHub Actions.

### How to use GitHub Actions?
Creating a GitHub action is simple. Go to your GitHub repository that you want to automate and click on "Actions"
![github actions new workflow](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/github-action-create-new.PNG)

You will be taken to Actions page where you can create a new Blank workflow or select existing actions from the marketplace. The actions from marketplace are reusable actions that you can use in your workflow. We are going to create a blank action and we will also use some actions from marketplace.
![github actions blank action](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/github-actions-blank-workflow.PNG)

Lets rename the YAML file to workflow.yml. You can name anything you like. We are going to create a Lambda function with API gateway in Serverless Application Model (SAM) template and deploy it using GitHub Actions. 
Below is our SAM template.
``` YAML
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  GitHub Actions demonstration App
Resources:
  ApiGatewayApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
    Auth:
     UsagePlan:
      CreateUsagePlan: PER_API
      Description: Usage plan for this API
      Quota:
       Limit: 500
       Period: MONTH
      Throttle:
       BurstLimit: 100
       RateLimit: 50
  LamdbaFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./    
      Handler: lambda.handler
      Runtime: python3.8
      Events:
        getCounter:
          Type: Api
          Properties:
            Path: /hello
            Method: get
            RestApiId: !Ref ApiGatewayApi
```
lambda.py
```
def handler(event, context):
            return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        'body':'Hello from Lambda!'
        ,
        "isBase64Encoded": False
    }
```
This contains one Lambda function and API with path hello. Lets first deploy manually using SAM CLI and then we will automate it. Create samconfig.toml with below details.
create s3_bucket that will be used for SAM deploy and update in samconfig.toml.

``` 
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "sam-github-actions-app"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1xyg1t2j2ws5k"
s3_prefix = "sam-app"
region = "us-east-1"
confirm_changeset = false
capabilities = "CAPABILITY_IAM"
```
Also create empty requirements.txt along with template.yml. Run **SAM build** and **SAM deploy -g** on CLI. 
![SAM Deploy](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/sam-deploy.PNG)

Go to API gateway and hit the url in browser. You should get "hello from Lambda!" response.
![github actions api](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/api.PNG)

Go back to our workflow file on GitHub. We will deploy as soon as we push updates to the repo.
Below is our workflow.yml
``` YAML
# This is a basic workflow to help you get started with Actions
name: AWS Lambda & API gateway deployment demonstration
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [ master ]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # 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:
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - uses: actions/checkout@v2
    # Installs Python
    - name: Set up Python 3.8
      uses: actions/setup-python@v2
      with:
        python-version: 3.8
    # Installs PIP
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
    # Configures AWS credentials from github secrets
    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: us-east-1
    # Build using SAM 
    - name: SAM Build
      uses: youyo/aws-sam-action/python3.8@master
      with:
        sam_command: build
      env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION:  us-east-1
    # Deploy on AWS
    - name: sam deploy
      uses: youyo/aws-sam-action/python3.8@master
      with:
          sam_command: 'deploy --stack-name myApp --no-fail-on-empty-changeset'
      env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION: us-east-1
```

We first indicate that we want to run this action on push to the master. Then we select runner (Ubuntu) on which our steps will execute. In Steps, we first checkout code, then install python and its dependencies. Then we use other actions from marketplace to configure AWS credentials and then we use another action to do SAM build and SAM deploy.  Please note that we need ti supply AWS ACCESS KEY and SECRET ACCESS KEY to actions for commands to work. We setup here GitHub Secrets.

![Github secrets](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/secrets.PNG)

As soon as you check-in workflow.yml, the action would trigger.
![Github actions workflow trigger](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/workflow_build.PNG)

Deploying stack
![Github actions deploying AWS stack](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/deploy.PNG)
![Github Actions job completes](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/job_complete.PNG)

Now you can login to the AWS console and confirm the stack is created.
![AWS cloud formation stack created](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/stack_created.PNG)

Go to Resources tab and access the API Gateway. Go to stages and access the Prod stage API.
Open the URL in browser with the path /hello and you should see below output!

![AWS Lambda function output](https://s3.amazonaws.com/blog-images-rajanpanchal.net/github-actions/testing.PNG)

Congratulations! You have successfully automated AWS deployment using GitHub Actions!
You can download the code from here:  
[![github actions repo card](https://github-readme-stats.vercel.app/api/pin/?username=rajanpanchal&repo=aws-github-actions)](https://github.com/rajanpanchal/aws-github-actions)