概要
- GithubActionsと ECRのイメージをもとにLambdaをデプロイするCICDを構築したため、記録として残しておく。
- 本記事を通して、下記が実現できるように記載していく
- ローカルでコード編集
- Commitして、GithubへPush
- GithubActionsが実行
- 編集後のコードをLambdaに自動デプロイする
- 最終的な構成として、キャプチャのよう流れとなる
前提
- Githubの操作(CommitやPushなど)経験があること
- AWSのアカウントがあること
- この記事内ではオレゴンリージョンを使用しているため、リージョンコードが
us-west-2
で進めています。なので、東京リージョンなどを使用する際は適宜書き換えてください
- この記事内ではオレゴンリージョンを使用しているため、リージョンコードが
- CICDの「CI」の部分は本記事には記載しません
ECRでプライベートリポジトリを作る
アップロードするためのLambda関数を作る&Build
関数作成
- AWS公式リファレンスを参照する
- 最終的なディレクトリ構成
├── .github │ └── workflows │ └── cicd.yml ├── Dockerfile ├── README.md ├── app │ ├── __init__.py │ └── main.py └── requirements.txt
- app/main.pyを作る
# 公式URL:https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/python-image.html import sys def handler(event, context): return "Hello from AWS Lambda using Python" + sys.version + "!"
- Dockerfileを作る
FROM public.ecr.aws/lambda/python:3.12 # Copy requirements.txt COPY requirements.txt ${LAMBDA_TASK_ROOT} # Install the specified packages RUN pip install -r requirements.txt # Copy function code COPY ./app/main.py ${LAMBDA_TASK_ROOT} # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "main.handler" ]
- requirements.txtを作る
boto3
Dockerを起動して、ローカルで動作検証
# ImageをBuild
docker build --platform linux/amd64 -t docker-image:test .
# コンテナを起動
docker run --platform linux/amd64 -p 9000:8080 docker-image:test
# curlでリクエストする
curl -i "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
- うまくいけば、下記のようなレスポンスが返る
HTTP/1.1 200 OK
Date: Wed, 29 May 2024 15:27:12 GMT
Content-Length: 114
Content-Type: text/plain; charset=utf-8
"Hello from AWS Lambda using Python3.12.3 (main, Apr 29 2024, 08:31:45) [GCC 11.4.1 20230605 (Red Hat 11.4.1-2)]!"%
DockerをECRにPushする
Terraformの利用経験がある方向け
この後記述されているLambdaとGithubActionsとの連携用のロールをTerraformで作りたい方は、リポジトリの方に手順あるので、参考にしてください。(init、applyのみで作れます)
https://github.com/Kyohei-takiyama/sample-upload-lambda-deploy-gha?tab=readme-ov-file#terraform
Lambdaを作る
GithubActionsを作る
- 参考
GithubActionsからAWSに対して、アクセストークンを取得するためのIAMロールを作成する
-
アクセストークンを取得するために、AWS側にIAMロールの作成を行うのですが、この方の記事が非常にわかりやすいので、参考に作成していただければと思います。
-
サービスから「Lambda」を選択して下記の許可を追加
- GetFunctionConfiguration
- UpdateFunctionCode
IAMロールのARNをGithubのシークレットに保存する
-
GHAをかく
-
流れとしては下記となる
yml .github/workflows/cicd.yml
name: Deploy to AWS
# トリガーのタイミングは適宜変更
on:
push:
branches:
- main
paths:
- ".github/workflows/**"
- "app/**"
env:
AWS_REGION: us-west-2
ECR_REPOSITORY: sample-lambda
FUNCTION_NAME: sample-lambda-function
# ワークフロー内で、Idトークンを使用するために権限を付与
# https://docs.github.com/ja/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services#adding-permissions-settings
permissions:
id-token: write
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout@v4
- name: set aws role to assume
run: echo "AWS_ROLE_ARN=${{ secrets.AWS_ROLE_TO_ASSUME }}" >> $GITHUB_ENV
# 「aws-actions/configure-aws-credentials」で、
# GitHub OIDC プロバイダーから JWT を受け取り、アクセス トークンを AWS に要求
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ env.AWS_ROLE_ARN }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: linux/arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push image
uses: docker/build-push-action@v5
id: build-image
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: false
platforms: linux/arm64
- name: Deploy to Lambda
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
run: |
aws lambda update-function-code --function-name ${{ env.FUNCTION_NAME }} --image-uri $ECR_REGISTRY/${{ env.ECR_REPOSITORY }}:${{ github.sha }}
# wait処理を入れる
# https://docs.aws.amazon.com/cli/latest/reference/lambda/wait/#cli-aws-lambda-wait
aws lambda wait function-updated --function-name ${{ env.FUNCTION_NAME }}
Lambdaコードを修正してデプロイする
python app/main.py
# https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/python-image.html
import sys
def handler(event, context):
return "MainへのPushを通じでデプロイされるように変更" + sys.version + "!"
-
以上の結果から、「ローカルでコード編集=>Commitして、GithubへPush=>GithubActionsが実行=>編集後のコードがLambdaにデプロイ」までの一連のCDフローを構築することができたと思われる(CIのテストの部分は省略)
まとめ
- 一見難しそうなことは、最初の一歩を踏み出すのが大変だが、実は踏み込んでみると今までわからなかったことが一気にわかるようになったりするため楽しい。
- 意外とやることが多く、また色々な用語やリソースが出てくるため最初は全く理解できなかったが、自分でいろいろ調べながら簡単な構成を作ることで理解が深まった。(今後はもっと応用できそうという自信も持てた)
- また、色々な人が記事を残してくれているおかげで、用語や認証周りの流れなどは理解がしやすかった(一人では無理でした)
- 私も誰かのためになればと思い、記事を残そうと改めて思った。本記事が誰かの一助になれば幸いです。
- 作成したコード
https://github.com/Kyohei-takiyama/sample-upload-lambda-deploy-gha/tree/main