はじめに
本記事はPERSOL PROCESS & TECHNOLOGY Advent Calendar 2023の記事です。
前記事(公式LINEアカウントへのログイン処理をAWS Lambda経由で実装してみた)を実装する開発環境にて、自動でLambda関数を更新するCI/CD環境を作成してみました。開発フェーズを素早く実施するための環境整備のお話になります。とっても簡単便利なのでぜひ。
構成図
各AWSサービスの役割は以下になります。
・Amazon ECR
→DockerImageレポジトリ
・AWS Lambda
→今回のデプロイ先
・CodeCommit
→コードGitリポジトリ
・CodeBuild
→ビルド・lambda更新コマンド実行
・CodePipeline
→CI/CDのパイプライン
実装
ローカル環境
Dockerにてイメージ作成できる環境、およびCodeBuildで実行するbuildコマンドを記述したbuildspecファイルを作成します。
ファイル構成例は以下です。今回の実装で利用しないファイルは削除しているため、とても単純な設計となっています。
docker フォルダ
∟Dockerfile … Dockerのコンテナイメージを作成するコマンドファイル
∟requirements.txt … 必要なライブラリを記載、Dockerfileの参照先
domain フォルダ
∟app.py … Lambda関数コードを記載するファイル
buildspec.yml … CodeBuildで実行するbuildコマンドファイル
始めにDockerfileです。ここでのポイントはベースイメージの選択です。
今回はLambda関数実行環境であること、そしてLambda関数はPythonで記述すること、そしてECRからイメージを取得して作成されるということから、AWSベースイメージを使用しています。
# ベースイメージの指定
FROM public.ecr.aws/lambda/python:3.11
# requirements.txtをコピーして依存関係をインストール
COPY ./docker/requirements.txt ./
RUN pip install --upgrade pip && \
pip install -r requirements.txt && \
rm requirements.txt
# アプリケーションのコードをコピー
COPY ./domain/ ./domain/
# ポートの公開
EXPOSE 80
CMD ["domain.app.lambda_handler"]
次にYMLファイルを作成します。これはこの後作成されるCodeBuildで実行されるコマンドを記述しているものとなります。
"$"から始まる変数は環境変数値です。(詳細は実際に環境変数値を設定する箇所で説明)
envはイメージ作成時のタグ名とバージョン管理用の変数になります。こちらはご自身が管理しやすいよう変更してください。
各フェーズの説明です。
1.pre_build
→AWSCLIを利用してECRへ認証を行います。
2.build
→DockerFileを元にイメージを作成します。作成したイメージへタグつけを行います。
3.post_build
→ECRへイメージをプッシュします。プッシュしたイメージを元にLambda関数を更新します。
version: 0.2
env:
variables:
tag_name: codebuild
version: 1.0.0
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region $region | docker login --username AWS --password-stdin $account
build:
commands:
- echo Building the Docker image...
- docker build -t $tag_name:$version -f ./docker/Dockerfile .
- docker tag $tag_name:$version $account/$ecr_repo:$version
post_build:
commands:
- echo Pushing the Docker image...
- docker push $account/$ecr_repo:$version
- aws lambda update-function-code --function-name $lambda_func --image-uri $account/$ecr_repo:$version
Amazon ECR
今回ECRへのプッシュはCodeBuildより実行するのでデフォルトは空でも大丈夫です。
AWS Lambda
今回はコンテナイメージより関数の作成をします。
"すでにコンテナイメージから作成されたLambda関数を更新する"CI/CDのため、中身はなんでも大丈夫です。
【注意!】ここでのアーキテクチャはCodeBuildの実行環境と同じにします。
(本CI/CDを利用して開発したLambda関数詳細はこちら→公式LINEアカウントへのログイン処理をAWS Lambda経由で実装してみた)
CodeCommit
作成したレポジトリのクローンをローカル環境へ作成します。今回はHTTPでの接続を表示します。
ステップ2:Git認証 では、作業しているIAMユーザーに対してGit認証を作成する必要があります。IAMより該当ユーザー内からセキュリティ認証情報を選択、AWS CodeCommitのHTTPS Git認証情報より認証情報を生成してください。ステップ3:リポジトリのクローンを作成するにおいて、ローカル環境からクローンを作成する際に入力が必要となる情報です。
CodePipeline と CodeBuild
早速作成してきた上記AWSサービスをパイプラインで繋げていきます。
CodeBuildはCodePipeline内で新規作成します。
Step1 パイプライン設定を行う。
パイプラインタイプは機能や課金形態が異なるため、実際の環境に合わせて選択ください。
Step2 ソースコードを選択する。
ソースプロバイダーにCodeCommitを選択し、先ほど作成したCodeCommitのレポジトリを選択します。
またレポジトリのブランチまで選択できるので、開発用と本番用で分けることが可能です。
Step3 CodeBuildの作成、設定を行う。
プロバイダーでCodeBuildを選択し、プロジェクトの作成を行います。
別タブで以下のように新規でCodeBuildを作成していきます。
【注意!】ビルド実行環境について、イメージは先ほど作成したLambda関数のアーキテクチャと同じにします。
また今回のビルドコマンドでDockerを利用するため特権付与にチェック✅を忘れずに!
設定完了したら、CodePipelineへ戻り、次へ進みます。
Step4 デプロイステージは今回スキップします。
"導入段階をスキップ"で次へ進みます。
最後のページで設定内容を確認し、パイプラインの完成です。
完成するとすぐに初めのパイプラインが実行されます。ビルドで失敗してしまうので、次のステップで修正します。
CodeBuild
先ほどCodePipeline内で作成したCodeBuildの設定を少し変更します。
CodePipelineから、またはCodeBuildの一覧からプロジェクト詳細を確認します。
該当プロジェクトを選択し、ビルドの詳細を表示します。
ここで変更する点は環境変数値とIAMロールです。
環境変数値は以下となります。ご自身の作成環境値に合わせ設定ください。
環境変数 | 説明 | 例 |
---|---|---|
region | 環境を作成したリージョン | ap-northeast-1 |
account | 自身のECRURI | 60000000.dkr.ecr.ap-northeast-1.amazonaws.com |
ecr_repo | 作成したECR名 | test_ecr |
lambda_func | 作成したLambda関数名 | test_lambda |
2.IAM
同じく環境にある、サービスロールを押下し、CodeBuildに紐付くIAMロールを修正します。
このIAMロールはCodeBuild作成時に新規作成しましたが、LambdaとECRへのアクセス権限が足らないので追加します。
今回はAWSより提供されているポリシーをアタッチしています。(IAMは必要に応じ最小限の権限へ変更をお願いします。)
これで問題なく動くはず。再度CodePipelineへ戻り、ステージの再試行を実施。
このようにオールグリーンになれば完成です。
まとめ
今回はAWS CodePipelineを用いてGit更新をトリガーに、Lambda関数へ自動デプロイ更新されるCI/CD環境を実装しました。ここまで自動でできていると、ローカル環境でGitPushするだけで数分後には自動で更新が反映されているのです。めちゃ便利〜。開発前に自動環境が揃っていると以降の作業負担が減るので、最初は大変でも環境整備しておいてよかったなと思います。
今後はpytestを利用したテストコードの実行まで自化できればいいな。。と実装検討中です。引き続き便利なCI/CD環境目指して精進します。