メインコンテンツへスキップ
友田 陽大
AWS Lambda 本番運用
AWS
Lambda
CI/CD
サーバーレス
IaC

Lambdaの安全なデプロイ:バージョン・エイリアス・カナリアリリース(CodeDeploy)とSAM/CDK/Terraform選定

AWS Lambdaをゼロダウンタイムで安全にデプロイする実装ガイド。不変なバージョンとエイリアス、加重エイリアスとCodeDeployのカナリア/リニア配信、プリ/ポストトラフィックフックとCloudWatchアラームによる自動ロールバック、関数ステートの待機、SAM/CDK/Terraform/Serverless Frameworkの選定、GitHub Actions OIDCによる鍵レスCI/CDまでAWS公式仕様に忠実な実コードで解説します。

公開日
読了時間
12分
著者
友田 陽大
シェア

update-function-code で本番に上書きデプロイしたら、不具合が全ユーザーに一斉に出た」——Lambda は1コマンドでデプロイできてしまうがゆえに、安全装置のない出荷をしがちです。決済の確定処理やユーザーの操作を捌くAPIで、新バージョンの不具合が100%のトラフィックに即座に当たるのは、本番運用として許容できません。

この記事は、AWS Lambda をゼロダウンタイム・自動ロールバック付きで安全にデプロイするための実装ガイドです。バージョンとエイリアスという土台から、カナリアリリース自動ロールバックIaC(SAM/CDK/Terraform)の選定OIDCによる鍵レスCI/CDまでを一気通貫で解説します。題材として、私が中核開発者として構築したサーバーレス決済プラットフォーム本番二重課金0件)での出荷判断も交えます。Lambda 本体の実行モデルは姉妹記事 AWS Lambda 本番運用ガイド に委ね、本稿は**「どう安全に出荷するか」一点**に集中します。

この記事のルール:仕様・パラメータ名・定義済み設定名は AWS 公式ドキュメント(2026年6月時点) に基づきます。CodeDeployの設定名やランタイム、各ツールの仕様は改定されます。本番投入前に必ず公式(末尾「参考」)で最新値を確認してください。


0. メンタルモデル:「不変なバージョン」と「動くポインタ」を分ける

安全なデプロイの全ては、この2つの分離から始まります。

  • バージョン=不変のスナップショット。公開(publish)すると、その時点のコードと設定が固定された番号付きバージョンになる。番号は単調増加で、削除・再作成しても再利用されない
  • エイリアス=バージョンを指す、動かせるポインタliveprod という名前で特定バージョンを指す。デプロイとは**「エイリアスの指す先を新バージョンに、安全に切り替える」**こと。
  • $LATEST は可変update-function-code のたびに上書きされる。だから本番トラフィックを $LATEST に直接向けない——必ずエイリアス経由で呼ぶ。
  • カナリア=ポインタを一気に動かさず、重みで少しずつ動かす。新バージョンに10%だけ流し、問題なければ100%へ。問題があれば自動で戻す。

この「不変な土台+動くポインタ+段階的切り替え+自動ロールバック」が、本記事の設計です。


1. バージョンとエイリアス:本番はエイリアス経由で呼ぶ

まず土台を作ります。$LATEST に対してコードを更新し、安定したらバージョンを公開し、エイリアスをそのバージョンに向ける。クライアントはエイリアスのARNを呼びます。

# 1) コードを更新($LATEST が変わる。本番はまだこれを見ていない)
aws lambda update-function-code --function-name orders --zip-file fileb://build.zip

# 2) 更新完了を待つ(重要。LastUpdateStatus=Successful になるまで次の操作は失敗する)
aws lambda wait function-updated-v2 --function-name orders

# 3) 不変バージョンを公開(番号が振られる。例: 42)
VERSION=$(aws lambda publish-version --function-name orders --query Version --output text)

# 4) エイリアス live をそのバージョンへ。クライアントは live を呼ぶ
aws lambda update-alias --function-name orders --name live --function-version "$VERSION"

