
はじめに
安全なシステム運用を実現するためには、安全なアプリケーションリリースを実現する必要があります。
これを実現するための具体的なデプロイ手法としてダークカナリアリリースやブルーグリーンデプロイメントがあります。
本記事では Azure 上に構築されたシステムを想定して、Azure Front Door と Azure Container Apps を使用したブルーグリーンデプロイメントとダークカナリアリリースを試してみます。
前提条件
- Azure CLI が実行できる環境
- Azure CLI の containerapp 拡張機能がインストール済み
- Azure CLI の front-door 拡張機能がインストール済み。
- Azure のサブスクリプションに適切な権限を持ち、Azure CLI の設定に適切な認証情報がセット済み
- Docker CLI が実行できる環境
- Docker client が実行できる環境 (Docker Desktop、Rancher Desktop など)
- コマンドの実行は Bash での実行を想定しています。
- データ層は除外し、アプリケーション層に対してブルーグリーンデプロイを試みる。
用語説明は最小にとどめ、必要に応じて参考にしたリンクを添付しています。
用語説明
カナリアリリースとは
カナリアリリースは、新バージョンのアプリケーションを一部のユーザーにのみ公開し、問題がないことを確認してから全体に展開するデプロイ手法です。
参考:カナリアリリース | リリース手法多すぎワロタァ B/G、カナリア、機能フラグ、ダークローンチ、A/Bテスト、、など
ダークカナリアリリースとは
ダークカナリアリリースは、カナリアリリースの一種で、特定の条件(IPアドレス、ユーザーエージェント、カスタムヘッダーなど)に基づいて、エンドユーザーを除いた開発者などの限定されたユーザーにのみ新バージョンを公開し、問題がないことを確認してから全体に展開するデプロイ手法です。
本記事では、運用中の環境をブルーとして、開発拠点の IP アドレスからのアクセスのみ新バージョン(グリーン)にルーティングすることで、本番環境でのテストを実現します。
参考:ダークカナリアリリース | リリース手法多すぎワロタァ B/G、カナリア、機能フラグ、ダークローンチ、A/Bテスト、、など
ブルーグリーンデプロイメントとは
ブルーグリーンデプロイメントは、リリース後の切り戻しを容易にするデプロイ戦略です。
参考:ブルーグリーンデプロイメント | リリース手法多すぎワロタァ B/G、カナリア、機能フラグ、ダークローンチ、A/Bテスト、、など
前準備
今回の想定する Azure システムを下図の通りとします。また、Azure Container Registry にはブルーグリーンデプロイメントに使用する Nginx を使用した Web サーバー用のイメージを2つ用意し、それらを Azure Container Apps で使用することとします。

