TOP>コラム一覧>Lambda の CI/CD を実装してみた

Lambda の CI/CD を実装してみた

はじめに

こんにちは、佐藤です。
皆さん、Lambda 関数の CI/CD って実装したことありますか?ECS や EKS などのコンテナ環境の CI/CD はよく実装すると思いますが、Lambda の CI/CD と言われると意外に実装したことが無いのではないでしょうか。

実績が少ない一方、サーバレスな構成が普及しており、開発案件では必ずといってもいいほど Lambda の CI/CD についてアプリ開発担当から質問を受けます。

そんな経緯から Lambda の CI/CD を実装してみたので皆さんに共有します。最近はAWS Serverless Application Model (AWS SAM)を使用してCI/CDパイプラインを作成するパターンも多いですが、今回はCodeBuild内でAWS CLIを使って実装しました。

CI/CDとは…

CI/CD (継続的インテグレーション/継続的デリバリー) とは、アプリケーション開発のステージに自動化を取り入れて、アプリケーションを提供する頻度を高める手法のこと

構成

今回実装したサンプル構成は以下の通りです。

各リソース名と役割は以下の通りです。

  • API Gateway
    ユーザからの API コールを受け、バックエンドに中継してレスポンスを返す
  • Lambda
    API Gateway からのコールを受け、GET リクエストに対してHello Worldを返す
  • WAF
    特定のIP アドレスからの通信のみを許可する
  • CodeCommit
    Lambda の CI/CD 用資材の格納先
    • buildspec.yml:CodeBuild 内で行う処理内容を記述したファイル
    • lambda_function.py:デプロイするコード
  • CodeBuild
    buildspec.yml に基づきビルド処理(+デプロイ処理)を行う。具体的な処理内容は後述する
  • CodePipeline
    CodeCommit 上のレポジトリが更新されたことをトリガーにビルド処理を行うパイプライン
  • S3
    アーティファクト用バケット

アーティファクトとは…

アーティファクトとは、パイプラインアクションによって処理されるアプリケーションのソースコード、構築されたアプリケーション、依存関係、定義ファイル、テンプレートなどのデータの集合を指す

実装方法

実装の流れは以下の通りです。詳細な手順はちょっと長くなるので割愛します。

  1. 1. Lambda関数 を作成する
  2. 2. API Gateway を作成する
  3. 3. WAF で WebACL を作成する
  4. 4. CodeCommit でレポジトリを作成する
  5. 5. CodeBuild でビルドプロジェクトを作成する
  6. 6. CodePipeline でパイプラインを作成する
  7. 7. buildspec.yml を作成する
  8. 8. デプロイするコードを作成する
  9. 9. レポジトリに Push する

1. Lambda関数 を作成する

詳細な手順は割愛します。下記 URL を参考に Lambda 関数を作成してください。

コンソールで Lambda 関数の作成

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/getting-started-create-function.html

関数の作成が完了したら、以下 2 つの機能を有効化します。

  • エイリアス
  • バージョニング

エイリアス/バージョニングの設定方法

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-aliases.html
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-versions.html

エイリアスを設定すると、エイリアスの ARN が作成されます。API Gateway の設定を行う際にエイリアスの ARN を指定することにより、Lambda のバージョンが変わっても一意の ARN を継続して使用可能になります。

2. API Gateway を作成する

詳細な手順は割愛します。下記 URL を参考に Lambda 関数をバックエンドとして API Gateway を作成して下さい。Lambda を指定する際はエイリアスの ARNを指定してください。

Amazon API Gateway で AWS Lambda を使用する

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-apigateway.html

3. WAF で WebACL を作成する

詳細な手順は割愛します。下記 URL を参考に WebACL を作成して API Gateway にアタッチしてください。

Getting started with AWS WAF

https://docs.aws.amazon.com/waf/latest/developerguide/getting-started.html

AWS WAF を使用して API を保護する

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html

4. CodeCommit でレポジトリを作成する

詳細な手順は割愛します。下記 URL を参考にレポジトリを作成してください。

AWS CodeCommit リポジトリを作成する

https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/how-to-create-repository.html

5. CodeBuild でビルドプロジェクトを作成する

詳細な手順は割愛します。下記 URL を参考にビルドプロジェクトを作成してください。

ビルドプロジェクトの作成 (コンソール)

https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/create-project-console.html

6. CodePipeline でパイプラインを作成する

詳細な手順は割愛します。下記 URL を参考にパイプラインを作成してください。

CodePipeline でパイプラインを作成します。

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/pipelines-create.html

今回作成したパイプラインは以下の通りです。

ビルドステージで実施している処理は次章で説明するbuildspec.ymlで記載します。

7. buildspec.yml を作成する