ここで効く公式仕様を3つ:

  • エイリアスは「修飾ARN(qualified ARN)」...:function:orders:live のように修飾子(バージョン番号 or エイリアス名)が付く。修飾子なし(unqualified)で呼ぶと暗黙的に $LATEST が走る——本番では事故の元。
  • プロビジョンド同時実行・SnapStart は公開バージョン/エイリアスでのみ有効$LATEST 不可)。レイテンシ対策(コールドスタート最適化)を効かせるにも、この土台が前提。
  • すべての設定変更がバージョンを公開するわけではない。例えば予約済み同時実行はバージョンを作らない(関数全体の運用設定のため)。

2. カナリアリリース:加重エイリアスで「10%だけ」流す

エイリアスは最大2つの公開バージョンを指し、重みでトラフィックを分配できます(routing config / AdditionalVersionWeights)。これがカナリアリリースの心臓部です。

# エイリアス live:97%を現行、3%を新バージョン(43)へ。問題なければ重みを上げていく
aws lambda update-alias --function-name orders --name live \
  --function-version 42 \
  --routing-config 'AdditionalVersionWeights={"43"=0.03}'

公式が課す制約を押さえます(守らないとエラー or 事故)。

  • 両バージョンとも公開済みであること($LATEST 不可)。
  • 両バージョンの実行ロールが同一であること。
  • **DLQ設定が同一(または両方なし)**であること。
  • 同一関数の2バージョンであること。

手で重みを上げ下げするのは現実的でないので、CodeDeployに任せて自動化します(次章)。

プロビジョンド同時実行との両立:カナリア中にコールドスタックを避けたいなら、ルーティングが有効な間だけプロビジョンド同時実行を多めに用意できます(公式が言及)。レイテンシSLAのあるAPIでは、カナリアとプロビジョンドを組み合わせます。


3. 自動ロールバック付きカナリア:CodeDeploy + SAM

CodeDeploy は、加重エイリアスの重みを定義済みのスケジュールで自動的に動かし、CloudWatchアラームが鳴れば自動ロールバックします。手動の重み調整は不要になります。

3.1 定義済みデプロイ設定(公式の正式名)

種別設定名(CodeDeployDefault. を冠する)挙動
カナリアLambdaCanary10Percent5Minutes / 10Minutes / 15Minutes / 30Minutes10%流し、指定分後に残り90%を一括
リニアLambdaLinear10PercentEvery1Minute / Every2Minutes / Every3Minutes / Every10Minutes10%ずつ段階的に増やす
一括LambdaAllAtOnce一気に100%(カナリアなし)

名前の注意:リニアの最短だけ Every1Minute(単数)、他は複数形(Every2Minutes)。SAM の DeploymentPreference.Type では先頭の CodeDeployDefault.Lambda外した短縮名(例:Canary10Percent10Minutes)を使います。

3.2 SAM なら数行で「検証+自動ロールバック」が組める

SAM の AutoPublishAlias(コード変更を検知して自動でバージョン公開+エイリアス更新)と DeploymentPreference(カナリア戦略・アラーム・フック)を組み合わせると、安全デプロイが宣言的に書けます。

# template.yaml(AWS SAM):カナリア+プリ/ポスト検証+アラームで自動ロールバック
Resources:
  OrdersFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs22.x
      Architectures: [arm64]              # Arm64で実行料金20%減(互換があれば)
      AutoPublishAlias: live              # これが無いと DeploymentPreference は使えない
      DeploymentPreference:
        Type: Canary10Percent5Minutes     # 10%を5分流し、問題なければ残りを切替
        Alarms:                           # どれか1つでも ALARM になれば自動ロールバック
          - !Ref OrdersErrorsAlarm
          - !Ref OrdersLatencyP99Alarm
        Hooks:
          PreTraffic: !Ref PreTrafficCheck   # 切替前にスモークテスト
          PostTraffic: !Ref PostTrafficCheck # 切替後に結合検証

  # 新バージョンのエラー率を監視(鳴ったらロールバック)
  OrdersErrorsAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      Namespace: AWS/Lambda
      MetricName: Errors
      Dimensions:
        - { Name: FunctionName, Value: !Ref OrdersFunction }
        - { Name: Resource, Value: !Sub "${OrdersFunction}:live" }
      Statistic: Sum
      Period: 60
      EvaluationPeriods: 1
      Threshold: 1
      ComparisonOperator: GreaterThanOrEqualToThreshold