この想定されるシステムを基にブルーグリーンデプロイメントとダークカナリアリリースを試していきます。
また、本記事では、ブルーグリーンデプロイメント時に使用する ブルーとグリーン環境はそれぞれ現在運用中の環境をブルー環境、新バージョンのリリースに使用する環境をグリーン環境とします。
以降は前準備のために実際にリソースを作成します。
実際にリソースは作成しない、ハンズオン形式で進めない、ブルーグリーンとダークカナリアリリースの実施手順のみを確認したい場合は「ブルーグリーンデプロイ実施」の章までスキップしてください。
リソースの作成
では、ブルーグリーンデプロイメントとダークカナリアリリースを行うために、上記の構成図を基に必要なリソースを作成します。
必要なDockerfileの作成
下記コマンドを実行し、bluegreen-demo ディレクトリ配下に Dockerfile.blue と Dockerfile.green を作成する。
# 作業用ディレクトリ作成
mkdir -p $HOME/bluegreen-demo# Dockerfile.blue
FROM nginx:alpine
RUN echo '<html><body style="background-color: #0066CC; color: white; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: Arial;"><div style="text-align: center;"><h1>Blue Version</h1><p>Version: 1.0.0</p><p>Revision: v1.0.0-blue</p></div></body></html>' > /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]# Dockerfile.green
FROM nginx:alpine
RUN echo '<html><body style="background-color: #00CC66; color: white; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: Arial;"><div style="text-align: center;"><h1>Green Version</h1><p>Version: 1.1.0</p><p>Revision: v1.1.0-green</p></div></body></html>' > /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]リソースの作成
下記コマンドを実行して変数をセットします。
# 変数
## 初期化
RESOURCE_GROUP_NAME='rg-bg-dcr-ve-je'
LOCATION='japaneast'
ACR_NAME='crbgdcrveje'
CONTAINER_APP_ENV_NAME='cae-bg-dcr-ve-je'
CONTAINER_APP_NAME='ca-bg-dcr-ve-je'
BLUE_REVISION_SUFFIX='v1-0-0-blue'
GREEN_REVISION_SUFFIX='v1-1-0-green'
FRONT_DOOR_NAME='afd-bg-dcr-ve-je'
FRONT_DOOR_ENDPOINT_NAME='fde-bg-dcr-ve-je'
FRONT_DOOR_ORIGIN_GROUP_NAME='origin-group-web'
FRONT_DOOR_ORIGIN_NAME="origin-containerapp"
FRONT_DOOR_ROUTE_NAME="route-default"
# リソースグループ
## リソース作成
az group create \
--name $RESOURCE_GROUP_NAME \
--location $LOCATION
# Azure Container Registry
## リソースの作成
az acr create \
--resource-group $RESOURCE_GROUP_NAME \
--name $ACR_NAME \
--sku 'Basic' \
--location $LOCATION \
--admin-enabled true
## 管理者認証情報の取得
ACR_USERNAME=$(az acr credential show \
--name $ACR_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--query username \
--output tsv)
ACR_PASSWORD=$(az acr credential show \
--name $ACR_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--query passwords[0].value \
--output tsv)
ACR_LOGIN_SERVER=$(az acr show \
--name $ACR_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--query loginServer \
--output tsv)
## ACR へログイン
az acr login --name $ACR_NAME # docker client が実行されている必要があります。例えば、Docker Desktop や Rancher Desktop などです。
## イメージのビルドとプッシュ
### 準備
cd $HOME/bluegreen-demo
IMAGE_BLUE="${ACR_LOGIN_SERVER}/web:v1.0.0-blue"
IMAGE_GREEN="${ACR_LOGIN_SERVER}/web:v1.1.0-green"
### ブルー用イメージ
docker build -t $ACR_LOGIN_SERVER/web:v1.0.0-blue -f Dockerfile.blue .
docker push $ACR_LOGIN_SERVER/web:v1.0.0-blue
### グリーン用イメージ
docker build -t $ACR_LOGIN_SERVER/web:v1.1.0-green -f Dockerfile.green .
docker push $ACR_LOGIN_SERVER/web:v1.1.0-green
# Container Apps
## Container Apps Environment の作成
az containerapp env create \
--name $CONTAINER_APP_ENV_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--location $LOCATION
## Container Apps の作成 (ブルー用のリビジョンのみ)
### --revisions-mode でマルチリビジョンモードに設定 (デフォルトではシングルリビジョンモード)
az containerapp create \
--name $CONTAINER_APP_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--environment $CONTAINER_APP_ENV_NAME \
--image $IMAGE_BLUE \
--registry-server $ACR_LOGIN_SERVER \
--registry-username $ACR_USERNAME \
--registry-password $ACR_PASSWORD \
--target-port 80 \
--ingress external \
--revision-suffix $BLUE_REVISION_SUFFIX \
--revisions-mode multiple \
--cpu 0.25 \
--memory 0.5Gi \
--min-replicas 1 \
--max-replicas 1
## すべてのトラフィックをブルーリビジョンに流す
az containerapp ingress traffic set \
--name $CONTAINER_APP_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--revision-weight $CONTAINER_APP_NAME--$BLUE_REVISION_SUFFIX=100
## ブルーリビジョンにラベル付与
az containerapp revision label add \
--name $CONTAINER_APP_NAME
--resource-group $RESOURCE_GROUP_NAME \
--label blue \
--revision $CONTAINER_APP_NAME--$BLUE_REVISION_SUFFIX
## アプリケーションの FQDN 取得
CONTAINER_APP_FQDN=$(az containerapp show \
--name $CONTAINER_APP_NAME
--resource-group $RESOURCE_GROUP_NAME \
--query "properties.configuration.ingress.fqdn" \
--output tsv)
# Front Door
## リソースの作成
az afd profile create \
--profile-name $FRONT_DOOR_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--sku Standard_AzureFrontDoor
## エンドポイントの作成
az afd endpoint create \
--profile-name $FRONT_DOOR_NAME \
--endpoint-name $FRONT_DOOR_ENDPOINT_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--enabled-state Enabled
## ブルー用配信元グループの作成
az afd origin-group create \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name $FRONT_DOOR_ORIGIN_GROUP_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--probe-request-type GET \
--probe-protocol Https \
--probe-interval-in-seconds 100 \
--probe-path / \
--sample-size 4 \
--successful-samples-required 3 \
--additional-latency-in-milliseconds 50
## ブルー用配信元の作成
az afd origin create \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name $FRONT_DOOR_ORIGIN_GROUP_NAME \
--origin-name $FRONT_DOOR_ORIGIN_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--host-name $CONTAINER_APP_FQDN \
--origin-host-header $CONTAINER_APP_FQDN \
--priority 1 \
--weight 1000 \
--enabled-state Enabled \
--http-port 80 \
--https-port 443
## ルートの作成
az afd route create \
--profile-name $FRONT_DOOR_NAME \
--endpoint-name $FRONT_DOOR_ENDPOINT_NAME \
--route-name $FRONT_DOOR_ROUTE_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--origin-group $FRONT_DOOR_ORIGIN_GROUP_NAME \
--supported-protocols Http Https \
--link-to-default-domain Enabled \
--forwarding-protocol MatchRequest \
--https-redirect Enabled
# 疎通確認
FRONT_DOOR_FQDN=$(az afd endpoint show \
--profile-name $FRONT_DOOR_NAME \
--endpoint-name $FRONT_DOOR_ENDPOINT_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--query "hostName" \
--output tsv)
curl -i "${FRONT_DOOR_FQDN}"疎通確認時に Blue Version という文字が表示されていれば疎通確認 OK で前準備が完了になります。
もし、404 などのエラーが返されるようであれば、変更内容が反映されていない可能性があるため、時間をあけて再度確認する必要があります。
ブルーグリーンデプロイ実施
前章を経て、下記の図のようなルーティングが可能な構成が実現されています。

では実際にこの構成を基にブルーグリーンデプロイメントとダークカナリアリリースを行ってみます。
これらを実現するための大まかな流れは下記の通りを想定しています。
- グリーンリビジョンを作成してラベルの割り当てを行う。
- グリーン用の配信元グループを作成する。
- ルールセットを作成し、ルートに割り当てる。
- 動作確認
すべてのトラフィックをグリーンに流す。
グリーンリビジョンの作成とラベルの割り当て
Container Apps に グリーンリビジョンを追加して、ラベルを割り当てます。
az containerapp update \
--name $CONTAINER_APP_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--image $IMAGE_GREEN \
--revision-suffix $GREEN_REVISION_SUFFIX \
--cpu 0.25 \
--memory 0.5Gi
az containerapp revision label add \
--name $CONTAINER_APP_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--label green \
--revision $CONTAINER_APP_NAME--$GREEN_REVISION_SUFFIX続いてグリーンのラベルURLを取得し、疎通確認を行います。
このとき、Green Version という文字が表示されれば OK です。
加えて、Container Apps の FQDN に https で疎通した場合の表示内容も確認しておきましょう。このタイミングでは Container Apps の FQDN に対するすべてのアクセスはブルーのリビジョンに流れるようになっているはずです。
# グリーンのラベル URL のパース
CONTAINER_APP_BASE_DOMAIN=$(echo $CONTAINER_APP_FQDN | cut -d '.' -f2-) # e.g. abc.123.def.456 -> 123.def.456
GREEN_LABEL_URL="${CONTAINER_APP_NAME}---green.${CONTAINE_RAPP_BASE_DOMAIN}" # green はラベル名
curl -i "${GREEN_LABEL_URL}"
curl -i "${CONTAINER_APP_FQDN}"ここまでの設定を完了すれば、下図のルーティングを実現する構成が作成されています。

