LambdaのCI/CDパイプラインを構築してみた
この記事はポート株式会社 サービス開発部 Advent Calendar 2024の20日目の記事です。
はじめに
SRE1年目のharaです。
今回初めてLambdaのCI/CDパイプラインを構築したので紹介します。同じように作成したことがない方の参考になれば幸いです!
背景
前回の記事で社内で初めてSQSを導入した話を書いたのですが、SQSのコンシューマーはLambdaを採用しました。Lambda関数の作成は自分以外のエンジニアが担当だったので少しでも開発が楽になるようにLambdaのCI/CDパイプラインを構築しました。
CI/CDパイプラインの構築
今回のワークフローは下記図の流れになっています。
上記ワークフローは下記ファイルで実現したのでそれぞれ説明します。
- cicd_pipeline.yaml
- build.yaml
- deploy.yaml
cicd_pipeline.yaml
name: Prod Lambda CI/CD Pipeline
run-name: ${{ github.workflow }} / triggered by @${{ github.actor }}
permissions: {}
on:
workflow_dispatch:
push:
branches:
- main
paths:
- ./production/lambda/**
jobs:
build:
permissions:
id-token: write # aws-configure-credentials
contents: read # checkout
uses: ./.github/workflows/prod-lambda-image-build.yml
deploy:
needs: build
permissions:
id-token: write # aws-configure-credentials
contents: read # checkout
uses: ./.github/workflows/prod-lambda-deploy.yml
工夫したポイントは下記になります。
-
mainブランチにマージした際に自動でデプロイするようにした
Github Actionsはイベントの発火条件を指定できるのでbranches・pathsフィルターを使用して実現しました。
https://docs.github.com/ja/actions/writing-workflows/workflow-syntax-for-github-actions#onpushbranchestagsbranches-ignoretags-ignore -
workflow_dispatchを使用して手動でもデプロイできるようにする
workflow_dispatchは手動でワークフローを実行できるイベントです。
https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_dispatch
今回は手動でのデプロイもできるようにしたかったためworkflow_dispatchを追加しました。 -
build・deploy用のワークフローを作成してCI/CDのワークフローから呼び出す
workflow_callを利用することで他のワークフローから呼び出せるようになります。
https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_call
今回は設定していませんがbuild or deployだけを実行したいときは各ワークフローにworkflow_dispatchを追加することで実現することもできるのでworkflow_callの利用はおすすめです。
build.yaml
name: Prod Docker Build and Push(Lambda Image)
permissions: {}
on:
workflow_call:
jobs:
build:
runs-on: linux-arm64
permissions:
id-token: write # aws-configure-credentials
contents: read # checkout
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: ${{ vars.AWS_SAMPLE_ROLE_TO_ASSUME_PROD }}
aws-region: ap-northeast-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@b430a9ae4b069c6327bd09bbcf041b67644ea84f # v.2.0.1
- name: Docker meta
id: meta
uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
with:
images: ${{ steps.login-ecr.outputs.registry }}/sample/lambda
tags: |
type=raw,value=${{ github.sha }}
- name: Build and push images
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
with:
context: ./production/lambda
tags: ${{ steps.meta.outputs.tags }}
platforms: linux/arm64
provenance: false
push: true
工夫したポイントは下記になります。
-
arm64のrunnerを利用
2024/06/07からGithub ActionsでArm64を利用することができる様になりました。
https://github.blog/jp/2024-06-07-arm64-on-github-actions-powering-faster-more-efficient-build-systems/
arm64はx86_64と比べると安価なのでGithub Actionsでrunnerを選択する場合は積極的にarm64を利用するのが良さそうです。 -
AWSの認証はOIDCを利用しています
aws-actions/configure-aws-credentials アクションのrole-to-assumeにOIDC用IAM Roleを渡せば静的なクレデンシャルを渡すことなく認証が可能になります。
また、OIDC用IAM Roleの作成方法は下記を参考に実施しました。
https://docs.github.com/ja/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
deploy.yaml
name: Prod Lambda Deploy
permissions: {}
on:
workflow_call:
env:
IMAGE_TAG: ${{ github.sha }}
AWS_REGION: ap-northeast-1
AWS_ACCOUNT_ID: xxxxxx
jobs:
deploy:
runs-on: linux-arm64
permissions:
id-token: write # aws-configure-credentials
contents: read # checkout
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: ${{ vars.AWS_SAMPLE_ROLE_TO_ASSUME_PROD }}
aws-region: ${{ env.AWS_REGION }}
- name: Lambda Deploy
run: >
aws lambda update-function-code
--function-name sample-lambda
--region ${{ env.AWS_REGION }}
--image-uri "${{ env.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/sample/lambda:$IMAGE_TAG"
--architectures arm64
--output json
工夫したポイントは下記になります。
-
Docker Imageにはhash commitを追加する
Imageにhash commitを付与することでLambdaを特定のバージョンに戻すことが容易になります。
また、今回Lambda Deployの箇所はaws cliを利用していますがlambrollというLambdaのデプロイツールがあるようです。こちらを使用するともっとスマートに書けるかもしれません。次回Lambdaのデプロイ処理を実装するときは使用したいです。
まとめ
今回LambdaのCI/CDパイプラインを構築してみて下記が勉強になりました。
- Build時に使用している各アクションの使用方法(今までは手元でBuildしてECRにpushすることしかしたことありませんでした、、)
- BuildからDeployまでのフローの作成方法
- OIDCを使用した認証方法
今回はLambdaのCI/CDパイプラインの構築でしたが次回はECSでバイプラインの構築をしてみたいです!
Discussion