Lambda continuous deployment with GitHub actions

This tutorial builds a continuous deployment (CD) pipeline between GitHub and AWS Lambda using GitHub actions.

Packaging and deploying your function and its dependencies with AWS Lambda can sometimes be a tedious job. Especially if you also want to use a source code management platform like GitHub to develop your code before pushing it to AWS Lambda.

You can use GitHub actions to set up automatic deployment for AWS Lambda from a Github repository. You need to push a commit to the main or master branch of your repository, then let GitHub actions create the deployment package, and deploy your code to AWS Lambda.

Prerequisites

Creating a new Lambda function in AWS console

  1. Create a new Lambda function called lambda-cd by navigating to the AWS Lambda console and creating a new function:

    create new function

  1. Add lambda-cd as your function name, choose your preferred runtime environment, and click Create function:

    create lambda from scratch

  1. Take a note of the function name, you need it later to configure the deployment file.

Creating a new GitHub repository

Now you can create a new GitHub repository which contains the function code.

  1. Create a new GitHub repository.

  2. On your local system, create a new project folder called lambda-cd:

    1. mkdir lambda-cd
    2. cd lambda-cd
  3. Create the Lambda function that you want to upload. As an example, here’s a Python Lambda function which returns data from a TimescaleDB table called stocks_intraday (read the tutorial to build a TimescaleDB API with Lambda here).

    1. touch function.py
    2. # function.py:
    3. import json
    4. import psycopg2
    5. import psycopg2.extras
    6. import os
    7. def lambda_handler(event, context):
    8. db_name = os.environ['DB_NAME']
    9. db_user = os.environ['DB_USER']
    10. db_host = os.environ['DB_HOST']
    11. db_port = os.environ['DB_PORT']
    12. db_pass = os.environ['DB_PASS']
    13. conn = psycopg2.connect(user=db_user, database=db_name, host=db_host,
    14. password=db_pass, port=db_port)
    15. sql = "SELECT * FROM stocks_intraday ORDER BY time DESC LIMIT 10"
    16. cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    17. cursor.execute(sql)
    18. result = cursor.fetchall()
    19. return {
    20. 'statusCode': 200,
    21. 'body': json.dumps(list_of_dicts, default=str),
    22. 'headers': {
    23. "Content-Type": "application/json"
    24. }
    25. }
  4. Initialize a git repository and push the project to GitHub:

    1. git init
    2. git add function.py
    3. git commit -m "Initial commit: add Lambda function"
    4. git branch -M main
    5. git remote add origin <YOUR_GITHUB_PROJECT_URL.git>
    6. git push -u origin main

At this point, you have a GitHub repository with just the Lambda function in it. Now you can connect this repository to the AWS Lambda function.

Connect GitHub and AWS Lambda

Connect the Github repository to AWS Lambda using Github actions.

Adding your AWS credentials to the repository

You need to add your AWS credentials to the repository so it has permission to connect to Lambda. You can do this by adding GitHub secrets using the GitHub command-line.

  1. Authenticate with GitHub:

    1. gh auth login

    Choose which account you want to log in to. Authenticate with your GitHub password or authentication token.

  2. Add AWS credentials as GitHub secrets. By using GitHub secrets, your credentials are encrypted and cannot be seen publicly. Use the gh secret set command to upload your AWS credentials one by one (you’ll be prompted to paste the values for each one):

    AWS_ACCESS_KEY_ID:

    1. gh secret set AWS_ACCESS_KEY_ID

    AWS_SECRET_ACCESS_KEY:

    1. gh secret set AWS_SECRET_ACCESS_KEY

    AWS_REGION:

    1. gh secret set AWS_REGION
  3. To make sure your credentials have been uploaded correctly, you can list the available GitHub secrets:

    1. gh secret list
    2. AWS_ACCESS_KEY_ID Updated 2021-09-13
    3. AWS_SECRET_ACCESS_KEY Updated 2021-09-13
    4. AWS_REGION Updated 2021-09-13

Now you know that you have your AWS credentials available for the repository to use.

Setting up GitHub actions

You can now set up some automation based on the “AWS Lambda Deploy” GitHub action to auto-deploy to AWS Lambda.

  1. Create a new YAML file that contains the deployment configuration:

    1. touch .github/workflows/main.yml
  2. Add this content to the file:

    1. name: deploy to lambda
    2. on:
    3. # Trigger the workflow on push or pull request,
    4. # but only for the main branch
    5. push:
    6. branches:
    7. - main
    8. jobs:
    9. deploy_source:
    10. name: deploy lambda from source
    11. runs-on: ubuntu-latest
    12. steps:
    13. - name: checkout source code
    14. uses: actions/[email protected]
    15. - name: default deploy
    16. uses: appleboy/lambda-[email protected]
    17. with:
    18. aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    19. aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    20. aws_region: ${{ secrets.AWS_REGION }}
    21. function_name: lambda-cd
    22. source: function.py

    This configuration deploys the code to Lambda when there’s a new push to the main branch.

    As you can also see in the YAML file, the AWS credentials are accessed using the ${{ secrets.AWS_ACCESS_KEY_ID }} syntax. Make sure to use the name of the Lambda function (as displayed in the AWS console) for the function_name property in this configuration file. (“lambda-cd” in this example).

Testing the pipeline

You can test if the hook works by pushing the changes to GitHub.

  1. Push the changes to the repository:

    1. git add .github/workflows/main.yml
    2. git commit -m "Add deploy configuration file"
    3. git add function.py
    4. git commit -m "Update function code"
    5. git push
  2. Navigate to the GitHub actions page of your repository, to see the build run and succeed:

    github action build

You now have a continuous deployment pipeline set up between GitHub and AWS Lambda.