🎼

Azure Container Apps でカナリアリリースっぽいことをやってみる

2025/02/24に公開

Microsoft のコミュニティブログにて、Azure Container Apps (ACA) にて Feature Flag / カナリアリリースっぽいことをやる記事が出ていました。

少し試してみていたのですが、色々と動かない箇所・誤りがありましたので、補足を加えつつまとめてみました。なお、後述の手順はすべて Azure Cloud Shell 上で実施しています。

お試し手順

Azure Container Registory の準備

まず、適当なリソースグループと Azure Container Registory (ACR) は作成しておきます。

また、アプリケーションの準備として、こちらの Dockerfile, app.js, package.json をダウンロードしておきます。

Staging 用のコンテナイメージを作る

そのままの app.js は Staging 用のコードとなっています。Azure Cloud Shell では Docker が無い…のですが、az acr build コマンドを利用することで Azure Cloud Shell 上でもコンテナイメージのビルド~プッシュを行うことができます。下記のコマンドでコンテナイメージのビルドとプッシュをすれば OK です。

az acr build --image my-container-app:v2 \
  --registry <ACR_Name> --file Dockerfile .

Production 用のコンテナイメージを作る

app.js の下記の箇所を修正します。前半のコメントアウトを外し、後半をコメントアウトしています。

app.js
//for production
const featureFlag = process.env.FEATURE_FLAG || 'false'; 

//for staging
//const featureFlag = process.env.FEATURE_FLAG || 'true';

その上で、コンテナイメージのビルドとプッシュをしましょう。

az acr build --image my-container-app:v1 \
  --registry <ACR_Name> --file Dockerfile .

Container Apps 環境 (Environment) を作成する

元ブログでは、このまま ACA へデプロイする流れになっていますが、まずは Container Apps 環境 (Environment) を作成する必要があります。下記のコマンドで Container Apps 環境を作成しておきます。

az containerapp env create -n <CAE_Name> \
  -g <RG_Name> --location japaneast

また、ACR との連携で Managed ID を利用するため、そちらも作成しておきます。

IDENTITY="mid-aca-fflag"
az identity create --name $IDENTITY --resource-group <RG_Name>
IDENTITY_ID=$(az identity show --name $IDENTITY --resource-group <RG_Name> --query id --output tsv)

ACA へデプロイする (Production)

Production 用のアプリを作成していきましょう。下記のコマンドを実行してデプロイします。なお、元の記事の --name は、多分誤りです。その他、いくつかのオプションを加えています。

az containerapp create \
  --name my-container-app \
  --resource-group <RG_Name> \
  --environment <CAE_Name> \
  --registry-server <ACR_Name>.azurecr.io\
  --image <ACR_Name>.azurecr.io/my-container-app:v1 \
  --user-assigned "$IDENTITY_ID" \
  --registry-identity "$IDENTITY_ID" \
  --cpu 0.5 --memory 1Gi \
  --target-port 8080 \
  --ingress 'external' \
  --revision-suffix version1 \
  --revisions-mode multiple

この後で新しいリビジョンをデプロイしますが、その際に古いリビジョンにトラフィックが流れるようにしたいため、一旦トラフィックが 100% 流れるように設定しておきます (参考記事)。

az containerapp ingress traffic set \
  --name my-container-app \
  --resource-group <RG_Name> \
  --revision-weight my-container-app--version1=100

このタイミングで ACA へアクセスすると、「Feature is disabled.」というページが表示されると思います。

ACA へデプロイする (Staging)

Staging 用のアプリを下記のコマンドを実行して追加デプロイします。こちらも、元の記事の --name はおそらく誤りです。

az containerapp update \
  --name my-container-app \
  --resource-group <RG_Name> \
  --image <ACR_Name>.azurecr.io/my-container-app:v2 \
  --cpu 0.5 --memory 1Gi \
  --revision-suffix version2

各リビジョンにラベルをつける

下記のコマンドで、それぞれにリビジョンにラベルを付与しておきます。元の記事の --revision および --label は誤りですね…。

az containerapp revision label add \
  --name my-container-app \
  --resource-group <RG_Name> \
  --revision my-container-app--version1 \
  --label production

az containerapp revision label add \
  --name my-container-app-2 \
  --resource-group <RG_Name> \
  --revision my-container-app--version2 \
  --label staging

トラフィックの割合を変更する

カナリアリリースっぽく、ステージング環境に10%だけトラフィックが流れるようにしてみます。

az containerapp ingress traffic set \
  --name my-container-app \
  --resource-group <RG_Name> \
  --label-weight production=90 staging=10

設定後、ブラウザからアプリへアクセスして更新ボタンをポチポチすると、「Feature is enabled!」が表示される時があることを確認できると思います。大丈夫そうですね!

おわりに

ということで、Azure Container Apps で Feature Flag とカナリアリリースっぽいことを試してみました。

カチっとした実運用では、もう少しアフィニティ等の考慮や工夫が必要になる場合もありそうですが、まずは深く考えなくても楽にこういうデプロイができるのは嬉しいですね!

Discussion