LoginSignup
1
2

More than 1 year has passed since last update.

AWS sam pipelineを使うとLambdaをデプロイするCI/CDパイプラインをどうやって作ればいいか分かりそうになる

Last updated at Posted at 2023-02-01

背景

Lambdaをgit管理して単体テストに通ったらデプロイってどうやるんだろうみたいなことができる。

概要

AWS SAMにはsam pipelineというコマンドがあり、これを使うことでパイプラインを自動で作ってくれる。
出来上がるステージとしては
CodeCommit
-> CloudFormation (パイプライン自体の設定デプロイっぽい)
-> CodeBuild テスト (オプション)
-> CodeBuild デプロイ(sam deploy)

sam pipelineではmainブランチに対してはデプロイ環境が二つできてしまう(上記のsam deployを行うステージが2回ある)が、作るべきパイプラインの参考にはなる。
featureブランチに対しては上記のようにsam deployは1回のみ

手順参考

公式でしっかり説明してくれているのが以下くらいしか見当たらないが、これを参考にすればなんとかできる。
コンテナ Lambda の CI/CD パイプラインを SAM Pipeline で作ろう !

やってみる

環境

Cloud9
sam --version 1.71.0

パイプラインを使わずLambdaの単体テストをできるようにするまで

sam initでHelloWorld関数のみを作成。python選択。
pytestというライブラリでテストができそうなディレクトリができるので、これを使ってテストする。
なお、pytestはtest_から始まるファイルを実行してしまうようで、今回はAPI Gatewayは使わないのでtests/integration/test_apigw.pyは消しておく。

pip install -r tests/requirements.txt
pytest tests # 後のCodeBuild上では失敗したためpython -m pytest testsにしたほうがいいかも

testsディレクトリ内にある初期のテストコードが実行される。
とりあえずここでsam deploy --guidedをしておくとデプロイできる。

sam pipeline 初期状態(単体テストなしでデプロイのみ)

sam pipeline bootstrapを2回実行。
参考手順の通り、名前はdev, prodにする。質問はほとんどデフォルトで答えるとIAMロールも自動で作ってくれるので任せる。作成されたリソースは記事末の参考記事で説明がある。

2回実行するのは、そういうテンプレートしか今のところなさそうだから。。。

2回bootstrapしたらsam pipeline init実行し、参考手順の記事を見ながら質問に答えていく。

ここで以下のコマンドでいよいよsam deploycodepipeline.yamlはCodePipelineなどを定義したテンプレート。

sam deploy --guided \
 --template codepipeline.yaml \
 --stack-name php-lambda-app-pipeline-stack \
 --capabilities=CAPABILITY_IAM \
 --parameter-overrides="FeatureGitBranch=feature"

パイプライン自体のデプロイは完了する。完了後、featureブランチへのgit pushでLambdaをデプロイするためのパイプラインが開始される。
しかし以下のエラーでCodeBuildのデプロイステージが失敗していた。

Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: sam deploy --stack-name $(echo ${FEATURE_BRANCH_NAME} | tr -cd '[a-zA-Z0-9-]') --capabilities CAPABILITY_IAM --region ${TESTING_REGION} --s3-bucket ${TESTING_ARTIFACT_BUCKET} --no-fail-on-empty-changeset --role-arn ${TESTING_CLOUDFORMATION_EXECUTION_ROLE}. Reason: exit status 1

Deploy this changeset? [y/N]: の直後にエラーになっていることから、この質問にyesが押せていないだけに見える。

上記はbuildspec_feature.ymlで記述されて実行されているコマンドだが、ここのsam deployコマンドに-no-confirm-changesetオプションを足してgit pushしたらビルドできた。

これで単体テストなしで、git pushによりLambda関数がデプロイできるパイプラインができた。

なお、mainブランチにpushすると多分2つのステージでデプロイされる。codepipeline.yamlを見ると、先ほどのFeatureGitBranchパラメータの値によって余分にリソースを作成しそうな箇所があった。

パイプラインに単体テストを追加する

codepipeline.yamlをCodeBuildProjectUnitTestで文字列検索して、uncommentしろと書いてある箇所を全てコメントアウトする(3ヶ所)。
Uncomment and modify the following step for running the unit-tests

追加で作成されたCodeBuildのステージではbuildspec_unit_test.ymlをbuildspecとして使うので、このファイルにpytestインストールとpytest実行を追加する。

  install:
    runtime-versions:
      python: 3.8
    commands:
      - pip install -r tests/requirements.txt
  build:
    commands:
      # trigger the unit tests here
      - echo 'Running unit tests'
      - python -m pytest tests

なお、python -m pytest testsじゃなくてローカルと同じようにpytest testsとすると以下のエラーになった

_________________ ERROR collecting tests/unit/test_handler.py __________________
ImportError while importing test module '/codebuild/output/src000000000/src/tests/unit/test_handler.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/root/.pyenv/versions/3.8.13/lib/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/unit/test_handler.py:5: in <module>
    from hello_world import app
E   ModuleNotFoundError: No module named 'hello_world'

この記事のおかげで直った。

作成されたスタックを確認してみる

参考手順通りの命名になってしまっている。
Lambda自体のデプロイに使用されるfeatureスタック(Lambdaが作成される)の他は以下の3つ。

php-lambda-app-pipeline-stack

ここで作成されたartifactのS3バケットにはcodepipeline.yamlやassume-role.sh, hello_worldディレクトリなど必要な資材が一式入っているようだ。これはCodePipelineのUpdatePipelineステージでCloudFormation deployにより指定されていたので、パイプライン自体の設定変更があればこのスタックに反映されそう

aws-sam-cli-managed-dev-pipeline-resources

ここで作成されたartifactのS3バケットにはdev環境のlambdaのsam template, さらにその中で参照されているCodeUri(ただしこちらのコードはなぜか中身は壊れていて見えない

aws-sam-cli-managed-prod-pipeline-resources

ここで作成されたartifactのS3バケットはまだ空。prod環境へのデプロイを行なっていないからだと思われる

参考

SAM Pipelineで作成されるリソースを眺めてみる
AWS SAM Pipelineを試す

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2