AWS CodeDeployによるアプリケーションのデプロイ

AWS CodeDeployのコンピューティングプラットフォーム、デプロイタイプと設定、ライフサイクルフック、プラットフォーム別AppSpecを学びます。

学習順Step 117 / 121サービスCodePipeline試験ドメインデプロイメント

AWS CodeDeployによるアプリケーションのデプロイ

アプリケーションの新しいバージョンを稼働環境へ届けるときは、ファイルや関数を配置するだけでなく、更新の順序、利用者トラフィックの切り替え、更新後の確認を管理する必要があります。AWS CodeDeployは、デプロイ対象と方式を指定し、アプリケーションのリビジョンを配備するマネージドサービスです。

CodeDeployは、デプロイグループやデプロイ設定に従って更新作業を進めます。ソースの取得、ビルド、テスト、承認などを含むリリース工程全体の編成はCodePipelineが担い、CodeDeployはその中のデプロイ工程を担当できます。CodeBuildがビルド済みの成果物を作る役割であるのに対し、CodeDeployは成果物を対象環境へ反映する役割です。

CodeDeployの基本要素

デプロイを理解するには、アプリケーション、リビジョン、コンピューティングプラットフォーム、デプロイグループ、デプロイタイプ、デプロイ設定を区別します。

要素 役割
アプリケーション CodeDeploy内でデプロイ対象を識別する名前。プラットフォーム、リビジョン、デプロイグループなどを関連付ける単位
リビジョン 配備するアプリケーションのバージョン。ソースコード、実行ファイル、設定ファイル、AppSpecなどから構成される
コンピューティングプラットフォーム デプロイ先の種類。EC2/オンプレミス、AWS Lambda、Amazon ECSの3種類
デプロイグループ デプロイ対象の集合や、トラフィック切り替えに関する設定。EC2インスタンスのタグやAuto Scalingグループ、Lambdaのエイリアス、ECSサービスなどを関連付ける
デプロイタイプ 既存環境を更新するか、置き換え環境へ切り替えるかなど、リビジョンを利用可能にする方法
デプロイ設定 ホスト更新時に満たす正常ホスト数や、Lambda・ECSでトラフィックを移す割合と間隔などを定めるルール

CodeDeployのデプロイタイプと、コンピューティングプラットフォームごとの更新方法

EC2/オンプレミスへデプロイする場合は、対象インスタンスでCodeDeployエージェントが実行され、リビジョンの取得やAppSpecに指定されたスクリプトの実行などを行います。AWS上のインスタンスからリビジョンを取得する権限にはインスタンスプロファイルを使い、CodeDeployのサービスロールは対象インスタンスやロードバランサーなどを操作するために使います。役割が異なるIAMロールを一つの権限として扱わず、それぞれの処理に必要な範囲を許可します。

コンピューティングプラットフォーム

CodeDeployの3つのプラットフォームは、配備する対象と更新の進め方が異なります。

プラットフォーム 配備する対象 主な更新方法
EC2/オンプレミス 実行ファイル、Web資産、設定ファイルなど インプレースで既存インスタンスを更新するか、EC2上に置き換え環境を用意するブルー/グリーン
AWS Lambda Lambda関数の新しいバージョン 関数エイリアスが指すバージョンを切り替え、設定した割合で呼び出しトラフィックを移す
Amazon ECS ECSサービスの新しいタスクセット 置き換えタスクセットを作成して検証し、ロードバランサー経由のトラフィックを移すブルー/グリーン

EC2/オンプレミスのリビジョンは、AppSpecと配備するファイルをまとめたアーカイブで、Amazon S3またはGitHubのリポジトリから取得できます。S3上のリビジョンはオブジェクトキーとETagやバージョン、GitHub上のリビジョンはコミットIDで識別します。Lambdaではデプロイする関数の情報を含むYAMLまたはJSON形式のリビジョンを使います。ECSではAppSpecにタスク定義やロードバランサー情報を記述します。CodePipelineを使う構成では、パイプラインのアーティファクトとしてソースや成果物をデプロイ工程へ受け渡します。

