さて、以前にGitHub Actionsを利用してEC2のデプロイ方法をブログしましたが、今回は独自コンテナイメージを利用してAWS Lambdaにデプロイするように試してみました。
ちなみにLambdaのデプロイはCircleCIでも作っていましたね。
構成
- ディレクトリ構成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ tree lambda lambda └── hoge ├── README.md ├── app.py └── requirements.txt $ tree docker/prd docker/prd └── hoge ├── Dockerfile └── README.md $ tree docker/stg docker/stg └── hoge ├── Dockerfile └── README.md |
- Dockerfile
1 2 3 4 5 6 7 8 9 |
FROM public.ecr.aws/lambda/python:3.9 COPY ./lambda/hoge/app.py ${LAMBDA_TASK_ROOT} COPY ./lambda/hoge/requirements.txt ${LAMBDA_TASK_ROOT} RUN pip install --upgrade pip RUN pip install -r requirements.txt -t . CMD ["app.lambda_handler"] |
- lambda/hogeディレクトリ配下にPythonのソースコードが管理されている前提
- LambdaはAPI Gatewayと連携
- Python imageのdocker build,push、aws-cliでイメージの更新
- Stg環境はworkflow_dispatchで手動デプロイ
- 本番環境はmasterマージでデプロイ
paths
を利用してディレクトリ配下に差分が出た場合に
- 準備
まずはAWSと連携したいため、OIDCの設定をしましょう。クレデンシャルを環境変数として管理するとセキュリティ面が下がりますし、管理が煩雑になりますからね。
GitHub Actions Workflow
- .github/workflows/deploy-stg-lambda.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
name: Deploy-stg-lambda # デプロイ時のデバッグ #on: # pull_request: workflow_dispatch: inputs: name: description: 'Name' required: true env: SLACK_WEBHOOK: ${{ secrets.STG_SLACK_WEBHOOK_URL }} SLACK_USERNAME: stg-deploy SLACK_CHANNEL: deploy SLACK_ICON: https://avatars.githubusercontent.com/u/44036562?s=280&v=4 AWS_ROLE_NAME: githubactions-oidc AWS_ROLE_SESSION_NAME: githubactions-oidc AWS_REGION: ap-northeast-1 permissions: id-token: write contents: read jobs: stg-lambda-deploy: name: Deploy stg-lambda runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@main with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ env.AWS_ROLE_NAME }} role-session-name: ${{ env.AWS_ROLE_SESSION_NAME }} aws-region: ${{ env.AWS_REGION }} - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Build, tag, and push image to Amazon ECR id: build-image run: | docker build -f docker/stg/hoge/Dockerfile -t ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-1.amazonaws.com/stg-hoge:latest . docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-1.amazonaws.com/stg-hoge:latest aws lambda update-function-code --function-name stg-hoge --image-uri ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-1.amazonaws.com/stg-hoge:latest - name: Slack Success if: ${{ success() }} uses: rtCamp/action-slack-notify@v2 env: SLACK_TITLE: Stg deploy Success SLACK_COLOR: good - name: Slack Failure if: ${{ failure() }} uses: rtCamp/action-slack-notify@v2 env: SLACK_TITLE: Stg deploy Failure SLACK_COLOR: danger # sshデバッグのためコメントアウト # - name: Setup tmate session # uses: mxschmitt/action-tmate@v3 |
https://github.com/aws-actions/configure-aws-credentials
Stg環境ではほとんどEC2のデプロイ方法と変わりなく、 workflow_dispatch
で手動デプロイをしています。32行目でOIDCになったことで aws-actions/configure-aws-credentials
を利用して事前に作成したロールを指定しています。あとはbuild、push、aws-cliでLambdaのコンテナイメージを切り替えるだけです。push時にECRのIMAGE_TAGもshaで変数にできますが、latestで問題ないでしょう。
- .github/workflows/deploy-prd-lambda.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
name: Deploy-prd-lambda # デプロイ時のデバッグ #on: # pull_request: on: push: branches: [master] paths: - "lambda/hoge/**" env: SLACK_WEBHOOK: ${{ secrets.PRD_SLACK_WEBHOOK_URL }} SLACK_USERNAME: prd-deploy SLACK_CHANNEL: deploy SLACK_ICON: https://avatars.githubusercontent.com/u/44036562?s=280&v=4 AWS_ROLE_NAME: githubactions-oidc AWS_ROLE_SESSION_NAME: githubactions-oidc AWS_REGION: ap-northeast-1 permissions: id-token: write contents: read jobs: prd-lambda-deploy: name: Deploy prd-lambda runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@main with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ env.AWS_ROLE_NAME }} role-session-name: ${{ env.AWS_ROLE_SESSION_NAME }} aws-region: ${{ env.AWS_REGION }} - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Build, tag, and push image to Amazon ECR id: build-image run: | docker build -f docker/prd/hoge/Dockerfile -t ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-1.amazonaws.com/hoge:latest . docker push ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-1.amazonaws.com/hoge:latest aws lambda update-function-code --function-name hoge --image-uri ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-1.amazonaws.com/hoge:latest - name: Slack Success if: ${{ success() }} uses: rtCamp/action-slack-notify@v2 env: SLACK_TITLE: Prd deploy Success SLACK_COLOR: good - name: Slack Failure if: ${{ failure() }} uses: rtCamp/action-slack-notify@v2 env: SLACK_TITLE: Prd deploy Failure SLACK_COLOR: danger # sshデバッグのためコメントアウト # - name: Setup tmate session # uses: mxschmitt/action-tmate@v3 |
本番環境では毎回masterマージでデプロイされないように、7行目の paths:
を指定するだけで簡単に差分検知でマージ時にデプロイすることができるため、デバッグ等の工数がかかりませんでした。CircleCIでは path-filtering
を利用していましたが、実装の手間が色々とかかっていましたね。
[CircleCI][Orbs][path-filtering]特定ディレクトリに差分が出たらterraform applyを適用するように実装してみた
- 動作確認
stg
本番
まとめ
差分検知はCircleCIよりGitHub Actionsの方が便利で感動した…!次はTerraformのCI/CD環境も作ってみたいと思います。
0件のコメント