プリ/ポストトラフィックフックは、CodeDeployがトラフィック切替の前後に呼ぶ検証用Lambdaです。フックは結果を PutLifecycleEventHookExecutionStatus でCodeDeployにコールバックし、失敗すればデプロイは中断・ロールバックされます。フック関数名は慣例で CodeDeployHook_ で始めます。

# プリトラフィックフック:切替前に新バージョンをスモークテストし、合否をCodeDeployへ返す
import boto3
codedeploy = boto3.client("codedeploy")

def handler(event, context):
    deployment_id = event["DeploymentId"]
    hook_id = event["LifecycleEventHookExecutionId"]
    status = "Succeeded"
    try:
        run_smoke_tests()   # 新バージョン(エイリアス未切替の version)を直接叩いて検証
    except Exception:
        status = "Failed"   # ここでFailedを返すと切替されずロールバックされる
    codedeploy.put_lifecycle_event_hook_execution_status(
        deploymentId=deployment_id, lifecycleEventHookExecutionId=hook_id, status=status,
    )
    return {"status": status}

最初のデプロイは2段階:CodeDeployは「切替元の旧バージョン」が必要なので、初回は AutoPublishAlias だけでデプロイ→2回目から DeploymentPreference を有効化、という順序になります。


4. IaC の選定:SAM / CDK / Terraform / Serverless Framework

「どれでLambdaを管理するか」は買い手意図の強い問いです。安全デプロイの組みやすさチームの資産で選びます。

ツール安全デプロイ強み向くチーム
AWS SAMDeploymentPreference 数行サーバーレス特化・最小設定でカナリアAWSサーバーレスに全振り、最短で安全に出荷したい
AWS CDKLambdaDeploymentGroup型安全なIaC・NodejsFunctionのesbuildバンドル型・補完・複雑な構成をコードで組みたい
Terraform○ 自前で組む多クラウド・既存Terraform資産すでにTerraform運用・AWS以外も管理
Serverless Framework○ プラグインYAMLの手軽さ小規模・素早く。ただしv4はライセンス注意

要点:

  • SAMAutoPublishAliasDeploymentPreferenceType/Alarms/Hooks)で、カナリア+自動ロールバックが最小コスト。CloudFormationの拡張なので、生成されるリソースも追える。
  • CDKaws-lambdaFunctionNodejsFunction(esbuildで自動トランスパイル・バンドル)と、aws-codedeployLambdaDeploymentGroupLambdaDeploymentConfig.CANARY_10PERCENT_5MINUTES で同等の安全デプロイ。Python/Goのバンドルはalphaモジュール。
  • Terraformaws_lambda_functionpublish = true)+ aws_lambda_aliasrouting_config.additional_version_weights)+ aws_codedeploy_appcompute_platform = "Lambda")/aws_codedeploy_deployment_group自分で組み合わせる。制御は効くが配線は増える。
  • Serverless Frameworkserverless.yml の手軽さは随一だが、v4 は「直近会計年度の売上が200万ドル超の個人・組織」に有償サブスクリプションが必要(v3は無償・OSS継続)。組織規模によってはコストを織り込む。
# Terraform:バージョン公開+エイリアスの加重ルーティング(カナリアの土台)
resource "aws_lambda_function" "orders" {
  function_name = "orders"
  role          = aws_iam_role.orders.arn
  handler       = "index.handler"
  runtime       = "nodejs22.x"
  architectures = ["arm64"]
  filename      = "build.zip"
  publish       = true # 変更のたびに不変バージョンを公開
}

resource "aws_lambda_alias" "live" {
  name             = "live"
  function_name    = aws_lambda_function.orders.function_name
  function_version = aws_lambda_function.orders.version
  routing_config {
    additional_version_weights = { } # CodeDeploy/手動でカナリア時に重みを注入
  }
}

5. CI/CD:GitHub Actions から「鍵レス」でデプロイする

長期的なAWSアクセスキーをGitHub Secretsに置くのは、漏洩リスクの塊です。公式の正解は OIDC(OpenID Connect)——GitHub が発行する短命のJWTを、AWSのIAMロールに AssumeRoleWithWebIdentity で交換し、一時クレデンシャルで動く。保存する鍵がゼロになります。

# .github/workflows/deploy.yml:OIDCで鍵レスにSAMデプロイ(長期キーをSecretsに置かない)
name: deploy
on:
  push: { branches: [main] }
