3
1

AWS CodePipeline Blue/Green デプロイ時にエラーが発生した際の勘所

Posted at

はじめに

本記事はAWSのCodePipelineを利用している環境で、Blue/Green デプロイ時にエラーが発生した際の勘所について記載しています。

DevOpsの一環として、CodePipelineを用いてECS環境(ECS on EC2)におけるBlue/Green デプロイの導入を行う機会がありました。

CodePipelineの仕様に対する理解不足が多く、デプロイ時にエラーが発生してトライアンドエラーを繰り返したのでナレッジとしてまとめました。

アップデート方式

クラウド上に構築したシステムに対するアップデート方式は、一括でアップデートを行うAll at onceを除くと、以下のようなデプロイ戦略があります。

  • Rolling
  • Bule/Green
  • Canary

目的に応じてソフトウェアの新しいバージョンや変更を本番環境に展開するためのデプロイ戦略を選択することが重要です。アップデート頻度やコストに対してリターンが見込めない場合は、最適でない場合もあると思います。

ECSのデフォルトは、Rollingによるアップデートです。
Rollingによるアップデートは、追加リソースが不要なため、コストがからないことがメリットです。デメリットは、切り戻しが困難なことです。

Blue/Green

Blue/Greenデプロイメントは、システムの可用性を最大化し、ダウンタイムを最小限に抑えることができます。

以下に、Blue/Greenデプロイメントのメリット及びデメリットについて記載します。

  • メリット
    • 高可用性と信頼性向上:Blue/Greenデプロイメントは、新しいバージョンのアプリケーションを現在の環境(Blue)とは別の環境(Green)に展開し、任意のタイミングでトラフィックを切り替えることができます。
    • 切り戻しが容易:新しいバージョンに問題が発生した場合、本番環境を別の環境(Green)から現在の環境(Blue)に切り替えることで、簡単にロールバックできます。
    • テストプロセスの強化: Blue/Greenデプロイメントはテストプロセスを強化します。新しいバージョンは現在の環境(Blue)とは別の環境(Green)でテスト可能なため、現在の環境となる本番環境に影響を与えずにテストが可能です。
  • デメリット
    • 追加のリソース:Blue/Greenデプロイメントでは、現在の環境(Blue)とは別の環境(Green)の両方が稼働するため、追加のリソースが必要です。従って追加のコストが発生1します。
    • データの同期:データベースなど何らかのデータストアを必要とする場合、データの同期と一貫性を維持することが難しい場合があります。そのため、データベースで管理するデータのマイグレーションを行う場合は注意2が必要です。
    • 導入コスト:AWSの場合はタスク定義のテンプレートやAppSpecファイルなど管理すべき資産が増えるため、Rollingと比較した場合AppSpecファイルの管理場所など検討事項が発生します。

基本的にRolling、Bule/Green、Canaryはサービス停止なしでアップデートが可能です。
Blue/Green方式と、Canaryの違いについては、Blue/Green方式が一括で切り替わるのに対して、Canary方式は徐々に環境が切り替わるのが特徴です。

Blue/Green デプロイ時にエラーが発生した際の勘所

Blue/Green デプロイ時にエラーが発生した際の勘所について以下に記載します。

コンソールの注意事項

AWSではサービスによってコンソールの新旧画面が存在する場合があります。

コンソールの新旧を切り替える場合は、EC2を例にすると画面左上の「New EC2 Experience」を操作することで、切り替えができます。

スクリーンショット 2023-09-29 8.15.15.png

コンソールの新旧を切り替えた場合は、表示内容が大きく変わるため、設定項目が変化することから注意が必要です。

デプロイメントタイプでBlue/Green デプロイメントが選択できない場合

ECSでBlue/Green デプロイに対応するための設定を行う場合、コンソール画面の新旧によって表示内容が異なります。

例えば、新しいコンソール画面からECSを開いて新規にサービスを作成する場合、デプロイオプションのデプロイタイプを確認すると、ローリングアップデートがグレー表示になっていて操作することができません。

スクリーンショット 2023-09-15 18.29.46.png

最初は起動タイプがEC2環境の場合、対応していないのかと勘違いしましたが、そんなことはありませんでした。

AWSのサポートにも確認しましたが、新しいコンソールの仕様とのことで、旧コンソール画面に切り替えることで選択できると回答いただきました。(将来的には改善されるのではないかと思います)

スクリーンショット 2023-09-15 18.29.59.png

taskdef.jsonの作成

タスク定義ファイルとしてtaskdef.jsonファイルを作成する場合、新コンソール画面から作成します。

旧コンソール画面の場合はJSONの形式が異なっているため、optionの項目がnullになることから注意が必要です。

サービスを更新したがデプロイできない場合

