継続は力なり

タイトル通り定期的な更新を心掛けるブログです。

AWS SAM の差分デプロイの課題を踏まえた改修をした

タダです.

モノリポで AWS Lambda のコードを管理し,デプロイをするために差分を検出する GitHub Actions のフローを作ったことを以前の記事で書いたのですが,運用していく中で問題がありました.その問題に開発者と改修を行ったのでその模様をこの記事にまとめます.

sadayoshi-tada.hatenablog.com

運用上の課題概要

プルリクのたび差分が S3 に都度アップロードされるためデプロイ時に手間が発生する

作ったフローではプルリクのたびに差分を検出して日付付きの template.yaml を S3 にアップロードし,そのファイルと同日のファイルがあればデプロイをするようになっていたのですが,後述する課題と関連し,本来デプロイしたくないファイルが S3 にアップロードされることがありました.そのため,都度確認と不要なファイルは削除するオペレーションが発生していて開発者体験的によろしくなかったです.

GitHub の開発の時系列上の差分の発生

頻度としてはかなり低いレベルで発生した問題として複数人による同時期の開発において下記の順でブランチができ,feature/Bfeature/Cを先にマージした後 feature/Aをマージする場合があったとします.

  1. feature/A
  2. feature/B
  3. feature/C

feature/AのHEADfeature/B,feature/Cが取り込まれたマージ先のブランチを比較してfeature/A分の差分,feature/Bfeature/Cの差分を検知します.feature/Atemplate.yaml,feature/Btemplate.yaml,feature/Ctemplate.yamlを元にfeature/A,feature/B,feature/Cのコードがfeature/Aのブランチのコードの状態でデプロイされたことで,デグレが発生することもありました.

改修した GitHub Actions

上記の課題に対して GitHub Actions を開発者と改修しました.AWS SAM のデプロイ処理で変更点のみ抜粋して記載します.

on:
  push:
    branches:
      - master
  pull_request:

jobs:
  sam-tes:
    runs-on: ubuntu-latest
    steps:
      ~中略~
     - name: Package&Deploy
        if: contains(github.event_name, 'push')
        run: |
          CURRENT_DIR=`pwd`
          for FILE in $(git diff HEAD^..HEAD --diff-filter=AM --name-only -- "*app.py") ; do
            cd $(dirname ${FILE}); cd ../
            RES=`\find . -name "*.yaml" -maxdepth 1 2> /dev/null`
            if [ -n "$RES" ]; then
              STACK_NAME=`pwd | awk -F "/" '{ print $NF }'`
              sam package --template-file template.yaml --output-template-file ${STACK_NAME}.yaml --s3-bucket ${{ secrets.AWS_SAM_BUCKET }} --region ${{ secrets.AWS_REGION}}
              sam deploy --template-file ${STACK_NAME}.yaml --stack-name ${STACK_NAME} --s3-bucket ${{ secrets.AWS_SAM_BUCKET }} --region ${{ secrets.AWS_REGION}} --capabilities CAPABILITY_IAM 
              cd $CURRENT_DIR
            elif [ -z "$RES" ]; then
              echo "template.yml nothing"
              cd $CURRENT_DIR
            fi
          done
      ~中略~

これまでは S3 に一時ファイルを置くために sam packagesam deploy が別々になっていたのですが,git diff HEAD^..HEAD --diff-filter=AM --name-only -- "*app.py" のコマンドにしてマージ先のコミットと1つ前の比較した時の差分を検出してデプロイできるようになりました.そのため,1つに処理に統合されました.

まとめ

AWS SAM の差分デプロイの運用上課題を開発者に改修したのでまとめました.運用上の課題があっても一緒に改修できたのは本当にありがたい経験でした.