グリーン用の配信元グループ作成
グリーン用の配信元グループと配信元を作成します。
このとき、配信元に割り当てる URL は グリーンリビジョンのラベル URL であることに注意してください。
# 変数初期化
FRONT_DOOR_ORIGIN_GROUP_FOR_BGDEPLOY_NAME='origin-group-web-for-bgdeploy'
FRONT_DOOR_ORIGIN_NAME='origin-containerapp'
# グリーン用の配信元グループ作成
az afd origin-group create \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name $FRONT_DOOR_ORIGIN_GROUP_FOR_BGDEPLOY_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--probe-request-type GET \
--probe-protocol Https \
--probe-interval-in-seconds 100 \
--probe-path / \
--sample-size 4 \
--successful-samples-required 3 \
--additional-latency-in-milliseconds 50
# グリーン用の配信元の作成
az afd origin create \
--profile-name $FRONT_DOOR_NAME \
--origin-group-name $FRONT_DOOR_ORIGIN_GROUP_FOR_BGDEPLOY_NAME \
--origin-name $FRONT_DOOR_ORIGIN_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--host-name $GREEN_LABEL_URL \
--origin-host-header $GREEN_LABEL_URL \
--priority 1 \
--weight 1000 \
--enabled-state Enabled \
--http-port 80 \
--https-port 443ここまでの設定を完了すれば、下図のルーティングを実現する構成が作成されています。

カスタムルールの作成と割り当て
開発拠点に設定されている IP アドレスから Azure Front Door へのアクセスのみ、グリーンの配信元にトラフィックが流れるようにします。
下記のコマンドを実行してルールセットを作成します。
# 変数の初期化
MY_PUBLIC_IP=$(curl -s ifconfig.me) # 開発拠点のIPアドレス取得
RULE_SET_NAME="DarkCanaryRules"
RULE_NAME='RouteToGreenByDeveloperIP'
# ルールセット作成
az afd rule-set create \
--profile-name $FRONT_DOOR_NAME \
--rule-set-name $RULE_SET_NAME \
--resource-group $RESOURCE_GROUP_NAME
# IP 制限のルール追加
az afd rule create \
--profile-name $FRONT_DOOR_NAME \
--rule-set-name $RULE_SET_NAME \
--rule-name $RULE_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--order 1 \
--match-variable RemoteAddress \
--operator IPMatch \
--match-values $MY_PUBLIC_IP \
--action-name RouteConfigurationOverride \
--origin-group $FRONT_DOOR_ORIGIN_GROUP_FOR_BGDEPLOY_NAME
# デフォルトルートにルールセットを紐づける
az afd route update \
--profile-name $FRONT_DOOR_NAME \
--endpoint-name $FRONT_DOOR_ENDPOINT_NAME \
--route-name $FRONT_DOOR_ROUTE_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--rule-sets $RULE_SET_NAME
このタイミングで、Container Apps の FQDN に HTTPS でアクセスすると、開発拠点の IP アドレスからのアクセスはグリーンのリビジョンに、それ以外の IP アドレスからのアクセスはブルーのリビジョンにトラフィックが流れます。
ここまでの設定を完了すれば、下図のルーティングを実現する構成が作成されています。

