Skip to content

Instantly share code, notes, and snippets.

@DominiquePaul
Last active April 26, 2024 09:45
Show Gist options
  • Save DominiquePaul/15be5f5da95b2c30684ecdfd4a151f27 to your computer and use it in GitHub Desktop.
Save DominiquePaul/15be5f5da95b2c30684ecdfd4a151f27 to your computer and use it in GitHub Desktop.
GitHub Action for auto-deploying a container based lambda function

Deploying your Lambda Function to AWS automatically with GitHub Actions

How to Configure this GitHub Action

This guide details how to set up a GitHub Action for deploying an AWS Lambda function from a Docker container image hosted in Amazon ECR.

Prerequisites

  • An AWS account with access key and secret access key configured.
  • A Docker container or dummy container image for initializing your Lambda function.

Setup Instructions

  1. Configure Secrets:

    • Navigate to Repo settings -> Security -> Secrets and Variables -> Actions -> Repository secrets.
    • Add your AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
  2. Initial Lambda Setup with Dummy Image:

    • You need to create your Lambda function in AWS using a Docker container. Initially, you can use a "dummy" Docker container. This is just a workaround to get your actual Lambda function created and configured in AWS.
    • For pushing a dummy image to AWS's ECR, refer to Amazon ECR Docker Basics.
    • Once your Lambda function is created, you will replace this dummy container with your actual application container through this GitHub Action.
  3. Prepare and Place the GitHub Action YAML File:

    • Create a .github/workflows directory in your repository if it doesn't already exist.
    • Place the github_action_lambda.yaml file inside this directory. This is where GitHub Actions expects to find YAML files defining workflows.
  4. Modify GitHub Action Configuration:

    • Update the arn:aws:lambda:YOUR_REGION:YOUR_ACCOUNT_ID:function:YOUR_FUNCTION_NAME in the YAML file with your Lambda function's ARN.
    • Replace YOUR_DOCKER_REPOSITORY_NAME with the name of your Docker repository in the ECR.
    • Adjust AWS_REGION as necessary. The default is set to eu-central-1.
    • Replace YOUR_LAMBDA_FUNCTION_NAME
  5. Update Docker Platform (if necessary):

    • For ARM-based Lambda functions, replace --platform linux/amd64 with --platform linux/arm64.
    • To specify the Dockerfile location, modify the build step to include -f path/to/your/Dockerfile.
  6. Environment Variables and Secrets:

    • Upload a JSON file containing your Lambda function's environment variables (e.g., {"SLACK_BOT_TOKEN": "XXX"}) to an S3 bucket.
    • Replace s3://bucket-name/secrets.json with the path to your JSON file in the YAML configuration.

Additional Notes

  • This setup includes an automated update for Lambda function environment variables using the uploaded JSON file.
  • Remember to review and test each component of your workflow to ensure it operates as expected within your AWS and GitHub environments.
name: Deploy Lambda on push to master
on:
push:
branches:
- master
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-central-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Ensure ECR repository exists
env:
AWS_REGION: eu-central-1
ECR_REPOSITORY: YOUR_DOCKER_REPOSITORY_NAME
run: |
aws ecr describe-repositories --region $AWS_REGION --repository-names $ECR_REPOSITORY || aws ecr create-repository --region $AWS_REGION --repository-name $ECR_REPOSITORY
echo "ECR URL: $ECR_REGISTRY/$ECR_REPOSITORY"
- name: Build, tag, and push image to Amazon ECR
env:
AWS_REGION: eu-central-1
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: YOUR_DOCKER_REPOSITORY_NAME
IMAGE_TAG: latest
run: |
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY
docker build --platform linux/amd64 -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "Pushed to ECR URL: $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
- name: Update Lambda Function Code
env:
AWS_REGION: eu-central-1
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: YOUR_DOCKER_REPOSITORY_NAME
FUNCTION_NAME: YOUR_LAMBDA_FUNCTION_NAME
IMAGE_TAG: latest
run: |
aws lambda update-function-code \
--function-name arn:aws:lambda:eu-central-1:764118177562:function:YOUR_FUNCTIONS_NAME \
--image-uri ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}
echo "Waiting for the update to complete..."
aws lambda wait function-updated --function-name ${{ env.FUNCTION_NAME }}
- name: Download Secrets from S3
run: |
aws s3 cp s3://bucket-name/secrets.json secrets.json
- name: Update Lambda Function Configuration
env:
AWS_REGION: eu-central-1
run: |
jq -c '{Variables: .}' secrets.json > env_vars.json
aws lambda update-function-configuration \
--function-name arn:aws:lambda:eu-central-1:764118177562:function:YOUR_FUNCTIONS_NAME \
--environment file://env_vars.json
echo "Lambda environment variables updated from secrets.json"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment