サーバーレスアプリケーションの段階的なデプロイ - AWS Serverless Application Model

サーバーレスアプリケーションの段階的なデプロイ

AWS Serverless Application Model (AWS SAM) には CodeDeploy が組み込まれているため、AWS Lambda を段階的にデプロイできます。数行設定するだけで、AWS SAM が以下を実行します。

  • Lambda 関数の新しいバージョンをデプロイし、新しいバージョンをポイントするエイリアスを自動的に作成する。

  • 新しいバージョンが期待どおりに動作していることを確認するまで、カスタマートラフィックを新しいバージョンに段階的に移行する。更新が正しく動作しない場合は、変更をロールバックできます。

  • トラフィック前およびトラフィック後のテスト関数を定義して、新しくデプロイされたコードが正しく設定されており、アプリケーションが期待どおりに動作していることを確認する。

  • CloudWatch アラームがトリガーされた場合にデプロイを自動的にロールバックする。

注記

AWS SAM テンプレートを通じて段階的なデプロイを有効にすると、CodeDeploy リソースが自動的に作成されます。CodeDeploy リソースは、AWS Management Console で直接表示できます。

以下の例では、カスタマーを新しくデプロイされたバージョンの Lambda 関数に段階的に移行させるための CodeDeploy の使用を示します。

Resources: MyLambdaFunction: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs12.x CodeUri: s3://bucket/code.zip AutoPublishAlias: live DeploymentPreference: Type: Canary10Percent10Minutes Alarms: # A list of alarms that you want to monitor - !Ref AliasErrorMetricGreaterThanZeroAlarm - !Ref LatestVersionErrorMetricGreaterThanZeroAlarm Hooks: # Validation Lambda functions that are run before & after traffic shifting PreTraffic: !Ref PreTrafficLambdaFunction PostTraffic: !Ref PostTrafficLambdaFunction

AWS SAM テンプレートに対するこれらの修正は、以下を実行します。

  • AutoPublishAlias: このプロパティを追加し、エイリアス名を指定することで、AWS SAM が以下を実行します。

    • Lambda 関数の Amazon S3 URI に対する変更に基づいて、新しいコードがデプロイされていることを検出する。

    • 最新のコードでその関数の更新バージョンを作成し、発行する。

    • ユーザーが提供する名前でエイリアスを作成し (エイリアスが既に存在する場合を除く)、Lambda 関数の更新バージョンをポイントする。これを活用するには、関数の呼び出しがエイリアス修飾子を使用する必要があります。Lambda 関数のバージョニングとエイリアスになじみがない場合は、AWS Lambda 関数のバージョニングとエイリアスについて参照してください。

  • Deployment Preference Type: 上記の例では、カスタマートラフィックの 10% が直ちに新しいバージョンに移行され、10 分後にすべてのトラフィックが新しいバージョンに移行されます。ただし、トラフィック前またはトラフィック後のテストが失敗した場合、または CloudWatch アラームがトリガーされた場合は、CodeDeploy がデプロイをロールバックします。次の方法で、バージョン間のトラフィックの移行方法を指定できます。

    • Canary: トラフィックは 2 回の増分で移行されます。事前定義された Canary オプションから選択できます。このオプションは、最初の増分で更新された Lambda 関数バージョンに移行されるトラフィックの割合と、2 番目の増分で残りのトラフィックが移行されるまでの間隔を分単位で指定します。

    • Linear: トラフィックは、毎回同じ間隔(分)の等しい増分で移行します。増分ごとに移行されるトラフィックの割合と、増分間の間隔 (分) を指定する事前定義された Linear オプションから選択できます。

    • AllAtOnce: すべてのトラフィックは元の Lambda 関数から最新バージョンの Lambda 関数に一度に移行されます。

    以下の表は、この例で使用したもの以外で利用可能なその他のトラフィック移行オプションの概要です。

    デプロイプリファレンスのタイプ

    Canary10Percent30Minutes

    Canary10Percent5Minutes

    Canary10Percent10Minutes

    Canary10Percent15Minutes

    Linear10PercentEvery10Minutes

    Linear10PercentEvery1Minute

    Linear10PercentEvery2Minutes

    Linear10PercentEvery3Minutes

    AllAtOnce

  • Alarms: デプロイで発生したエラーによってトリガーされる CloudWatch アラームです。エラーが発生すると、デプロイは自動的にロールバックされます。例えば、デプロイしている更新されたコードがアプリケーション内にエラーを生じさせている場合です。別の例は、AWS Lambda、または指定した カスタム CloudWatch メトリクスがアラームのしきい値を超えた場合です。

  • Hooks: トラフィックが新しいバージョンに移行を開始する前、および移行が完了した後でチェックを実行する、トラフィック前とトラフィック後のテスト関数です。

    • PreTraffic: トラフィックの移行を開始する前に、CodeDeploy が pre-traffic hook Lambda 関数を呼び出します。この Lambda 関数は、CodeDeploy にコールバックして成功したか失敗したかを伝える必要があります。関数が失敗すると移行が中止され、AWS CloudFormation に失敗が報告されます。関数が成功すると、CodeDeploy はトラフィックの移行に進みます。

    • PostTraffic: トラフィックの移行が完了した後で、CodeDeploy が post-traffic hook Lambda 関数を呼び出します。pre-traffic hook と同様に、この関数は CodeDeploy にコールバックして成功したか失敗したかを伝える必要があります。post-traffic hook を使用して、統合テストやその他の検証アクションを実行します。

    詳細については、「SAM Reference to Safe Deployments」を参照してください。

初めて Lambda 関数を段階的にデプロイする

Lambda 関数を段階的にデプロイする場合、CodeDeploy は、トラフィックの移行元である、以前デプロイされた関数バージョンが必要です。したがって、最初のデプロイは次の 2 つのステップで実行する必要があります。

  • ステップ 1: Lambda 関数をデプロイし、AutoPublishAlias を使用してエイリアスを自動的に作成します。

  • ステップ 2: DeploymentPreference を使用して段階的にデプロイします。

最初の段階的デプロイを 2 つのステップで実行すると、トラフィックの移行元である、以前の Lambda 関数バージョンが CodeDeploy に与えられます。

ステップ 1: Lambda 関数をデプロイする

Resources: MyLambdaFunction: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs12.x CodeUri: s3://bucket/code.zip AutoPublishAlias: live

ステップ 2: 段階的にデプロイする

Resources: MyLambdaFunction: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs12.x CodeUri: s3://bucket/code.zip AutoPublishAlias: live DeploymentPreference: Type: Canary10Percent10Minutes Alarms: # A list of alarms that you want to monitor - !Ref AliasErrorMetricGreaterThanZeroAlarm - !Ref LatestVersionErrorMetricGreaterThanZeroAlarm Hooks: # Validation Lambda functions that are run before and after traffic shifting PreTraffic: !Ref PreTrafficLambdaFunction PostTraffic: !Ref PostTrafficLambdaFunction