コンテンツにスキップ

cd_pipeline_lambda pattern

概要

cd_pipeline_lambda patternは、Runtime環境上のLambda関数をデプロイするためのpatternです。

想定する適用対象環境

cd_pipeline_lambda patternは、Runtime環境で使用することを想定しています。

依存するpattern

cd_pipeline_lambda patternは、事前に以下のpatternが適用されていることを前提としています。

pattern名 利用する情報
cd_pipeline_lambda_trigger pattern デプロイのトリガとなるイベント、Delivery環境のデプロイ元であるAmazon S3バケットへアクセスするためのロール

構築されるリソース

このpatternでは、以下のリソースが構築されます。

リソース名 説明
AWS CodePipeline (CodePipeline) デプロイメントパイプラインを構成します
AWS CodeBuild (CodeBuild) Lambda関数のパブリッシュを行います。
AWS CodeDeploy(CodeDeploy) Lambda関数のエイリアスに対して、バージョンを紐づけます。
Amazon EventBridge 異なるAWSアカウント間でイベントを伝搬させるための経路(イベントバス)を構築します
Amazon CloudWatch Events デプロイ実行のトリガとなるイベントを受信するためのイベントを構成します
AWS Key Management Service (KMS) CodePipelineが利用するArtifact Store(S3バケット)を暗号化するための鍵を構築します

モジュールの理解に向けて

本モジュールはDelivery環境にアップロードされたLambda関数のソースを、Runtime環境にデプロイするためのモジュールです。

前提事項

cd_pipeline_lambda patternは、以下の前提事項のもとで利用されることを想定しています。


ℹ️

cd_pipeline_lambda_trigger patternでは、デプロイ用のイベントを発火させるために、 CloudTrailのデータイベントログ記録機能に依拠しています。 一方で、本patternについては当該機能は有効化せずとも動作します。 コンプライアンスや課金の観点を鑑み、有効・無効をご判断ください。

Lambda関数のデプロイにあたっては、AWS Lambdaバージョンエイリアスの機能を利用しています。


環境毎のデプロイ戦略

下図は、前者のcd_pipeline_lambda_trigger patternを組み合わせた場合のデプロイ処理のアーキテクチャおよびシーケンスを示したものです。

アーキテクチャ

図のケースでは、イベントバス経由でDelivery環境からデプロイ開始イベントが伝搬することでデプロイが開始されます。 デプロイ処理はCodePipelineが制御し、大きく分けて以下のシーケンスで行われます。

  1. CodePipeline: Delivery環境のS3バケット上のzip圧縮されたアプリケーションの読み取り。アーティファクトストアのsourceに配置されます
    • Delivery環境のS3バケット上に配置されるzipファイルには以下のファイルを含めておきます
      • 必須
        • Lambda関数用のソース(zip)
        • buildspec.yml
      • オプション
        • appspec.yaml(パイプラインを最後まで実行するためには必要ですが、ここでは必要ありません)
  2. CodePipeline: (オプション)承認権限者へのデプロイ承認要求
  3. CodeBuild: Lambda関数のパブリッシュ。アーティファクトストアのsourceからアプリケーションと設定ファイルbuildspec.ymlを読み取り。CodeDeployで使用するappspec.yamlファイルを、アーティファクトストアのbuildに配置
    • appspec.yamlは、CodeBuild実行時に作成しても問題ありません。もちろん、Delivery環境のS3バケットへアップするzipに含めておくこともできます
  4. CodePipeline: (オプション)承認権限者へのデプロイ承認要求
  5. CodeDeploy: (オプション)Lambda関数のエイリアスのバージョン付け替え。設定ファイルappspec.yamlはアーティファクトストアのbuildより取得

2つの設定ファイル、buildspec.ymlappspec.yamlについては別途説明します

承認権限者への承認はオプションです。例えば、開発環境の場合はCodeBuild実行前とCodeDeploy実行前、両方とも承認不要にするといった対応が可能です。その場合、以下のように設定します。

runtimes/staging/cd_pipeline_lambda/main.tf

module "cd_pipeline_lambda" {

  ...

  deployment_require_approval_before_build = false  # CodeBuild実行前の承認不要
  deployment_require_approval_before_deploy = false  # CodeDeploy実行前の承認不要
}

一方でProduction環境においては、デプロイタイミングもサービス関係者の協議の元で決定されるため、パイプラインの進行はマニュアル操作で開始する方が多いであろうと想定しています。

Production環境へのデプロイには承認必須とする場合は、以下のように設定します。

runtimes/production/cd_pipeline_lambda/main.tf

module "cd_pipeline_lambda" {

  ...