6章で説明したビルドステージで実行する処理をbuildspec.ymlに記載します

  version: 0.2

  phases:
    install:
      commands: //AWS CLIをインストール
        - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
        - unzip awscliv2.zip
        - ls -l /root/.pyenv/shims/aws
        - ./aws/install --bin-dir /root/.pyenv/shims --install-dir /usr/local/aws-cli --update
    pre_build:
      commands:
        - echo No Pre Build phase
    build: //更新前のバージョンを取得した上で、関数の更新を実行
      commands:
        - echo Build started on `date`
        - CurrentVersion=$(echo $(aws lambda get-alias --function-name poc-lambda-cicd-lambda-01 --name prod | grep FunctionVersion | tail -1 |tr -cd 0-9))
        - zip -r lambda.zip ./lambda_function.py
        - aws lambda update-function-code --function-name poc-lambda-cicd-lambda-01 --zip-file fileb://lambda.zip
        - sleep 10
    post_build: //新バージョンを発行し、エイリアスに紐づいているバージョンを新バージョンに変更
      commands:
        - echo Build completed on `date`
        - ls
        - aws lambda publish-version --function-name poc-lambda-cicd-lambda-01 --description "update version"
        - TargetVersion=$(echo $(aws lambda list-versions-by-function --function-name poc-lambda-cicd-lambda-01 | grep Version | tail -1 | tr -cd 0-9))
        - echo $CurrentVersion
        - echo $TargetVersion
        - aws lambda update-alias --function-name poc-lambda-cicd-lambda-01 --name prod --function-version $TargetVersion
        - aws lambda delete-function --function-name poc-lambda-cicd-lambda-01 --qualifier $CurrentVersion


CodeBuild のビルド仕様に関するリファレンス

https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html

lambda — AWS CLI 1.22.73 Command Reference

https://docs.aws.amazon.com/cli/latest/reference/lambda/index.html

8. デプロイするコードを作成する

デプロイするコードを作成し、lambda_funcation.pyとして保存します。本書ではPythonを使用して作成しています。

    def lambda_handler(event, context):
    return {
      "isBase64Encoded": False,
      "statusCode": 200,
      "headers": {},
      "body": '{"message": "Hello World!!"}',
    }

9. レポジトリに Push する

CodeCommit 上のレポジトリに push します。push するファイルは以下の 2 つです。

  .
  ├── buildspec.yml
  └── lambda_function.py

1. レポジトリをローカルにクローンします。

 $ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/{repo_name}

2. buildspec.ymllambda_function.pyをローカルレポジトリにコピーします。

  $ cp buildspec.yml local_repo_path
  $ cp lambda_function.py local_repo_path
  $ cd local_repo_path

3. 以下のコマンドを実行して変更内容をインデックスに追加します。

  $ git add -A

4. 以下のコマンドを実行して変更内容をコミットします。

  $ git commit -m "comment"

  出力例
  [master 3488038] 2022/03/15 14:27 Lambda修正
  1 file changed, 1 insertion(+), 1 deletion(-)

5. 以下のコマンドを実行して CodeCommit 上のレポジトリに push します。

  $ git push origin master

  出力例
  Enumerating objects: 5, done.
  Counting objects: 100% (5/5), done.
  Delta compression using up to 4 threads
  Compressing objects: 100% (3/3), done.
  Writing objects: 100% (3/3), 381 bytes | 190.00 KiB/s, done.
  Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
  To https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/{repo_name}
  50f0c31..3488038  master -> master

実行結果

初回実行結果

作成した API をコールした結果は以下の通りです。

修正後リリース結果

コードを以下の通り修正し、再度 push します。

    def lambda_handler(event, context):
    return {
        "isBase64Encoded": False,
        "statusCode": 200,
        "headers": {},
        "body": '{"message": "こんにちは、世界!!"}',
    }

push すると、パイプラインが実行されます。

再度 API をコールします。表示される文字列が更新され、Lambda が更新されたことが確認できます。

一方、Lambda の設定画面を見てみると、デプロイしたバージョンとエイリアスが紐づいていることが確認できます。

最後に

CodeCommit、CodeBuild、CodePipeline を使用して Lambda の CI/CD を実装することができました。ポイントを改めてまとめます。

  • Lambda でエイリアスとバージョニングを有効にする
  • API Gateway で Lambda を実行する際は、エイリアスの ARN を指定する
  • CodBuildのbuildspec.yaml内でaws cliを使用してLambda関数の更新を実装

CodeBuildのOS は Linux ですので、Linux でできることは大抵できます。そのため、buildspec.yml をいかに駆使するかで自由度が変わります。一方で、連携する AWS サービス間で変更が発生した際の影響を理解し、互いに干渉しない仕組みがあるかどうかの確認も必要です。

CTCは、AWSのビジネス利活用に向けて、お客様のステージに合わせた幅広い構築・運用支援サービスを提供しています。
経験豊富なエンジニアが、ワンストップかつ柔軟にご支援します。
ぜひ、お気軽にお問い合わせください。

お問い合わせ

【著者プロフィール】

佐藤 和希(さとう かずき)

伊藤忠テクノソリューションズ株式会社 クラウドアーキテクト

AWS上で実装されるクラウドネイティブなシステムの開発プロジェクトに従事。 エンタープライズ向けクラウドネイティブ案件のプリセールス並びにプロジェクトにおけるクラウドアーキテクトとして活躍中。

佐藤 和希(さとう かずき)

TOP>コラム一覧>Lambda の CI/CD を実装してみた

pagetop