検証を行っている中、サービスを更新したがデプロイが開始されない事象が発生しました。

確認したところ、公式ドキュメントのコンソールを使用したサービスの更新を参考にサービスの設定から新しいデプロイの強制をチェックしたら動きました。

更新されたコンテナイメージをタスクに使用する場合は、そのイメージを使用して新しいタスク定義リビジョンを作成し、コンソールで [新しいデプロイの強制] オプションを使用して、サービスにデプロイできます。

スクリーンショット 2023-09-15 18.53.01.png

CodePipelineのアクセスエラー

CodePipelineのDeployステージで、AWSCodePipelineServiceRoleに対するアクセスエラーが発生しました。

AWSCodePipelineServiceRoleはデフォルトで作成されるロールですが、Blue/Green デプロイを行うには権限が不足しています。

必要な権限については、公式ドキュメントのAWS CodePipeline のためのアイデンティティおよびアクセス管理からCodePipeline サービスロールにアクセス許可を追加するの7をご確認ください。

{
    "Effect": "Allow",
    "Action": [
        "codedeploy:CreateDeployment",
        "codedeploy:GetDeployment",
        "codedeploy:GetApplication",
        "codedeploy:GetApplicationRevision",
        "codedeploy:RegisterApplicationRevision",
        "codedeploy:GetDeploymentConfig",
        "ecs:RegisterTaskDefinition",
        "ecs:TagResource"
    ],
    "Resource": "resource_ARN"
},

BuildArtifactの例外発生

CodePipelineのDeployステージで、BuildArtifactの例外が発生しました。

CodePipelineはbuildspec上でアーティファクトを出力する必要があるため、buildspec.ymlファイルに以下に示すような設定の記述が存在するか確認しましょう。

files: 
    - appspec.yml
    - taskdef.json

AppSpecファイルの拡張子

ymlファイルの拡張子は.yamlymlがあります。

CodePipelineの設定と、buildspec.ymlファイル及びappspec.yml間で整合が取れてない場合は、ファイルが認識できないため、Exception while trying to read the AppSec artifact file from: BuildArtifact.のようなエラーが出力されます。

  • CodePipelineの設定
    スクリーンショット 2023-09-28 23.42.25.png

  • buildspec.ymlファイル

files: 
    - appspec.yml
    - taskdef.json

1タスクで複数コンテナが稼働する場合

公式ドキュメントのイメージ定義ファイルのリファレンスを参考にしながら複数のコンテナイメージのペアをリストするようにファイルを構築することもできます。

1タスクで複数コンテナが稼働する場合はtaskdef.jsonで指定するimageに対する考慮が必要です。

以下はtaskdef.jsonで指定するimageに不備があったため、出力されたエラーメッセージです。

Container.image contains invalid characters.

端的に言うと、buildspec.ymlファイルのビルドプロセスでtaskdef.jsonを出力するようにすることで、1タスクで複数コンテナの設定が可能です。

CodePipelineのビルド時に実行するコマンドで注意すべきこと

上記に関連して、例えばbuildspec.ymlファイルのビルドプロセスでsedコマンドを使用する場合、ECRのリポジトリは/が含まれるため、sedコマンドを使用する場合はデリミタに対する注意が必要です。

対応として、sedコマンドで使用するデリミタを/から@に変更することで解消できます。

Tags can not be empty.

デプロイ時にTags can not be empty.のようなエラーメッセージが出力された場合は、taskdef.jsonファイルの以下行を削除します。

 "tags": []

参考:AWS pipeline, code deploy 'Tags cannot be empty'."

タイムアウト

「トラフィックを再ルーティングするタイミングを指定する」を有効にしている場合、CodeDeployは時間が過ぎても自動的にルーティングを実行してくれません。

後で確認すると、以下のようなエラーメッセージが出力されます。

The deployment timed out while waiting for a notification to continue. This time out period is 1440 minutes.

エラーを発生させないためには、指定した時間までにトラフィックの再ルーティングを実行するとが必要です。

おわりに

デプロイを開始してビルドは成功したものの、デプロイでエラーが発生し、原因を究明してトライアンドエラーを繰り返す。

本記事を書くにあたり、他にもまだエラーが出ていたたと思います。
同じような事象が発生した方のご参考になれば幸いです。

参考

  1. RollingもBlue/Greenより短い時間ではあるものの、一時的に2つのタスクが稼働します。そのため、ECS on EC2の場合はデプロイ時に複数のタスクを起動するためのスペックが必要です。

  2. Rollingも一時的に異なる環境のコンテナが平行稼働するため、破壊的変更があるマイグレーションが発生する場合は、古いコンテナからはアクセスできないなどのエラーが懸念されます。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1