Skip to content

Deploy Lambda Functions #54

Deploy Lambda Functions

Deploy Lambda Functions #54

# TODO:
# 1. Add Build only GHA?
# 2. Add dev, test and prod stage so that the same image
# is used across all environments
# 3. Add static code anaylsis for Typescript?
name: Deploy Lambda Functions
on:
push:
branches:
- master
paths:
- "aws/**"
workflow_dispatch:
inputs:
environment:
description: "Select target environment"
required: true
default: "dev"
type: choice
options:
- dev
- test
- prod
env:
WORKING_DIRECTORY: ./aws
NODE_VERSION: 20
jobs:
get-lambdas:
runs-on: ubuntu-latest
outputs:
lambda_dir_list: ${{ steps.convert.outputs.LAMBDA_DIR_LIST }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get Lambda directories
id: lambdas
shell: bash
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
dirs=$(find lambdas -mindepth 2 -maxdepth 2 -type d | sed 's|lambdas/||' | paste -sd ';' -) # Space-separated
echo "LAMBDA_DIRS=$dirs" >> $GITHUB_ENV
- name: Convert FOLDERS to JSON array
id: convert
shell: bash
working-directory: ${{ env.WORKING_DIRECTORY }}
run: |
LAMBDA_DIR_LIST=$(echo "${LAMBDA_DIRS}" | jq -R 'split(";")' -c)
echo "LAMBDA_DIR_LIST=$LAMBDA_DIR_LIST" >> $GITHUB_OUTPUT
build-and-deploy:
needs: get-lambdas
environment: ${{ inputs.environment }}
permissions:
id-token: write
packages: write
runs-on: ubuntu-latest
env:
LAMBDA_ECR_REPO_URL: ${{ vars.AWS_ACCOUNT }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com/${{ vars.APP_NAME }}-lambda-ecr-repo-${{ vars.ENVIRONMENT_NAME }}
strategy:
matrix:
lambda: ${{ fromJSON(needs.get-lambdas.outputs.lambda_dir_list) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install dependencies
run: npm install
working-directory: ${{ env.WORKING_DIRECTORY }}
- name: Run build
run: npm run build
working-directory: ${{ env.WORKING_DIRECTORY }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-skip-session-tagging: true
aws-region: ${{ vars.AWS_REGION }}
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
role-duration-seconds: 1800
role-session-name: ci-deployment
- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v2
- name: Log in to the GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get short SHA
id: short_sha
run: |
echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Parse Resource and Lambda Name
id: parse
run: |
echo "Lambda: ${{ matrix.lambda }}"
RESOURCE=$(echo "${{ matrix.lambda }}" | cut -d'/' -f1)
LAMBDA=$(echo "${{ matrix.lambda }}" | cut -d'/' -f2)
echo "RESOURCE=$RESOURCE" >> $GITHUB_ENV
echo "LAMBDA=$LAMBDA" >> $GITHUB_ENV
- name: Setup Image Metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.LAMBDA_ECR_REPO_URL }}
tags: |
type=raw,value=${{ env.RESOURCE }}.${{ env.LAMBDA }}-${{ env.SHORT_SHA }}
- name: Build ${{ matrix.lambda }} image
uses: docker/build-push-action@v6
with:
push: true
file: ./docker/aws/Dockerfile.release
context: ./aws
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
TARGET_FUNCTION=${{ matrix.lambda }}
NODE_VERSION=${{ env.NODE_VERSION }}
- name: Update Lambda Function
shell: bash
run: |
aws lambda update-function-code \
--function-name ${{ vars.APP_NAME }}-${{ env.LAMBDA }}-lambda-${{ vars.ENVIRONMENT_NAME }} \
--image-uri ${{ env.LAMBDA_ECR_REPO_URL }}:${{ env.RESOURCE }}.${{ env.LAMBDA }}-${{ env.SHORT_SHA }}