動作確認
このタイミングでグリーンのリビジョンにアクセスできる開発者はシステムに問題がないか、例えばUIベースのテストを行います。
このタイミングで問題が発生した場合は、問題に応じてアプリの修正を行う必要があります。
問題が発生した場合でも、一般ユーザーからのアクセスはすべて旧バージョンのブルーリビジョンに流れているため、運用中の環境には影響が発生しません。
すべてのトラフィックをグリーンに流す
動作確認時に問題が発生しないことが確認できたら、下記の手順に従って、すべてのトラフィックをグリーンのリビジョンに流れるようにします。
1. ルールセットの割り当てを解除する。
2. Container Apps のトラフィック重みづけ変更して、Container Apps の FQDN に対するアクセスが、グリーンのリビジョンに流れるようにする。
下記コマンドを実行して、ルールセットの割り当て解除と Container App FQDN への HTTPS アクセスが、グリーンのリビジョンに流れるようにします。
# ルールセットの割り当て解除
az afd route update \
--profile-name $FRONT_DOOR_NAME \
--endpoint-name $FRONT_DOOR_ENDPOINT_NAME \
--route-name $FRONT_DOOR_ROUTE_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--rule-sets $RULE_SET_NAME
# トラフィックの重みづけを変更する。
az containerapp ingress traffic set \
--name $CONTAINER_APP_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--label-weight blue=0 green=100これですべてのトラフィックがグリーンのリビジョンに流れ、リリース作業は完了になります。
最終的なルーティングのイメージは下記の通りです。

万が一、リリース作業完了後に問題が発生した場合は、下記のコマンドを実行することで即座にロールバックすることが可能です。
az containerapp ingress traffic set \
--name $CONTAINER_APP_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--label-weight blue=100 green=0まとめ
本記事では、Azure Container Apps と Azure Front Door を使用したブルーグリーンデプロイメントとダークカナリアリリースを実装しました。
マルチリビジョンの機能を使用すれば1つの Azure Container Apps でブルーグリーンデプロイメントを実現でき、配信元2つとルールセットの機能を活用すれば Azure Front Door でダークカナリアリリースを実現することができました。
本番環境の運用でもこれらのリリース戦略を使用してシステムの安全運用に努めましょう!
備考
Azure Front Door と Azure Container Apps を使用してブルーグリーンデプロイメントとダークカナリアリリースを試すにあたって事前に気になっていたことを備忘録としてまとめます。
Container Apps 1つでブルーグリーンデプロイメントが実現可能か
可能です。Container Apps を マルチリビジョンモード で作成し、リビジョンとトラフィックの重み、リビジョンラベルを活用することで実現できます。
ブルーグリーンデプロイメントの前後でイングレスは変更されるか
変更されない。Container Apps の FQDN とラベルによるトラフィックの重みづけにより、ブルーグリーンデプロイメント前後でイングレスは変更されません。
補足として、ラベルが付与された任意のリビジョンにアクセスする場合には、ラベル URL またはリビジョン URL を使用することで指定のリビジョンにアクセスすることができます。
また、ブルーグリーンデプロイメント時にラベル URL を使用することは、ラベル URL のサポートされるシナリオに含まれています。
ダークカナリアリリースを行うためにフロントドアの配信元グループは2つ必要か
必要です。Front Door の標準機能では、配信元レベルでの IP アドレスに基づくトラフィック制御は直接行えないため、カスタムルールと配信元グループのオーバーライド機能を利用する必要があります。





![Microsoft Power BI [実践] 入門 ―― BI初心者でもすぐできる! リアルタイム分析・可視化の手引きとリファレンス](/assets/img/banner-power-bi.c9bd875.png)
![Microsoft Power Apps ローコード開発[実践]入門――ノンプログラマーにやさしいアプリ開発の手引きとリファレンス](/assets/img/banner-powerplatform-2.213ebee.png)
![Microsoft PowerPlatformローコード開発[活用]入門 ――現場で使える業務アプリのレシピ集](/assets/img/banner-powerplatform-1.a01c0c2.png)