  deployment_require_approval_before_build = true  # CodeBuild実行前の承認が必要
  deployment_require_approval_before_deploy = true  # CodeDeploy実行前の承認が必要
}

承認必須とした場合は、CodePipeline上に構成されるデプロイメントパイプラインを手動で進行再開させてください。

承認

ℹ️ 設定しなかった場合、いずれもデフォルトはtrue(承認必須)となります。

ℹ️ 承認が必要となった場合、Amazon SNSによって承認者宛に通知できます。詳細は入出力リファレンスを参照してください。

このパターンで作成されるCodeDeployステージの実行もオプションです。エイリアスの付け替えを行わない場合は、このステージを実行しないようにできます。

module "cd_pipeline_lambda" {

  ...

  require_codedeploy = false  # CodeDeployのステージを実行しない
  deployment_require_approval_before_deploy = false # CodeDeploy実行前の承認が不要
}

サンプルコード

cd_pipeline_lambda patternを使用したサンプルコードを、以下に記載します。

module "cd_pipeline_lambda" {
  source = "git::https://gitlab.com/eponas/epona.git//modules/aws/patterns/cd_pipeline_lambda?ref=v0.2.6"

  delivery_account_id = "[Delivery環境のアカウントID]"

  pipeline_name = "my-lambda-cd-pipeline"

  artifact_store_bucket_name = "my-lambda-artifacts"

  # Delivery環境のS3にCodePipelineからクロスアカウントでアクセスするためのロール
  # cd_pipeline_lambda_trigger の output として出力される
  cross_account_codepipeline_access_role_arn = "arn:aws:iam::[Delivery環境のAWSアカウントID]:role/[ロール名]"

  # ci_pipeline の static_resource_buckets と同じ名前を指定する
  source_bucket_name = "my-lambda-source-bucket"
  source_object_key  = "source.zip"

  # CodeBuild、CodeDeployを実行する前の承認を行うかどうか
  deployment_require_approval_before_build = true
  deployment_require_approval_before_deploy = true

  # CodeBuild、CodeDeployを実行する前の承認を行う場合、SNS topicに承認のためのURLを送る場合、
  # SNS topicのARNを指定する
  sns_topic_arn_approval_before_build  = "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:sns-topic01"
  sns_topic_arn_approval_before_deploy = "arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:sns-topic02"

  # CodeDeplyの設定。デプロイメントグループと名称を指定。
  codedeploy_deployment_group_name = "deployment_group-lambda-01"
  codedeploy_name                  = "codedeploy-lambda-01"
}

デプロイをするための設定ファイル群

Eponaとしては、Lambda関数のデプロイを行うケースとして以下の2種類のユースケースを想定しています。以下、それぞれのユースケースに対したサンプルを記載します。

  1. 常にLambda関数の最新バージョンを使う
    • 主として開発環境等において、最新のLambda関数を利用して実行とコード修正を繰り返したい場合を想定しています
  2. 利用するLambda関数のバージョンを明示的に指定する
    • 主としてProduction環境等において、十分にテストされたLambda関数を実行したい場合を想定しています

Eponaで提供するLambda関数のためのCI/CDパイプライン全体で必要になるファイル群の詳細なサンプルについては、Getting Startedを参照してください。

常にLambda関数の最新バージョンを使う

  • CodeBuild
    • AWS CLIを利用してエイリアスが向いている現在のバージョンを取得
    • AWS CLIを利用してLambda関数をパブリッシュ
    • AWS CLIを利用してLambda関数の最新バージョン($LATEST)を取得
    • エイリアスの現在のバージョンと、変更後のバージョンを記載したappspec.yamlを作成
      • appspec.yamlを作成するためのテンプレートappspec.yaml.tmplを用意しておき、sedコマンドで置き換えています
    • appspec.yamlをアーティファクトのアウトプットとして設定
  • CodeDeploy
    • エイリアスに紐づくバージョンを変更
# buildspec.yaml
version: 0.2
phases:
  build:
    commands:
      - function_name="YOUR_FUNCTION_NAME"
      - alias_name="YOUR_ALIAS_NAME"
      - current=$(aws lambda get-alias --function-name ${function_name} --name ${alias_name} --query  FunctionVersion)
      - aws lambda update-function-code --publish --function-name ${function_name} --zip-file  fileb://source.zip
      - target=$(aws lambda publish-version --function-name ${function_name} --query Version)
      - sed -e "s/CURRENTVERSION/${current}/" -e "s/TARGETVERSION/${target}/" appspec.yaml.tmpl > appspec.yaml
artifacts:
  files:
    - appspec.yaml
  discard-paths: yes
