🐙

【AWS】ダウンタイムゼロへの挑戦 - バックエンドとフロントエンドをBlue/Greenデプロイ

2024/08/27に公開

はじめに

EVチームでは、サービスリリース時にユーザーが一時的に利用できなくなるダウンタイムが発生していました。ダウンタイムの主な問題は、ユーザーの利用機会の喪失と、リリース作業の厳しいタイムリミットです。これらの問題を解決するため、新しいデプロイ手法の導入が必要となったので、Blue/Greenデプロイを採用し、導入しました。

対象と使用するAWSサービス

  • バックエンド
    • API Gateway
    • Lambda
  • フロントエンド
    • Route 53
    • Elastic Beanstalk
    • Application Load Balancer(ALB)
    • EC2

ダウンタイムとその影響

ダウンタイムとは、システムやサービスが一時的に停止することを指します。
ダウンタイムはユーザー体験の低下や収益の損失を引き起こし、リリース作業における心理的ハードルを高めます。特に、24時間稼働が必要な電気自動車の充電サービスでは、ダウンタイムは避けなければならない重要な課題です。この記事では、ダウンタイムを最小限に抑えるための手法であるBlue-Greenデプロイについて説明します。

Blue/Greenデプロイとは何か?

Blue-Greenデプロイは、ダウンタイムを発生させずに新しいバージョンのアプリケーションをリリースするためのデプロイ戦略です。
この手法では、2つの環境(通常「Blue」と「Green」と呼ばれます)を用意します。
現在稼働中の「Blue」環境と、新しいバージョンがデプロイされる「Green」環境を用意し、Green環境が正常に動作していることを確認した後、トラフィックをBlue環境からGreen環境に切り替えます。これにより、ユーザーへの影響を最小限に抑えて新しいバージョンをリリースできます。

Blue-greenデプロイのメリットとデメリット

メリット

  • ダウンタイムを最小限に抑えることができる。
  • 新しいバージョンに問題が発生した場合、迅速に元のバージョンに戻せる。
  • リリースの安全性が向上し、リスクが軽減される。

デメリット

  • 環境を2つ用意するため、インフラコストが増加する可能性がある。
  • 環境の同期を保つための運用が複雑になることがある。

API編(バックエンド)

EVチームでは、バックエンドのAPIにAWSの「API Gateway」と「Lambda」を使用しています。ここでは、このAPI部分でのBlue-Greenデプロイ手法を紹介します。

  1. Lambdaのバージョン設定
  2. Lambdaのエイリアス設定
  3. apigatewayからのLambdaと統合
  4. blue/greenへのリクエストの切り替え方法

api-backend

1.Lambdaのバージョン設定

Lambdaにはバージョン管理機能があり、関数を更新すると新しいバージョンを作成し、その時点の状態を保存できます。
これにより、特定のバージョンを固定し、必要に応じてそのバージョンに戻ることができます。

ステップ詳細(コンソール):

  1. Lambda関数の更新後、AWSコンソールから「新しいバージョンを発行」を選択して新しいバージョンを作成します。
  2. バージョン番号(1, 2, 3...)が自動的に割り当てられ、その時点のLambda関数の状態が保存されます。

lambda-version

2.Lambdaのエイリアス設定

Lambdaのエイリアス(Alias)機能は、特定のバージョンに名前を付けて管理するための機能です。これにより、"blue"や"green"エイリアスを特定のバージョンに割り当てて簡単に参照できます。

ステップ詳細(コンソール):

  1. AWSコンソールでLambda関数の「エイリアス」タブを開きます。
  2. 「エイリアスを作成」を選択し、エイリアス名を指定します(例: blue、green)。
  3. エイリアスに紐付けるバージョンを選択します。これにより、指定したエイリアスを使用してそのバージョンにアクセスできます。

lambda-alias

3.API GatewayからLambda Aliasの使用

API GatewayのステージとLambdaのエイリアスを統合すると、環境ごとに異なるLambdaバージョンを簡単に管理できます。
API Gatewayの「blue」ステージをLambdaの「blue」エイリアスに紐付けることで、blueステージでは常にblueエイリアスで指定したLambdaバージョンを使用できます。

ステップ詳細(コンソール):

  1. API Gatewayで「ステージ」タブを開き、blue/greenのステージを作成します。
    agw-stage
  2. Lambda関数のARNを指定する際、エイリアスを含めます。エイリアスの指定方法は、ARNの末尾に「:エイリアス名」を指定します。(例: arn:aws:lambda:region:account-id:function:function-name:blue)。
    agw-lambda-integration
  3. これにより、API Gatewayの「blue」ステージがLambdaの「blue」エイリアスに紐付けられます。

4.blue/greenへのリクエストの切り替え方法

1~3のステップでAPI Gatewayで2つのblue/greenステージを作成し、それぞれのステージをblue/greenのLambdaエイリアスを紐付けが完了しました。

最後にAPI Gatewayでカスタムドメインを設定し、そのドメインに対してAPIマッピングを行います。
カスタムドメインに対して、パスベースで各ステージをマッピングします。
Blue/Greenデプロイのタイミングで、ドメインのルートに対するマッピングを切り替えます。

例えば、以下のように設定し、本番はblueステージで動作させつつ、新しいバージョンのAPIを/testで動作確認することが可能になります。

https://example.com → blue ステージ

https://example.com/test → green ステージ

ステップ詳細(コンソール):

  1. API Gatewayで「Custom Domain Names」セクションを開き、カスタムドメインを設定します。
  2. ドメインに対してパスベースで各ステージ(例: /blue、/green)をマッピングします。
  3. デプロイのタイミングで、ドメインのルート(例: https://example.com/)を「blue」から「green」に切り替えます。

これにより、ユーザーに影響を与えることなく新しいバージョンのAPIを提供できます。

api-mapping

Web編(フロントエンド)

フロントエンドにはAWSの「Route 53」「Elastic Beanstalk」「Application Load Balancer(ALB)」「EC2」を使用しています。

以下にフロントエンドのBlue-Greenデプロイ方法を紹介します。

  1. Elastic Beanstalkの準備
  2. Application Load Balancerの設定
  3. Route 53の設定
  4. デプロイと切り替え

frontend

1.Elastic Beanstalkの準備

Elastic BeanstalkでBlue/Green二つの環境を作成します。
各環境には、それぞれ独自のURLが割り当てられます(例: blue-env.elasticbeanstalk.com と green-env.elasticbeanstalk.com)。

ステップ詳細(コンソール):

  1. AWSコンソールでElastic Beanstalkを開き、「Create a new environment」を選択します。
  2. 2つの環境(「blue」と「green」)を作成し、異なるアプリケーションバージョンをデプロイします。
  3. 各環境には、Elastic Beanstalkが独自のサブドメインを割り当てます。

Elastic beanstalkの各環境の作成後画面

2.Application Load Balancerの設定

ALBを作成し、両方のElastic Beanstalk環境に対してターゲットグループを設定します。

ステップ詳細(コンソール):

  1. blue/green環境で使用するec2をそれぞれ用意します。
    ec2
  2. EC2コンソールで「ターゲットグループ」を選択します。2つのターゲットグループを作成し、それぞれのEC2を指定します。(例: blue-target-group と green-target-group)。
    target-group
  3. EC2コンソールで「ロードバランサー」を選択し、Blue/Green用のALBを作成し、それぞれのターゲットグループと連携します。
    load-balancer

3.Route 53の設定

Route 53でカスタムドメインを設定し、ALBにCNAMEレコードを設定します。初期設定では、すべてのトラフィックを blue-target-group に送信します。

ステップ詳細(コンソール):

  1. Route 53コンソールで「Hosted Zones」を開き、該当するホストゾーンを選択します。
  2. 「レコードを作成」をクリックし、Aレコードとして設定します。
  3. トラフィックのルーティング先として、「Application Load Balancer と Classic Load Balancer へのエイリアス」を選択します。
  4. ロードバランサーの選択では、先ほど作成したBlueのロードバランサーをを指定します。
  5. これにより、指定のホストにアクセスしたユーザーがblue-target-groupにルーティングされるようになります。

route53

4.デプロイと切り替え

Green環境に新しいアプリケーションバージョンをデプロイし、テストを実施します。

  1. Green環境に新しいアプリケーションバージョンをデプロイします。
  2. Green環境のテストを実施。
    • セキュリティグループを設定し、デプロイ環境のIPのみ、Greenのターゲットグループに接続できるように設定します。
    • frontend-test
  3. route53のAレコードをGreen環境に変更

ステップ詳細(コンソール):

  1. Green環境へのデプロイ
    • Elastic Beanstalkコンソールで「green」環境を選択し、新しいアプリケーションバージョンをデプロイします。
  2. Green環境でアプリケーションの動作確認
    • Blueで使用しているALBのリスナールールを設定し、特定のIPアドレスのみがGreenのターゲットグループへルーティングするようにし、ステージングテストを行います。
    • listeners
  3. 切り替え
    • Route 53コンソールで、Aレコードを更新しすべてのトラフィックがGreen環境にルーティングされるようにします。
    • 切り替え後、必要に応じてblue環境を保留するか削除し、次回のデプロイに備えます。

最後に

今回のBlue-Greenデプロイの導入により、サービスのリリースに伴うダウンタイムを大幅に削減することができました。特に、電気自動車の充電サービスのように24時間稼働が求められる環境では、このデプロイ手法が非常に有効であることを実感しました。また、リリース作業に対する心理的ハードルが下がり、開発チーム全体の生産性向上にも寄与しました。
一方で運用の複雑さという課題があり、デプロイ機構の改修は今後も取り組んでいきます。


最後まで読んでいただきありがとうございました。

Discussion