タダです.
モノリポで AWS Lambda のコードを管理し,デプロイをするために差分を検出する GitHub Actions のフローを作ったことを以前の記事で書いたのですが,運用していく中で問題がありました.その問題に開発者と改修を行ったのでその模様をこの記事にまとめます.
運用上の課題概要
プルリクのたび差分が S3 に都度アップロードされるためデプロイ時に手間が発生する
作ったフローではプルリクのたびに差分を検出して日付付きの template.yaml
を S3 にアップロードし,そのファイルと同日のファイルがあればデプロイをするようになっていたのですが,後述する課題と関連し,本来デプロイしたくないファイルが S3 にアップロードされることがありました.そのため,都度確認と不要なファイルは削除するオペレーションが発生していて開発者体験的によろしくなかったです.
GitHub の開発の時系列上の差分の発生
頻度としてはかなり低いレベルで発生した問題として複数人による同時期の開発において下記の順でブランチができ,feature/B
とfeature/C
を先にマージした後 feature/A
をマージする場合があったとします.
feature/A
feature/B
feature/C
feature/AのHEAD
とfeature/B
,feature/C
が取り込まれたマージ先のブランチを比較してfeature/A
分の差分,feature/B
とfeature/C
の差分を検知します.feature/A
のtemplate.yaml
,feature/B
のtemplate.yaml
,feature/C
のtemplate.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 package
と sam deploy
が別々になっていたのですが,git diff HEAD^..HEAD --diff-filter=AM --name-only -- "*app.py"
のコマンドにしてマージ先のコミットと1つ前の比較した時の差分を検出してデプロイできるようになりました.そのため,1つに処理に統合されました.
まとめ
AWS SAM の差分デプロイの運用上課題を開発者に改修したのでまとめました.運用上の課題があっても一緒に改修できたのは本当にありがたい経験でした.