EC2/オンプレミス:インプレースデプロイ

インプレースデプロイでは、デプロイグループ内の既存インスタンスを対象に、アプリケーションを停止し、新しいリビジョンをインストールして再起動・検証します。ロードバランサーと連携する場合、更新するインスタンスを一時的にロードバランサーから外し、完了後に戻すように構成できます。

同じインスタンスを順に更新するため、新旧環境を別々に保持する必要はありません。一方で、更新中のインスタンスはリクエストを処理できない時間があり、同時に更新する台数や正常とみなすホスト数によって利用可能容量が変わります。AllAtOnceで全対象を一斉に更新すると短時間で完了しやすい反面、ロードバランサー配下の全台を同時に対象にする構成では処理能力の低下や停止につながる可能性があります。

EC2/オンプレミス:ブルー/グリーンデプロイ

ブルー/グリーンデプロイでは、新しいリビジョンを別の置き換え環境に配備し、テストや確認の後でトラフィックを新環境へ移します。旧環境をすぐに終了させず保持しておけば、問題発生時の切り戻しに利用できます。元の環境を更新しながら使うインプレース方式に対し、置き換え環境で確認してから切り替えるため、リリース時の環境差を減らしやすくなります。

EC2/オンプレミスというプラットフォーム名でも、このブルー/グリーン方式の対象はAmazon EC2インスタンスのみです。オンプレミスサーバーにはEC2/オンプレミスのインプレースデプロイを使えますが、このプラットフォームにおけるブルー/グリーンデプロイには対応していません。置き換え先はAuto Scalingグループを基に作成するか、タグなどで指定します。新環境の準備後、Elastic Load Balancingとの設定に従ってトラフィックを切り替えます。

AWS Lambda:関数バージョンとエイリアス

Lambdaでは、CodeDeployは関数の発行済みバージョンをデプロイし、エイリアスを介して呼び出しトラフィックを旧バージョンから新バージョンへ移します。関数の実行環境をインスタンス単位で更新するのではなく、どのバージョンにリクエストを送るかを制御します。

たとえば、物流追跡APIのLambda関数を更新するとき、新バージョンへ少量のトラフィックを送り、エラーや応答を確認してから残りを切り替える構成にできます。段階的な移行には、CodeDeployのトラフィックシフト設定を使います。検証用Lambdaをフックとして指定すると、切り替え前後の確認結果をデプロイに反映できます。

Amazon ECS:置き換えタスクセット

CodeDeployのECSコンピューティングプラットフォームでは、ブルー/グリーンデプロイで旧タスクセットと置き換えタスクセットを扱います。新しいタスクセットを作成してテストトラフィックを通し、検証後に本番トラフィックを移します。デプロイ設定は一度に切り替える方法のほか、一定時間を空けて一部ずつ切り替える方法を選べます。

CodeDeployのECSデプロイでは、ロードバランサーとタスク定義を関連付ける必要があります。AppSpecにはタスク定義のARN、置き換えタスクセットでトラフィックを受けるコンテナ名とポートなどを指定します。テストリスナーを用意すると、本番トラフィックを切り替える前に置き換えタスクセットを検査できます。

「ECSはブルー/グリーンのみ」とは、CodeDeployのECSコンピューティングプラットフォームを使う場合の話です。ECSにはCodeDeploy以外のネイティブなデプロイコントローラーとデプロイ方式もあります。設問では、ECSサービスのデプロイコントローラーがCodeDeployなのか、ECSネイティブなのかを確認し、別の仕組みの機能を混同しないようにします。

デプロイタイプとデプロイ設定

デプロイタイプは「既存の実行環境を更新するか、新しい環境を用意して切り替えるか」を表し、デプロイ設定は「何台ずつ更新するか、またはトラフィックをどの割合で移すか」を表します。この二つは異なる設定です。

EC2/オンプレミスの更新単位

EC2/オンプレミスでは、デプロイ設定が更新中に維持する正常ホスト数や一度に更新するホスト数を決めます。標準の設定は次の3種類です。

設定 更新の進め方 特徴
CodeDeployDefault.AllAtOnce できるだけ多くのインスタンスを同時に更新する 最短時間で更新しやすいが、一時的に利用可能な台数が減る。更新成功台数に関するデプロイ全体の成功条件も確認が必要
CodeDeployDefault.HalfAtATime 最大で対象の半数ずつ更新する 一部のホストを残しながら進める。対象数が奇数の場合の端数処理と、全体の成功判定はAWSの定義に従う
CodeDeployDefault.OneAtATime 一度に1台を更新する 変更の影響を小さくしやすいが、台数が多いほど完了に時間がかかる。最後の1台に対する成功判定には例外がある

この設定はインプレースだけでなく、EC2/オンプレミスのブルー/グリーンでも、置き換えインスタンスへの配備やトラフィック再ルーティングに適用されます。Blue/Greenでは新環境の更新とトラフィック切り替えの段階にも関係するため、名前だけから「インスタンスを作る速度」だけを決める設定と考えないでください。より細かい正常ホスト数を使う場合は、カスタムデプロイ設定を作成できます。

Lambda・ECSのトラフィックシフト

LambdaとECSのCodeDeployデプロイ設定は、旧バージョンまたは旧タスクセットから新しい対象へ、トラフィックをどのように移すかを決めます。

方式 トラフィックの移し方 向いている検証
All-at-once すべてを一度に新しいバージョンまたはタスクセットへ移す 更新をすばやく切り替えたい場合
Canary まず一部を新しい対象へ送り、設定した待ち時間後に残りを移す 初期の少量トラフィックで問題がないか確認してから全体へ広げたい場合
Linear 一定の割合を一定間隔で段階的に移す 複数段階のメトリクスやアプリケーション動作を観察しながら切り替えたい場合

たとえば、Canaryでは最初に10%を新バージョンへ送り、指定した時間が経過した後に残りを移す設定があります。Linearでは10%ずつなどの等しい割合を一定間隔で追加し、全量に達するまで段階を進めます。CodeDeployにはLambda用・ECS用の定義済み設定があり、条件に応じてカスタムのCanaryまたはLinear設定を作成できます。なお、Network Load Balancerを使うCodeDeployのECSデプロイでは、定義済みのECSAllAtOnceのみがサポートされます。ロードバランサーの種類を含めて設定を選びます。

デプロイライフサイクルフック

ライフサイクルイベントは、デプロイの進行中にCodeDeployが行う段階です。ライフサイクルフックは、その段階で独自のスクリプトや検証関数を実行するための設定です。単なるファイルコピーの前後に、バックアップ、サービスの停止と起動、設定変更、ヘルスチェックなどを差し込めます。フックを定義しないイベントでは、独自の処理は実行されません。

EC2/オンプレミス、ECS、LambdaのCodeDeployライフサイクルイベントとフック

EC2/オンプレミスのフック

EC2/オンプレミスではAppSpecのhooksにイベント名と実行スクリプトを対応付けます。主要な順序は、既存アプリケーションの停止、インストール前処理、ファイル配置、配置後処理、アプリケーション起動、動作確認です。

イベント 使いどころ
ApplicationStop 既存アプリケーションの停止や、旧パッケージの削除。前回成功したリビジョンに含まれるAppSpecとスクリプトが使われる
DownloadBundle エージェントがリビジョンを一時ディレクトリへコピーする。エージェント専用イベントのため、独自スクリプトは登録できない
BeforeInstall 新しいファイルを配置する前のバックアップや、インストール準備
Install エージェントがリビジョンのファイルを指定先へコピーする。エージェント専用イベントのため、独自スクリプトは登録できない
AfterInstall 設定変更、所有者や権限の設定、依存関係の準備
ApplicationStart 停止していたサービスやアプリケーションの起動
ValidateService 起動後のヘルスチェックや、アプリケーションの応答確認