# appspec.yaml.tmpl
version: 0.0
Resources:
  - myLambdaFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: "YOUR_FUNCTION_NAME"
        Alias: "YOUR_ALIAS_NAME"
        CurrentVersion: CURRENTVERSION
        TargetVersion: TARGETVERSION

利用するLambda関数のバージョンを明示的に指定する

  • CodeBuild
    • Lambda関数をパブリッシュ
  • CodeDeploy
    • エイリアスに紐づくバージョンを変更
# buildspec.yml
version: 0.2
phases:
  build:
    commands:
      - aws lambda update-function-code --publish --function-name Lambda関数名 --zip-file  fileb://source.zip
artifacts:
  files:
    - appspec.yaml
  discard-paths: yes
# appspec.yaml
version: 0.0
Resources:
  - myLambdaFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: Lambda関数名
        Alias: エイリアス名
        CurrentVersion: 1 # 現在のバージョン
        TargetVersion: 2 # 変更後のバージョン 存在しないバージョンを指定するとCodeDeploy実行時にエラーになります。

注意

  • CodeDeployで実行する内容の設定ファイル名はappspec.yamlです
    • 拡張子は.yamlです。.ymlではありませんので注意してください
  • appspec.yamlCurrentVersionTargetVersionは数字を指定する必要があります
    • $LATESTは指定できません

関連するpattern

cd_pipeline_lambda patternに関連するpatternを、以下に記載します。

pattern名 説明
cd_pipeline_lambda_trigger pattern デプロイのトリガとなるイベントやDelivery環境のリソースアクセスに必要なロールなどを構築します。
lambda pattern このパターンのデプロイ先となるLambda関数を作成できます。

入出力リファレンス

Requirements

Name Version
terraform ~> 0.14.10
aws >= 3.37.0, < 4.0.0

Inputs

Name Description Type Default Required
codedeploy_deployment_group_name CodeDeployのデプロイメントグループ名 string n/a yes
codedeploy_name CodeDeployのアプリケーション名 string n/a yes
cross_account_codepipeline_access_role_arn Runtime環境のCodePipelineから利用するクロスアカウントアクセス用RoleのARN。 string n/a yes
delivery_account_id Delivery環境のアカウントID string n/a yes
pipeline_name CodePipelineの名前 string n/a yes
source_bucket_name デプロイ用のzip化されたソースファイルを配置するバケット名 string n/a yes
artifact_store_bucket_force_destroy Artifact Storeとして使っているS3 bucketを強制的に削除可能にするか否か bool false no
artifact_store_bucket_name CodePipelineのアーティファクトを管理するS3 bucket名
未設定の場合、 "[pipeline_name]-artifact-store" でS3 bucketを作成する。
string "" no
artifact_store_bucket_transitions Artifact Storeの移行に対するポリシー設定。最新でなくなったファイルに対して適用される。未設定の場合は30日後にAmazon S3 Glacierへ移行する list(map(string))
[
{
"days": 30,
"storage_class": "GLACIER"
}
]
no
codebuild_compute_type デプロイ用CodeBuildのコンピューティングリソースタイプ。選択できる値についてはTerraformドキュメントのcompute_typeを参照。 string "BUILD_GENERAL1_SMALL" no
deployment_cloudwatch_logs_kms_key_id デプロイ用CodeBuildのログデータを暗号化するためのKMS CMKのARN string null no
deployment_cloudwatch_logs_retention_in_days デプロイ用CodeBuildのログをCloudWatch Logsで保持する期間を設定する。

値は、次の範囲の値から選ぶこと: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653.
Resource: aws_cloudwatch_log_group / retention_in_days
number null no
deployment_require_approval_before_build CodeBuildの実行前に承認を必要とするか bool true no
deployment_require_approval_before_deploy CodeDeployの実行前に承認を必要とするか bool true no
require_codedeploy CodeDeployをパイプラインに含めるかどうか。デフォルトは含める(true) bool true no
sns_topic_arn_approval_before_build ビルド前の承認リクエストの送信先となるSNSトピックのARNを指定する。 string null no
sns_topic_arn_approval_before_deploy デプロイ前の承認リクエストの送信先となるSNSトピックのARNを指定する。 string null no
source_object_key デプロイ用のzip化されたソースファイルのObject Key string "source.zip" no
tags CodePipelineに付与するタグ map(string) {} no

Outputs

Name Description
artifact_store_arn Artifact store用bucketのARN
codebuild デプロイプロパイダとして用いるCodeBuildの情報
kms_keys 作成されたKMSの鍵

※ このドキュメントはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。

※ このドキュメントに記載されている会社名、製品名は、各社の登録商標または商標です。

© 2021 TIS Inc.