はじめに
前回の記事で、コンテナイメージを使用した AWS Lambda 関数の開発環境を構築しました。
ローカル環境でテストレポートおよびカバレッジレポートを出力できるようにしたので、それを AWS CodeBuild で実行し、テスト結果を S3 に格納できるようにしました。
前提
下記の事前準備ができていることを前提とします。
- AWS コンソールにログインできるアカウントを有している
- ローカルの WSL2 Ubuntu 環境から、AWS CLI コマンドを実行できる(アクセスキーを有している)
今回のゴール
- CodeBuild で自動ユニットテストを実行するためのカスタムイメージを作成する
- CodeBuild で Lambda 関数の自動ユニットテストを実行し、テスト結果(テストレポートおよびカバレッジレポート)を S3 に格納する
ディレクトリ構成
今回のディレクトリ構成は下記のようになります。
/home/appuser
├── workspace
│ ├── docker-compose.yaml
│ ├── .vscode
│ │ └── launch.json
│ └── lambda001
│ ├── Dockerfile
+ │ ├── Dockerfile_codebuild
+ │ ├── buildspec_pytest.yml
│ ├── opt
│ │ ├── bootstrap_debug
│ │ ├── lambda-entrypoint_debug.sh
│ │ └── pytest
│ │ ├── run_pytest.sh
│ │ └── reports
│ └── var
│ └── task
│ ├── app.py
│ ├── pytest.ini
│ └── tests
│ └── test_app_001.py
手順
資材作成
-
Dockerfile_codebuild
ファイルを作成
CodeBuild で自動ユニットテストを実行するためのコンテナが必要になります。
カスタムイメージを作るための Dockerfile として、Dockerfile_codebuild
ファイルを下記のように作成します。Dockerfile_codebuild# Python 3.12.1 FROM public.ecr.aws/lambda/python:3.12.2024.03.04.10-x86_64 # ツールをインストール RUN dnf install -y \ unzip # AWS CLI をインストール RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" RUN unzip awscliv2.zip RUN ./aws/install # Python のライブラリをインストール RUN pip3 install pytest==8.1.* RUN pip3 install pytest-cov==4.1.* RUN pip3 install pytest-html==4.1.* RUN pip3 install debugpy==1.8.* # 資材を配置する ###### COPY ./var/task/ /var/task/ RUN mkdir -p /opt/pytest/reports/report_text/ RUN mkdir -p /opt/pytest/reports/report_xml/ RUN mkdir -p /opt/pytest/reports/report_html/ RUN mkdir -p /opt/pytest/reports/coverage_html/ ###### COPY ./opt/pytest/ /opt/pytest/ COPY ./opt/bootstrap_debug /opt COPY ./opt/lambda-entrypoint_debug.sh/ /opt/ # パーミッションを変更する RUN chmod 755 /opt/bootstrap_debug RUN chmod 755 /opt/lambda-entrypoint_debug.sh # 起動時のコマンドを設定する ###### CMD ["app.handler"]
-
buildspec_pytest.yml
ファイルを作成
CodeBuild で自動ユニットテストを実行するための定義として、buildspec_pytest.yml
ファイルを下記のように作成します。buildspec_pytest.ymlversion: 0.2 phases: pre_build: commands: - cp -r ./var/task/. /var/task/ build: commands: # pytest をカバレッジレポートを出力するモードで起動する - cd /var/task/ - python -m pytest -c pytest.ini -s -v --junitxml=/opt/pytest/reports/report_xml/report.xml --html=/opt/pytest/reports/report_html/report.html --cov-report=html:/opt/pytest/reports/coverage_html/ --cov=/var/task/ --cov-branch /var/task/ > /opt/pytest/reports/report_text/report.txt post_build: commands: # テストレポートとカバレッジレポートをS3にアップロードする - datetime=$(date '+%Y%m%d%H%M%S') - aws s3 cp /opt/pytest/reports/report_text/ s3://study-codebuild-202502/pytest_reports/lambda001/$datetime/report_text/ --recursive - aws s3 cp /opt/pytest/reports/report_html/ s3://study-codebuild-202502/pytest_reports/lambda001/$datetime/report_html/ --recursive - aws s3 cp /opt/pytest/reports/coverage_html/ s3://study-codebuild-202502/pytest_reports/lambda001/$datetime/coverage_html/ --recursive reports: report_xml: files: - report_xml/report.xml base-directory: /opt/pytest/reports discard-paths: yes file-format: JunitXml
AWS コンポーネント作成
-
ECR リポジトリを作成
ECR リポジトリlambda_codebuild
を作成します。
(手順は省略します)
-
コンテナイメージを作成して ECR に Push する
自動ユニットテストを実行するためのコンテナイメージを作成して ECR に Push します。
コマンドは、ECR リポジトリの「プッシュコマンドを表示」ボタンを押下してコピーします。-
Docker クライアントを認証
WSL2 Ubuntucd /home/appuser/workspace/lambda001 aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 999999999999.dkr.ecr.ap-northeast-1.amazonaws.com
下記が出力されれば成功です。
WSL2 UbuntuLogin Succeeded
-
Docker イメージをビルド
docker build
コマンドには、-f ./Dockerfile_codebuild
オプションを追加で指定します。WSL2 Ubuntudocker build -t lambda_codebuild . -f ./Dockerfile_codebuild
下記が出力されれば成功です。
WSL2 Ubuntu[+] Building 4.4s (18/18) FINISHED ~~~~~~~~~~ 省略 ~~~~~~~~~~
-
イメージにタグ付け、ECR リポジトリに Push
イメージにタグ付けするコマンドを実行した後、ECR リポジトリに Pushします。WSL2 Ubuntudocker tag lambda_codebuild:latest 999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/lambda_codebuild:latest docker push 999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/lambda_codebuild:latest
下記が出力されれば成功です。
WSL2 UbuntuThe push refers to repository [999999999999.dkr.ecr.ap-northeast-1.amazonaws.com/lambda_codebuild] 598813a81bbf: Pushed ~~~~~~~~~~ 省略 ~~~~~~~~~~ 8a302ef602af: Pushed latest: digest: sha256:5474828fb3e5a60ed72ba03c3c5002d1c1f067b30c4663b4eed69be511363a1d size: 4078
-
-
S3 バケットを作成
下記のように S3 バケットとプレフィックスを作成します。
(手順は省略します)
今回のバケット名はstudy-codebuild-202502
とします。S3s3://study-codebuild-202502/ ├── pytest_reports/ └── lambda/
-
ソースコードを格納
s3://study-codebuild-202502/lambda/
内に、\\wsl$\Ubuntu-22.04\home\appuser\workspace\lambda001
をディレクトリごと格納します。
(手順は省略します)S3s3://study-codebuild-202502/ ├── pytest_reports/ └── lambda/ + └── lambda001 + ├── Dockerfile + ├── Dockerfile_codebuild + ├── buildspec_pytest.yml + ├── opt + │ ├── bootstrap_debug + │ ├── lambda-entrypoint_debug.sh + │ └── pytest + │ ├── run_pytest.sh + │ └── reports + └── var + └── task + ├── app.py + ├── pytest.ini + └── tests + └── test_app_001.py
-
サービスロールにポリシーをアタッチ
サービスロールcodebuild-lambda001_pytest-service-role
に、下記のポリシーをアタッチします。
(手順は省略します)AmazonS3FullAccess
AWSAppRunnerServicePolicyForECRAccess
動作確認
-
ビルド実行
ビルドプロジェクトlambda001_pytest
の「ビルドを開始」ボタンを押下します。
[ビルド履歴]で、ビルドステータスが「成功」になることを確認します。
-
S3 バケットを確認
s3://study-codebuild-202502/pytest_reports/lambda001/{yyyyMMddHHmmss}/
内に、下記3つのプレフィックスが作成され、テスト結果が格納されていることを確認します。
最後に
今回はサンプル実装のため、ビルドプロジェクトのソースに S3 を指定しましたが、実際のプロジェクトでは GitHub を使うことが多いと思います。
また、AWS CodePipeline を利用して AWS CodeDeploy と組み合わせて使うこともあるかと思いますが、基本的な作り方は変わりません。
テストレポートの S3 バケットを HTTP で公開するなど工夫すれば、更に便利にできそうです。