ApplicationStopのスクリプトは今回のリビジョンではなく、前回成功したリビジョンに含まれるものが実行されます。初回のデプロイでは以前のリビジョンがないため、このイベントのフックは実行されません。フックのスクリプトが失敗すると、デプロイも失敗し得ます。

ロードバランサー連携時には、インスタンスをロードバランサーから外す前のBeforeBlockTraffic、外した後のAfterBlockTraffic、登録前のBeforeAllowTraffic、登録後のAfterAllowTrafficも使えます。BlockTrafficとAllowTraffic自体はCodeDeployエージェントが処理するイベントで、独自スクリプトを登録する段階ではありません。どのイベントが利用できるかはデプロイタイプやフックのシナリオにもよります。

ECSのフック

ECSではインスタンスごとのスクリプトではなく、AppSpecのhooksから検証用Lambda関数を呼び出します。デプロイ中に呼ばれる順序と目的は次のとおりです。

  1. BeforeInstall:置き換えタスクセットの作成前に処理する。
  2. AfterInstall:置き換えタスクセットが作られた後に確認する。
  3. AfterAllowTestTraffic:テストリスナーが置き換えタスクセットへトラフィックを送った後に検証する。
  4. BeforeAllowTraffic:本番トラフィックを移す直前に検査する。
  5. AfterAllowTraffic:本番トラフィックを新しいタスクセットへ移した後に確認する。

各イベントは必要なものだけ指定します。テストトラフィック後の検査に失敗した場合など、イベントによってはデプロイをロールバックできます。検証用Lambdaは、実行結果をCodeDeployへSucceededまたはFailedとして通知します。結果が返らないまま所定の制限時間を過ぎるとデプロイは失敗します。

Lambdaのフック

Lambda関数のデプロイでは、フックとして指定した検証用Lambda関数が新バージョンへの切り替えの前後に実行されます。

  • BeforeAllowTraffic:新バージョンへトラフィックを切り替える前に検証する。
  • AfterAllowTraffic:すべてのトラフィックを新バージョンへ移した後に確認する。

ECSの場合よりイベント数は少なく、インスタンスやタスクセットではなく関数バージョンとエイリアスの切り替えを検証します。ここでも、検証用Lambdaは結果をCodeDeployへ通知します。CodeDeployのリリース設定で指定する「デプロイ対象のLambda」と、フックで起動する「検証用Lambda」は役割が異なります。

AppSpecファイルで配備内容を指定する

AppSpec(Application Specification)ファイルは、CodeDeployに対象リソースやデプロイ時の処理を伝えるファイルです。必要な項目はコンピューティングプラットフォームごとに異なります。

プラットフォーム 主なAppSpec項目 指定する内容
EC2/オンプレミス version、os、files、permissions、hooks OS、コピー元と配置先、ファイル権限、ライフサイクルイベントごとのスクリプト
Amazon ECS version、Resources、Hooks ECSサービス、タスク定義、ロードバランサーで使うコンテナ名とポート、検証用Lambda
AWS Lambda version、Resources、Hooks 関数名、エイリアス、現在のバージョンと配備先バージョン、検証用Lambda

EC2/オンプレミスのAppSpecは、リビジョンのルートに置くYAMLファイルappspec.ymlです。filesはリビジョン内のファイルとインスタンス上の配置先を対応させます。permissionsは対応するLinux系環境などで配置ファイルに権限を設定し、hooksは前述のライフサイクルイベントにスクリプトを割り当てます。アーカイブにAppSpecを含め、同じリビジョンのファイルと一緒にデプロイします。

