.NET や Next.js のアプリケーションを Azure へ載せる方法は、この数年でかなり整理されました。ホスティングの選択肢が増えた一方で、CI/CD はキーレス(OIDC)が標準となり、構成は IaC で管理し、認証情報はマネージド ID で扱うという型がほぼ定まっています。本稿では、2026 年時点で実務に耐える構成を前提に、ホスティングの選び方から GitHub Actions によるデプロイ、デプロイスロット、Bicep、監視、コストまでを一通り整理します。サンプルは az CLI と GitHub Actions を中心に、そのまま応用できる形で示します。
ホスティングの選択肢と選び方
Azure でアプリを動かす基盤は用途ごとに分かれています。まずはそれぞれの守備範囲を押さえると、迷いが少なくなります。
- App Service — .NET の Web API や MVC/Blazor、あるいは Node ランタイムの Next.js を素直に動かせる PaaS。運用がシンプルで、デプロイスロットや自動スケールが標準で使える。既存アプリの移行先として第一候補になりやすい。
- Azure Container Apps — コンテナ前提で、マイクロサービスやバックグラウンド処理、ゼロスケールを含む従量課金を求めるワークロードに向く。Dapr や KEDA によるイベント駆動スケールを組み込みやすい。
- Static Web Apps — 静的書き出しやハイブリッドな Next.js フロントエンドと、軽量な API を一体で配信する構成に適する。グローバル CDN とプレビュー環境が付いてくる。
- Azure Functions — HTTP エンドポイントやキュー・タイマー起点の単発処理に向く。フルの Web アプリというより、イベント処理やグルー的な API を切り出す用途で効く。
選び方の目安を挙げます。従来型の .NET Web アプリをまず安定して動かしたいなら App Service、コンテナ化済みで細かくスケールさせたいなら Container Apps、フロントエンド主体で API が薄いなら Static Web Apps、単機能のイベント処理なら Functions という順で検討すると整理しやすくなります。1 つに寄せる必要はなく、Next.js フロントを Static Web Apps、.NET API を Container Apps に置くといった組み合わせも一般的です。

