GitHub ActionsでAzure Container Appsへデプロイする際の要点は、GitHubリポジトリへのコミットをきっかけにコンテナーイメージを更新し、その更新イメージを基にAzure Container Appsの新しいリビジョンを発行できることです。開発者はワークフローYAMLとイメージタグ、管理者はAzure認証・レジストリ認証・リビジョンモードを確認する必要があります。Microsoft Learnでは、特定ブランチへのコミットでワークフローが起動し、コンテナーレジストリ内のイメージ更新後に新しいリビジョンが作成される流れが説明されています。(Microsoft Learn)
特に注意したいのは、latestのような固定タグで運用しないこと、Azure Container RegistryではマネージドIDとAcrPullロールを基本にすること、GitHub Actions側のAzure認証をシークレット方式のまま放置しないことです。既存のCI/CDをそのまま移すだけでは、意図しない本番デプロイ、古いイメージの再利用、リビジョン切り替え時の混乱が起きやすくなります。
なお、Microsoft Learnの日本語ページ上では最終更新日が2025年5月20日と表示されています。2026年5月時点でこの情報を確認する場合も、記事の日付だけで判断せず、公式ページ本文、GitHub MarketplaceのActionバージョン、利用中のワークフロー設定をあわせて確認してください。(Microsoft Learn)
GitHub ActionsでAzure Container Appsのリビジョン公開は何が変わるのか
今回のポイントは、Azure Container Appsへのデプロイを「Azure PortalやCLIで手動更新する作業」から「GitHubリポジトリを起点にした継続的デプロイ」へ寄せられることです。
Azure Container Appsでは、コンテナーアプリの変更履歴をリビジョンとして扱います。リビジョンはアプリの各バージョンのスナップショットであり、コンテナーイメージやスケール設定などリビジョンスコープの変更があると新しいリビジョンが作成されます。(Microsoft Learn)
GitHub Actionsを使うと、次の流れを自動化できます。
GitHubへpush
↓
GitHub Actionsワークフローが起動
↓
コンテナーイメージをビルドまたは既存イメージを指定
↓
レジストリへpush、またはレジストリ上のイメージを参照
↓
Azure Container Appsへデプロイ
↓
新しいリビジョンが作成される
この仕組みにより、開発チームは「どのコミットが、どのリビジョンとして本番またはステージングに反映されたか」を追跡しやすくなります。一方で、ワークフローのトリガーや認証設定を誤ると、意図しないブランチからのデプロイや、権限過多のサービスプリンシパル運用につながります。
対応するデプロイパターン
azure/container-apps-deploy-actionは、Azure Container Appsへビルドとデプロイを行う公式Actionです。Microsoft Learnでは、Dockerfileからのビルド、Dockerfileなしのソースコードビルド、既存コンテナーイメージのデプロイがサポート対象として整理されています。(Microsoft Learn)
| デプロイパターン | 主な指定項目 | 向いているケース | 注意点 |
|---|---|---|---|
| Dockerfileからビルド | appSourcePath、必要に応じてdockerfilePath | Dockerfileでビルド手順を明確に管理したい | Dockerfileのパス、ビルド引数、ベースイメージ更新を管理する |
| ソースコードからビルド | appSourcePath | .NET、Java、Node.js、PHP、Pythonなどで簡単に始めたい | ビルド挙動を細かく制御したい場合はDockerfileを用意する |
| 既存イメージをデプロイ | imageToDeploy | 別ジョブでテスト済みイメージを作り、デプロイだけ分けたい | latestではなく${{ github.sha }}など一意のタグを使う |
実務では、最初から本番用ワークフローを複雑にしすぎないことが大切です。小規模なAPIや検証環境では「ソースコードからビルド」で始めてもよいですが、本番ではDockerfileまたは既存イメージ方式のほうが再現性を確保しやすくなります。
既存環境への影響範囲
GitHub ActionsからAzure Container Appsへリビジョンを発行する運用に変えると、影響は開発者だけでなく、Azure管理者、セキュリティ担当、運用担当にも及びます。
| 対象者 | 影響するポイント | 確認すべきこと |
|---|---|---|
| 開発者 | pushやmergeがデプロイにつながる | 対象ブランチ、ワークフローの発火条件、イメージタグ |
| Azure管理者 | Container Apps、ACR、マネージドID、RBACが関係する | AcrPullロール、リソースグループ範囲、サービスプリンシパルまたはOIDC |
| セキュリティ担当 | GitHub SecretsやPATの扱いが増える | シークレットの最小化、OIDC利用、PATのスコープ |
| 運用担当 | リビジョン管理とロールバック手順が重要になる | 単一リビジョンか複数リビジョンか、トラフィック分割、監視 |
特に本番環境では、「mainブランチにpushされたら即デプロイ」でよいとは限りません。GitHub Environmentsの承認、ブランチ保護、Pull Requestレビュー、ステージング環境での事前検証を組み合わせるべきです。
管理者が最初に確認すべき設定
Azure Container RegistryのPull権限
Azure Container AppsがACRからイメージを取得するには、Container Apps側にもレジストリからPullする権限が必要です。Microsoft Learnでは、マネージドIDを有効化し、そのIDにACRのAcrPullロールを割り当てる構成が案内されています。(Microsoft Learn)
確認すべきコマンド例は次のとおりです。
az containerapp identity assign \
--name my-container-app \
--resource-group my-container-app-rg \
--system-assigned
az role assignment create \
--assignee <MANAGED_IDENTITY_PRINCIPAL_ID> \
--role AcrPull \
--scope <ACR_RESOURCE_ID>
az containerapp registry set \
--name my-container-app \
--resource-group my-container-app-rg \
--server <ACR_NAME>.azurecr.io \
--identity system
ここで失敗しやすいのは、GitHub Actions側の認証だけを設定して満足してしまうことです。GitHub Actionsがイメージをpushできても、Container Appsがそのイメージをpullできなければ新しいリビジョンは正常に起動しません。
GitHub ActionsからAzureへの認証
Microsoft Learnのサンプルでは、AZURE_CREDENTIALSというGitHub SecretにサービスプリンシパルのJSON認証情報を保存し、azure/loginで認証する例が示されています。(Microsoft Learn)
ただし、現在の運用ではOpenID Connect、つまりOIDCの利用を優先して検討すべきです。Azure/loginの公式READMEでは、Azure Login ActionがOIDC、サービスプリンシパルシークレット、マネージドIDによる認証をサポートし、セキュリティ強化のためOIDCベース認証を推奨しています。(GitHub)
OIDCを使う場合、GitHub Actionsのワークフローにはid-token: write権限が必要です。この権限はAzureリソースへの書き込み権限そのものではなく、OIDCトークンを要求するための権限です。(GitHub Docs)
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Log in to Azure
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
すでにAZURE_CREDENTIALSで動いている環境をすぐ止める必要はありません。しかし、新規構築や本番ワークフローの見直しでは、長期シークレットをGitHubに置き続けるより、フェデレーション資格情報を使う構成へ移行するほうが安全です。
Actionのバージョン固定
Microsoft Learnのサンプルではazure/container-apps-deploy-action@v1が使われています。一方、GitHub Marketplace上ではAzure Container Apps Build and DeployのLatestがv2として表示されています。(Microsoft Learn) (GitHub)
ここで重要なのは、単純に「新しいからv2へ置き換える」ことではありません。次の方針で管理してください。
| 方針 | 理由 |
|---|---|
@mainのような浮動指定は避ける | 予期しない変更で本番デプロイが壊れる可能性がある |
@v1または@v2などメジャーバージョンを固定する | 大きな破壊的変更を避けやすい |
| 重要環境ではコミットSHA固定も検討する | サプライチェーンリスクを下げやすい |
| バージョン変更時はステージングで検証する | 引数やビルド挙動の違いを確認できる |
本番環境では、Actionのバージョン更新もアプリケーションのリリースと同じく変更管理の対象にすべきです。
開発者が確認すべきワークフローYAMLのポイント
最小構成の例は次のようになります。Actionのバージョンは、組織で検証済みのものに固定してください。
name: Deploy to Azure Container Apps
on:
push:
branches:
- main
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Log in to Azure
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Build and deploy Container App
uses: azure/container-apps-deploy-action@v2
with:
appSourcePath: ${{ github.workspace }}/src
acrName: ${{ vars.ACR_NAME }}
containerAppName: ${{ vars.CONTAINER_APP_NAME }}
resourceGroup: ${{ vars.RESOURCE_GROUP }}
この例ではmainブランチへのpushでデプロイされます。実務では、本番用と検証用でブランチやEnvironmentを分けることが多くなります。
on:
push:
branches:
- main
- develop
ただし、複数ブランチを同じワークフローで扱う場合は、どのブランチがどのAzureリソースへデプロイされるかを明確にしてください。developの変更が本番Container Appへ反映されるような設定ミスは、CI/CD移行時によくある事故です。
既存イメージをデプロイする場合はタグ設計が最重要
別ジョブや別ワークフローでコンテナーイメージをビルドしている場合は、imageToDeployで既存イメージを指定します。
- name: Deploy existing image
uses: azure/container-apps-deploy-action@v2
with:
containerAppName: ${{ vars.CONTAINER_APP_NAME }}
resourceGroup: ${{ vars.RESOURCE_GROUP }}
imageToDeploy: ${{ vars.ACR_LOGIN_SERVER }}/my-api:${{ github.sha }}
ここでlatestを使うのは避けてください。Microsoft Learnでも、別ステップでイメージをビルドする場合はlatestのような安定タグではなく、コミットSHAなど一意のタグを使うよう注意されています。GHCRの説明でも、一意のタグはキャッシュ問題の回避と新しいリビジョン作成の信頼性向上に役立つとされています。(Microsoft Learn)
悪い例です。
imageToDeploy: myregistry.azurecr.io/my-api:latest
よい例です。
imageToDeploy: myregistry.azurecr.io/my-api:${{ github.sha }}
さらに運用しやすくするなら、短いコミットSHA、ビルド番号、リリース番号を組み合わせます。
imageToDeploy: myregistry.azurecr.io/my-api:${{ github.run_number }}-${{ github.sha }}
イメージタグは、後から障害調査やロールバックを行うときの手がかりになります。「どのリビジョンがどのソースコードに対応しているか」を人間が追える形にしておくことが重要です。
GHCRなどACR以外のレジストリを使う場合の注意点
Azure Container Appsは、Azure Container Registryだけでなく、GitHub Container Registry、つまりGHCRなどのレジストリ上のイメージも扱えます。Microsoft Learnでは、ACR以外のレジストリを使う場合、パブリックイメージであってもContainer App側にレジストリ設定が必要だと説明されています。(Microsoft Learn)
パブリックGHCRイメージを使う例です。
- name: Deploy public GHCR image to Container App
uses: azure/container-apps-deploy-action@v2
with:
containerAppName: my-container-app
resourceGroup: my-container-app-rg
imageToDeploy: ghcr.io/<YOUR-GITHUB-USERNAME>/myimage:${{ github.sha }}
registryUrl: ghcr.io
Container App側にもレジストリを設定します。
az containerapp registry set \
--name my-container-app \
--resource-group my-container-app-rg \
--server ghcr.io
プライベートGHCRイメージの場合は、read:packagesスコープを持つGitHub Personal Access Tokenを使い、ユーザー名とトークンをGitHub Secretsに保存します。(Microsoft Learn)
- name: Deploy private GHCR image to Container App
uses: azure/container-apps-deploy-action@v2
with:
containerAppName: my-container-app
resourceGroup: my-container-app-rg
imageToDeploy: ghcr.io/<YOUR-GITHUB-USERNAME>/myimage:${{ github.sha }}
registryUrl: ghcr.io
registryUsername: ${{ secrets.GHCR_USERNAME }}
registryPassword: ${{ secrets.GHCR_TOKEN }}
ただし、PATは漏えい時の影響が大きいため、不要になったら削除し、必要最小限のスコープで作成し、定期的に棚卸ししてください。
リビジョンモードは本番展開の運用方針で選ぶ
Azure Container Appsのリビジョンモードは、デプロイ後のトラフィック制御に直結します。Microsoft Learnでは、単一リビジョン、複数リビジョン、展開ラベルの考え方が説明されています。単一リビジョンでは新しいリビジョンの準備ができるまで既存リビジョンがトラフィックを受け続け、複数リビジョンではトラフィック分割や手動制御が可能です。(Microsoft Learn)
| リビジョンモード | 向いているケース | 運用上の注意点 |
|---|---|---|
| 単一リビジョン | シンプルなWeb API、社内ツール、小規模サービス | 段階的リリースやA/Bテストには向かない |
| 複数リビジョン | 本番での段階的リリース、ブルーグリーン、A/Bテスト | トラフィック配分、古いリビジョン整理、ロールバック手順が必要 |
| 展開ラベル | 特定リビジョンへわかりやすいURLでアクセスしたい | プレビュー扱いの機能は本番採用前に公式情報を確認する |
ブルーグリーンデプロイを行う場合は、configuration.activeRevisionsModeをmultipleにし、template.revisionSuffixにビルド番号やGitコミットの短いハッシュなど、リリースを識別できる値を使う構成が案内されています。(Microsoft Learn)
本番で安全に使うには、次のような段階を踏むとよいでしょう。
新リビジョンを作成
↓
ヘルスチェックとログ確認
↓
一部トラフィックを新リビジョンへ振り分け
↓
エラー率、応答時間、ビジネス指標を確認
↓
問題なければ100%切り替え
↓
旧リビジョンを一定期間残してから整理
リビジョンを作れることと、安全にリリースできることは別です。GitHub Actionsで自動化するほど、切り戻し手順も明文化しておく必要があります。
移行前チェックリスト
GitHub ActionsからAzure Container Appsへリビジョンを発行する前に、次の項目を確認してください。
| チェック項目 | 確認内容 |
|---|---|
| デプロイ対象ブランチ | main、develop、releaseブランチなど、環境ごとに分けているか |
| GitHub Environments | 本番デプロイに承認フローを入れるか |
| Azure認証 | サービスプリンシパルシークレットか、OIDCか |
| Azure RBAC | Contributorを広く付けすぎていないか |
| ACR Pull権限 | Container AppのマネージドIDにAcrPullがあるか |
| レジストリ設定 | ACR、GHCR、Docker Hubなどの接続設定が済んでいるか |
| イメージタグ | latestではなくコミットSHAなど一意のタグか |
| Actionバージョン | @mainではなく検証済みバージョンに固定しているか |
| リビジョンモード | 単一か複数か、運用方針と一致しているか |
| ロールバック | 失敗時に旧リビジョンへ戻す手順があるか |
| 監視 | 新リビジョンの起動失敗、エラー率、レスポンス悪化を検知できるか |
このチェックリストを満たさずに本番デプロイを自動化すると、「ワークフローは成功したのにアプリが起動しない」「リビジョンは増えているが想定したイメージではない」「誰が本番へ反映したか追跡できない」といった問題が起きやすくなります。
よくある失敗と対策
| 失敗例 | 原因 | 対策 |
|---|---|---|
| 新しいコードをpushしたのに古い動作のまま | latestタグを再利用している | ${{ github.sha }}など一意のタグを使う |
| デプロイは成功したがリビジョンが起動しない | Container Appがレジストリからpullできない | マネージドID、AcrPull、az containerapp registry setを確認 |
| 想定外のブランチから本番へ反映された | on.push.branchesやEnvironment設定が甘い | 本番用ブランチと承認フローを明確にする |
| GHCRのパブリックイメージが使えない | Container App側のレジストリ設定がない | registryUrlとaz containerapp registry set --server ghcr.ioを確認 |
| ビルド結果が環境ごとに変わる | Dockerfileなしビルドに依存している | 本番ではDockerfileを用意して再現性を高める |
| Action更新後に突然失敗した | バージョンを固定していない | メジャーバージョンまたはコミットSHAで固定する |
| サービスプリンシパルの権限が広すぎる | サブスクリプション全体にContributorを付与 | リソースグループ単位など必要最小限にする |
特に多いのは、Azure側の権限とGitHub側の権限を混同するケースです。GitHub ActionsがAzureへログインできること、レジストリへpushできること、Container Appsがpullできることは、それぞれ別の確認項目です。
本番運用でおすすめの構成
小規模な検証では、Microsoft Learnのサンプルに近い構成でも始められます。ただし、本番では次の構成を基本にすると安全です。
| 項目 | 推奨構成 |
|---|---|
| Azure認証 | OIDCを使ったazure/login |
| レジストリ | ACRを基本にし、Container AppはマネージドIDでPull |
| イメージタグ | コミットSHAまたはビルド番号付きタグ |
| Actionバージョン | 検証済みのメジャーバージョンに固定 |
| デプロイ環境 | GitHub Environmentsでstagingとproductionを分離 |
| 本番承認 | production環境に承認者を設定 |
| リビジョン管理 | 単純運用は単一、本格的な段階展開は複数 |
| ロールバック | 旧リビジョンへ戻す手順をRunbook化 |
| 監視 | 起動プローブ、準備プローブ、ログ、メトリックを確認 |
開発速度だけを優先すると、CI/CDはすぐに導入できます。しかし本番では、「誰が」「どのブランチから」「どのイメージを」「どのリビジョンとして」展開したかを追えることが重要です。
まず取るべきアクション
GitHub ActionsでAzure Container Appsのリビジョン公開を始めるなら、最初に既存のデプロイ手順を棚卸ししてください。手動のaz containerapp updateやPortal操作が残っている場合は、それをワークフローに置き換える前に、イメージタグ、レジストリ権限、リビジョンモードを整理します。
次に、ステージング環境で次の順に検証します。
1. GitHub ActionsからAzureへログインできるか
2. イメージをビルドまたは指定できるか
3. レジストリへpushまたは参照できるか
4. Container Appsがイメージをpullできるか
5. 新しいリビジョンが作成されるか
6. 正しいリビジョンへトラフィックが流れるか
7. 失敗時に旧リビジョンへ戻せるか
この順序で確認すれば、問題が起きたときに「GitHub Actionsの問題なのか」「Azure認証の問題なのか」「レジストリPull権限の問題なのか」を切り分けやすくなります。
GitHub ActionsによるAzure Container Appsのリビジョン公開は、正しく設計すればデプロイの再現性と追跡性を大きく高めます。まずはlatestタグの廃止、マネージドIDとAcrPullの確認、OIDC認証への移行検討から始めるのが現実的です。そのうえで、単一リビジョンでシンプルに運用するのか、複数リビジョンで段階的にリリースするのかを、サービスの重要度に合わせて選びましょう。

コメント