LambdaとECSではAppSpecをYAMLまたはJSONで記述できます。LambdaのResourcesは、配備する関数、エイリアス、現在のバージョン、目標バージョンを特定します。ECSのResourcesは、更新先のECSサービスを指定し、タスク定義やロードバランサーの設定を関連付けます。どちらもHooksにはライフサイクルイベントで呼び出す検証用Lambdaを設定できます。EC2向けのfilesやpermissionsをLambda・ECSのAppSpecにそのまま持ち込むのではなく、対象プラットフォームに対応したスキーマを使います。

CodeBuildのbuildspec.ymlはビルドコマンドや成果物を定義するのに対し、CodeDeployのAppSpecは配備先で何を配置・更新し、どのフックを実行するかを定義します。名前が似た設定ファイルとして混同せず、パイプライン内の役割を分けてください。

試験で見分けるポイント

  • どのサービスがどの工程を担うか:工程全体はCodePipeline、ビルドとテストはCodeBuild、対象環境への配備はCodeDeploy。
  • EC2とオンプレミス:どちらもEC2/オンプレミスのプラットフォームを使える。インプレースは両方を対象にできるが、このプラットフォームのブルー/グリーンはEC2のみ。
  • インプレースとブルー/グリーン:既存ホストを更新するのか、置き換え環境に先に配備してからトラフィックを切り替えるのかを読み分ける。
  • EC2のデプロイ設定:AllAtOnce、HalfAtATime、OneAtATimeは更新ホスト数や正常ホストの成功条件に関わる。
  • LambdaとECSのデプロイ設定:CodeDeployのAll-at-once、Canary、Linearは、割合と時間に従ったトラフィック移行を定める。
  • ECSの更新方式:CodeDeployのECSプラットフォームではブルー/グリーンでタスクセットを切り替える。ECSネイティブのデプロイ方式と区別する。
  • ライフサイクルフック:EC2/オンプレミスはインスタンス上でスクリプトを実行し、Lambda・ECSでは検証用Lambdaを実行して結果をCodeDeployへ返す。
  • AppSpecのプラットフォーム差:EC2/オンプレミスはファイル配置や権限、スクリプトを指定し、Lambda・ECSは更新するリソースとトラフィック検証を指定する。
  • 初回デプロイとApplicationStop:このフックは前回成功したリビジョンの定義を使うため、初回には実行されない。

公式ドキュメント

重要ポイント

  • ▸CodeDeployは、EC2・オンプレミス、Lambda、ECSの各プラットフォームへアプリケーションのリビジョンを配備するサービスであり、CI/CD全体の工程を編成するCodePipelineとは役割が異なる
  • ▸EC2/オンプレミスのインプレースは既存インスタンスを順次更新し、ブルー/グリーンは新しい環境へリビジョンを配備してからトラフィックを切り替える。EC2/オンプレミス基盤のブルー/グリーンはEC2インスタンスが対象で、オンプレミスインスタンスには使えない
  • ▸EC2/オンプレミスのAllAtOnce、HalfAtATime、OneAtATimeは、更新するホスト数と成功条件を決める。LambdaとECSのCodeDeployデプロイではAll-at-once、Canary、Linearでトラフィックを移す
  • ▸CodeDeployのECSデプロイはブルー/グリーン方式でタスクセットを入れ替える。ECS自体のネイティブデプロイ方式とCodeDeployのデプロイコントローラーを混同しない
  • ▸AppSpecはデプロイ対象と処理をプラットフォーム別に記述する。EC2/オンプレミスはfiles・permissions・スクリプトhooks、ECSとLambdaはresources・検証用hooksが中心となる
  • ▸EC2/オンプレミスのApplicationStopは前回成功したリビジョンのフックを実行するため、初回デプロイでは動かない。LambdaとECSのhooksは検証用Lambda関数を実行し、成功または失敗をCodeDeployへ返す

このトピックの学習を完了しますか?

完了状態はいつでも切り替えられます