GitHub Actions での CI/CD をキーレスにする
デプロイの起点は GitHub Actions で組むのが標準です。ここで重要なのは、発行プロファイルやサービスプリンシパルのシークレットをリポジトリに置かないことです。現在は OIDC のフェデレーション資格情報を使い、GitHub のワークフローが実行時に短命トークンを取得してサインインする方式が推奨されます。長期シークレットの管理と漏洩リスクが不要になります。
まず Microsoft Entra ID にアプリを登録し、GitHub リポジトリのブランチに対するフェデレーション資格情報を作成します。
# アプリ登録とサービスプリンシパルを作成
az ad app create --display-name "gh-deploy-myapp"
APP_ID=$(az ad app list --display-name "gh-deploy-myapp" --query "[0].appId" -o tsv)
az ad sp create --id "$APP_ID"
# main ブランチからの実行を信頼するフェデレーション資格情報を追加
az ad app federated-credential create --id "$APP_ID" --parameters '{
"name": "gh-main",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:my-org/my-repo:ref:refs/heads/main",
"audiences": ["api://AzureADTokenExchange"]
}'
# デプロイ先リソースグループにロールを付与
az role assignment create --assignee "$APP_ID" \
--role "Contributor" \
--scope "/subscriptions/$SUB_ID/resourceGroups/rg-myapp"
クライアント ID・テナント ID・サブスクリプション ID は機密ではないため、リポジトリ変数として登録すれば十分です。ワークフローは次のようになります。permissions の id-token: write が OIDC トークン発行の要点です。
name: deploy
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: Publish
run: dotnet publish ./src/Api -c Release -o ./publish
- name: Azure login (OIDC)
uses: azure/login@v2
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: Deploy to App Service (staging slot)
uses: azure/webapps-deploy@v3
with:
app-name: app-myapp
slot-name: staging
package: ./publish
Next.js 側も同じ流れで、ビルド成果物を Static Web Apps や App Service に配置します。Static Web Apps ではデプロイトークンを使う方式もありますが、Azure リソースへ直接触れる処理は OIDC ログインに寄せておくと、認証情報の管理箇所を一元化できます。
デプロイスロットとブルーグリーン
本番へ直接上書きするデプロイは、切り戻しが難しく、起動直後の不安定な状態を利用者に見せてしまいます。App Service のデプロイスロットを使うと、この問題をブルーグリーン方式で回避できます。新バージョンをステージングスロットに配置し、ウォームアップが済んでから本番スロットと入れ替えます。入れ替えは瞬時に切り替わり、問題があれば再度スワップして元に戻せます。
# ステージングスロットを作成(初回のみ)
az webapp deployment slot create \
--name app-myapp --resource-group rg-myapp --slot staging
# 検証後、ステージングを本番へスワップ
az webapp deployment slot swap \
--name app-myapp --resource-group rg-myapp \
--slot staging --target-slot production
スワップ前に稼働確認を挟むと安全性が高まります。App Service のヘルスチェックを設定し、ステージングスロットのエンドポイントを CI から叩いて 200 応答を確認してからスワップするワークフローが実務的です。スロット単位で設定を固定したい接続文字列などは、スロット設定としてスワップ対象から外しておきます。Container Apps ではリビジョンとトラフィック分割で同等のことを実現でき、新リビジョンへ段階的に比率を移すカナリアリリースも可能です。
Bicep による構成管理
ポータルでの手作業は再現性がなく、環境差異の温床になります。インフラはコードで定義し、リポジトリで管理します。Azure ネイティブなら Bicep が扱いやすく、App Service とプランを次のように記述できます。
param location string = resourceGroup().location
param appName string
resource plan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: '${appName}-plan'
location: location
sku: { name: 'P1v3', tier: 'PremiumV3' }
}
resource site 'Microsoft.Web/sites@2023-12-01' = {
name: appName
location: location
identity: { type: 'SystemAssigned' }
properties: {
serverFarmId: plan.id
httpsOnly: true
siteConfig: {
netFrameworkVersion: 'v9.0'
healthCheckPath: '/healthz'
}
}
}
デプロイは what-if で差分を確認してから適用すると、想定外の変更を防げます。この what-if 実行を CI に組み込み、プルリクエスト時点で影響範囲をレビューできるようにするのが望ましい形です。
# 差分を確認
az deployment group what-if \
--resource-group rg-myapp \
--template-file main.bicep --parameters appName=app-myapp
# 適用
az deployment group create \
--resource-group rg-myapp \
--template-file main.bicep --parameters appName=app-myapp
マネージド ID・シークレット・監視
データベースや Storage、他サービスへの接続に、接続文字列やキーをアプリ設定へ直書きするのは避けたい構成です。App Service や Container Apps にマネージド ID を割り当て、対象リソースへ RBAC でロールを付与すれば、コード側は資格情報を持たずにアクセストークンを取得できます。どうしても文字列のシークレットが必要な場合は Key Vault に格納し、アプリ設定から Key Vault 参照で解決します。
# アプリのマネージド ID に Key Vault の読み取り権限を付与
PRINCIPAL_ID=$(az webapp identity show \
--name app-myapp --resource-group rg-myapp --query principalId -o tsv)
az role assignment create --assignee "$PRINCIPAL_ID" \
--role "Key Vault Secrets User" \
--scope $(az keyvault show --name kv-myapp --query id -o tsv)
# アプリ設定を Key Vault 参照で登録(値は Vault 側に保持)
az webapp config appsettings set \
--name app-myapp --resource-group rg-myapp \
--settings "Db__Password=@Microsoft.KeyVault(SecretUri=https://kv-myapp.vault.azure.net/secrets/db-password/)"
監視は Application Insights と Log Analytics を土台にします。.NET なら OpenTelemetry ベースの Azure Monitor ディストリビューションを組み込むと、リクエスト・依存関係・例外が自動的に収集されます。接続文字列はマネージド ID か Key Vault 経由で渡します。
// Program.cs
builder.Services.AddOpenTelemetry().UseAzureMonitor();
収集したテレメトリは Log Analytics ワークスペースに集約され、KQL で横断的に分析できます。エラー率やレイテンシに対してアラートを設定し、デプロイ直後の異常を早期に検知できるようにしておくと、スロットのスワップ判断にも使えます。
コストとスケールの考え方
基盤ごとに課金モデルが異なるため、トラフィックの性質に合わせて選ぶとコストが最適化されます。常時一定の負荷があるなら App Service の固定プランが読みやすく、リクエストに波があるなら Container Apps や Functions の従量課金・ゼロスケールが効きます。フロントエンドの静的配信は Static Web Apps に寄せると、CDN コストを抑えつつ低レイテンシを確保できます。
スケール設定は指標に基づいて自動化します。App Service では CPU やキュー長を条件にスケールアウトのルールを組み、Container Apps では KEDA によりキューメッセージ数や HTTP 同時実行数に応じてレプリカを増減させます。過剰なスケールアウトはコスト増に直結するため、上限レプリカ数と最小レプリカ数を明示し、負荷試験で実際の必要量を把握してから設定するのが堅実です。開発・ステージング環境は夜間や休日に縮退させることでも無駄を減らせます。まずは小さめの構成で始め、監視データを見ながら段階的に調整する進め方が、過剰投資も性能不足も避けやすくなります。
エンハンスド株式会社では、.NET / Next.js アプリケーションの Azure 移行と、デプロイ基盤の構築を支援しています。ホスティングの選定から OIDC ベースの CI/CD、Bicep による構成管理、マネージド ID と監視の整備まで、既存の運用体制に合わせて設計・実装します。クラウド移行やデプロイ自動化の見直しをご検討の際は、現状の構成整理からお気軽にご相談ください。
このテーマの全体像は .NET モダナイゼーション完全ガイド にまとめています。
この記事をシェア
関連記事

Azure Container Appsで構築するマイクロサービスの実務ガイド
マイクロサービスをコンテナで運用したいものの、Kubernetes クラスターの構築と保守までは抱え込みたくない。こうした要望に応えるのが Azure Container Apps(ACA)です。…

Azure Bicepで実践するInfrastructure as Code
Azure 上のインフラを手作業で構築・変更する運用は、環境ごとの差分や設定ミス、担当者の暗黙知への依存といった問題を抱えがちです。Infrastructure as Code(IaC)は、…

.NET Modernization for Beginners とは — Copilot でレガシー .NET を .NET 10 へ引き上げる無料コース
Microsoft は 2026 年 7 月 16 日、 .NET Modernization for Beginners という無償の学習コースを公開しました。…