permissions:
  id-token: write   # OIDCトークンの発行に必須
  contents: read
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v6   # 推奨:OIDCで一時クレデンシャル取得
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-deploy
          aws-region: ap-northeast-1
      - uses: aws-actions/setup-sam@v2
      - run: sam build
      - run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset

IAM側は、信頼ポリシーで発行者 token.actions.githubusercontent.com・オーディエンス sts.amazonaws.com を許可し、**sub クレームで「このリポジトリのこのブランチだけ」**に絞ります(最小権限)。OIDCの詳しい設計は姉妹記事 OIDCで実現する鍵レスCI/CD に。


6. ゼロダウンタイムの落とし穴:関数ステートを待つ

最後に、地味だが本番で必ず踏む落とし穴。Lambdaの更新は非同期で、ステートマシンを持ちます。

State意味操作可否
Pending作成/設定中(VPCのENI作成など)呼び出し不可。更新も失敗する
Active稼働中呼び出せる唯一の状態
Inactiveアイドルで回収(VPCは14日)次回呼び出しは一旦失敗→Pendingで再作成
Failed失敗削除して作り直す

加えて LastUpdateStatusSuccessful/Failed/InProgress)があり、InProgress の間は次の UpdateFunctionCode/UpdateFunctionConfiguration/PublishVersion が失敗ResourceConflictException / 409)します。だから:

  • コード更新 → wait function-updated-v2 → 設定更新/公開、という順序を守る(CIで連続実行すると409で落ちる典型)。
  • VPC関数は反映に時間がかかる(Hyperplane ENI。詳細はコールドスタート記事)。デプロイ直後に叩くテストは、Activeを確認してから。
# CIでの安全な連続更新:各ステップで完了を待ってから次へ
aws lambda update-function-code --function-name orders --zip-file fileb://build.zip
aws lambda wait function-updated-v2 --function-name orders        # ← これを挟まないと409
aws lambda update-function-configuration --function-name orders --environment "Variables={LOG_LEVEL=INFO}"
aws lambda wait function-updated-v2 --function-name orders
aws lambda publish-version --function-name orders

7. まとめ:安全デプロイ・チートシート

  • 土台$LATEST は可変。**公開バージョン(不変)+エイリアス(ポインタ)**を作り、本番は修飾ARN(エイリアス)経由で呼ぶ。
  • カナリア:加重エイリアス(最大2バージョン・重み分配)。両バージョンは公開済み・同一実行ロール・同一DLQが条件。
  • 自動化:CodeDeploy の Canary10Percent5Minutes 等+プリ/ポストフックで検証CloudWatchアラームで自動ロールバック。SAMなら AutoPublishAliasDeploymentPreference の数行。
  • IaC:安全デプロイ最短はSAM、型安全はCDK、多クラウド/既存資産はTerraform、手軽だがServerless v4は年商200万ドル超で有償
  • CI/CDOIDCで鍵レスid-token: writeAssumeRoleWithWebIdentitysub でリポジトリ/ブランチを限定)。
  • 落とし穴:更新は非同期。LastUpdateStatus=Successful を待つInProgress 中の更新は409)。VPC関数は反映に時間がかかる。

私は決済プラットフォームで、本番二重課金0件を支える出荷規律として「不変バージョン+カナリア+アラーム自動ロールバック+鍵レスCI/CD」を徹底しました。新バージョンの不具合が全ユーザーに当たる前に、10%で検知して自動で戻す——これが、止められない決済基盤を安全に進化させ続ける土台です。

「自社のLambdaを、止めず・壊さず・自動で戻せる形で継続的に出荷したい」——カナリア戦略の設計からCI/CDの鍵レス化、IaCの選定まで、一人 × 生成AI(Claude Code)の速さで伴走します。 既存のデプロイフロー監査からでも、お気軽にご相談ください。


参考(公式ドキュメント)

友田

友田 陽大

経済産業大臣賞 受賞プロダクト開発者。TypeScript + Python + AWS で、SaaS・業界DX・ 実用レベルの生成AI(RAG)を、要件定義からインフラ・運用まで一人で完遂します。

この記事で解説した技術の適用事例

環境分野のサーバーレス決済プラットフォーム(フルスタック開発・決済信頼性レイヤーを主導)

ケーススタディを見る