このリファレンス アーキテクチャは、App Service Environment (ASE) を使用した一般的なエンタープライズ ワークロードとこのワークロードのセキュリティを強化するためのベスト プラクティスを示します。
このアーキテクチャの参照実装は、GitHub で入手できます。
アーキテクチャ
このアーキテクチャの Visio ファイルをダウンロードします。
ワークフロー
このアーキテクチャの主要なコンポーネントは、App Service Environment です。 ASE は、パブリック IP アドレスのある外部 ASE か、内部ロード バランサー (ILB) に属する内部 IP アドレスがある内部 ASE のいずれかとしてデプロイできます。 このリファレンス アーキテクチャは、ILB ASE とも呼ばれる内部 ASE 内にエンタープライズ Web アプリケーションをデプロイします。 シナリオで次の行為が必要な場合は、ILB ASE を使用します。
- サイト間接続または ExpressRoute でアクセスするクラウドでイントラネット アプリケーションを安全にホストできます。
- WAF デバイスでアプリケーションを保護できます。
- パブリック DNS サーバーに示されていないクラウドでアプリケーションをホストできます。
- インターネットから分離されたバックエンド アプリを作成して、ご使用のフロントエンド アプリを安全に統合できます。
ASE は常に企業の仮想ネットワーク内の自身のサブネットにデプロイする必要があります。これによって、送受信トラフィックを厳しく管理できるようになります。 このサブネット内では、App Service アプリケーションは 1 つ以上の App Service プラン内にデプロイされます。これは、アプリケーションを実行するために必要な物理的なリソースの集合です。 複雑さやリソース要件に応じて、App Service プランを複数のアプリケーション間で共有できます。 このリファレンス実装では、プライベート API および関数と相互に作用する Voting App という名前の Web アプリをデプロイします。 また、複数のアプリケーションのデプロイを実施するための Test App という名前のダミーの Web アプリケーションもデプロイします。 App Service アプリケーションはそれぞれ自身の App Service プランにホストされ、必要に応じて、それぞれ個別にスケールできます。 スケーリングのニーズや、ストレージやコンピューティングなど、これらのホストされたアプリケーションが必要とするすべてのリソースは、App Service Environment インフラストラクチャによって完全に管理されます。
この実装における簡単な投票アプリケーションを使用すると、ユーザーは既存のエントリに投票するだけでなく、既存のエントリを表示するか、または新しいエントリを作成できます。 エントリや投票の作成や取得には、Web API が使用されます。 データ自体は、SQL Server データベースに格納されます。 非同期データ更新を実施するために、Web アプリは、Service Bus インスタンス内に新たに追加された票を待ち行列に入れます。 この関数は、待ち行列に入った票を選び、SQL データベースを更新します。 Web アプリでブラウザーに表示するために取得するモックアップ広告の格納には、Azure Cosmos DB が使用されます。 アプリケーションは、Azure Cache for Redis を使用して、キャッシュ管理を行います。 自身のサブネットで ASE と同じ仮想ネットワークへの設定を可能にする、Premium レベルの Azure Cache for Redis が使用されます。 これによって、セキュリティが強化され、キャッシュから隔離されます。
Web アプリケーションは、Application Gateway を介してインターネットにアクセスできる唯一のコンポーネントです。 インターネット クライアントからは API と関数にはアクセスできません。 受信トラフィックは、Application Gateway で設定された Web Application Firewall によって保護されます。
コンポーネント
次のサービスは、このアーキテクチャで ASE をロックダウンする上で重要です。
Azure Virtual Network または VNet は、企業が所有するプライベートの Azure クラウド ネットワークです。 ネットワークベースのセキュリティと分離を提供します。 ASE は、企業所有の VNet のサブネットへの App Service デプロイです。 これにより、ネットワーク セキュリティ グループとサービス エンドポイントを使用して、企業はネットワーク空間とそれにアクセスするリソースを厳密に制御できるようになります。
Application Gateway は、アプリケーションレベルの Web トラフィック ロードバランサー、TLS/SSL オフロード、Web アプリケーション ファイアウォール (WAF) 保護を備えています。 パブリック IP アドレスでリッスンし、ILB ASE のアプリケーション エンドポイントにトラフィックをルーティングします。 これはアプリケーションレベルのルーティングであるため、同じ ILB ASE 内の複数のアプリケーションにトラフィックをルーティングすることができます。 アプリケーション ゲートウェイで複数のサイトがどのようにサポートされているかについては、「Application Gateway の複数サイトのホスト」を参照してください。
Azure Firewall は、Web アプリケーションからの送信トラフィックを制限するために使用されます。 ASE が必要とするサービス エンドポイント チャネルとルート テーブルを通過しない送信トラフィックは、ファイアウォール サブネットに送られます。 サービス エンドポイントは、追跡可能性のためにファイアウォール サブネット上に構成することをお勧めしますが、常に実現できるとは限りません。 たとえば、ASE のインフラストラクチャで ASE サブネットに対するサービス エンドポイントが必要になる場合があります。 わかりやすくするために、このアーキテクチャでは、ASE サブネット上のすべてのサービス エンドポイントを構成します。
Azure Active Directory (Azure AD) は、Azure のリソースとサービスへのアクセス権限とアクセス許可の管理を提供します。 Managed Identities は、自動的に Azure AD によって管理されるサービスやアプリケーションに ID を割り当てます。 これらの ID は、Azure AD 認証をサポートする任意のサービスを認証するために使用できます。 これにより、これらのアプリケーションの資格情報を明示的に構成する必要がなくなります。 このアーキテクチャでは、Web アプリにマネージド ID を割り当てます。
Key Vault には、アプリケーションで必要なシークレットと資格情報が格納されます。 本オプションは、アプリケーションにシークレットを直接格納する場合に使用します。
Azure Pipelines は、このアーキテクチャの継続的インテグレーションと継続的デプロイ機能を提供します。 ASE は仮想ネットワークの内部にあるため、仮想マシンを VNet 内部の ジャンプボックスとして使用して、App Service プランにアプリケーションをデプロイします。 このパイプラインは、VNet の外部にアプリケーションを構築します。 セキュリティを強化し、RDP/SSH 接続をシームレスにするには、最近リリースされた Azure Bastion をジャンプボックスとして使用することをご検討ください。
マルチサイトの構成
この図の Visio ファイルをダウンロードします。
内部 ASE は、HTTP エンドポイントを使用して複数の Web アプリケーションと API をホストできます。 ILB IP は Microsoft Azure Virtual Network 内からしかアクセスできないため、これらのアプリケーションはパブリック インターネットからロックダウンされます。 Application Gateway は、これらのアプリケーションを選択的にインターネットに公開するために使用されます。 ASE は、各 App Service アプリケーションに <default-appName>.<ASE-domain>.appserviceenvironment.net
として既定の URL を割り当てます。 ASE のドメイン名を ASE ILB IP アドレスにマッピングするプライベート DNS ゾーンが作成されます。 これにより、カスタム DNS を使用して VNet 内のアプリケーションにアクセスすることを回避できます。
Application Gateway は、リスナーが、ゲートウェイの IP アドレスへの要求を HTTPS ポートでリッスンするように構成されています。 わかりやすくするために、この実装ではパブリック DNS 名の登録を使用しないため、コンピューター上の localhost ファイルを変更して、任意に選択した URL が Application Gateway の IP にポイントされるようにする必要があります。 わかりやすくするために、リスナーは自己署名証明書を使用してこれらの要求を処理します。 Application Gateway には、App Service アプリケーションの既定の URL ごとにバックエンド プールがあります。 ルーティング規則は、リスナーをバックエンド プールに接続するように構成されています。 ゲートウェイと ASE 間の接続を暗号化するかどうかを決定する HTTP 設定が作成されます。 これらの設定は、バックエンド プールから選択されたホスト名を使用して受信 HTTP ホスト ヘッダーを上書きするためにも使用されます。 この実装では、既定の ASE アプリケーションの URL に対して作成された既定の証明書を使用します。この証明書はゲートウェイによって信頼されています。 要求は、対応するアプリケーションの既定の URL にリダイレクトされます。 VNet にリンクされているプライベート DNS は、この要求を ILB IP に転送します。 次に、ASE は要求された App サービスにこの要求を転送します。 ASE アプリケーション内のすべての HTTP 通信は、プライベート DNS を経由します。 リスナー、バックエンド プール、ルーティング規則、HTTP 設定は、各 ASE アプリケーションの Application Gateway で構成する必要があります。
これらの構成がどのように複数のサイトを許可できるようにするかを理解するには appgw. json と dns. json をご確認ください。 testapp
という名前の Web アプリは、この構成を実施するために作成された空のアプリケーションです。 これらの JSON ファイルには、デプロイ スクリプト deploy_std.shからアクセスします。また、これらのファイルは deploy_ha sh によってもアクセスされます。これは、高可用性マルチサイト ASE デプロイを行うために使用されます。
シナリオの詳細
Azure App Service は、Web アプリケーション、API アプリケーション、関数、モバイル アプリケーションなどの Azure 上の様々なアプリケーションをホストするのに使用される PaaS サービスです。 App Service Environment (ASE) を使用すると、企業は自社の Azure Virtual Network にあるサブネットに App Service アプリをデプロイし、クラウド ワークロードのための分離された、高度にスケーラブルな専用の環境を提供できます。
考慮事項
これらの考慮事項は、ワークロードの品質向上に使用できる一連の基本原則である Azure Well-Architected Framework の要素を組み込んでいます。 詳細については、「Microsoft Azure Well-Architected Framework」を参照してください。
セキュリティ
セキュリティは、重要なデータやシステムの意図的な攻撃や悪用に対する保証を提供します。 詳細については、「セキュリティの重要な要素の概要」を参照してください。
App Service 環境
内部 ASE は、パブリック インターネットから非表示になっている企業の仮想ネットワークにデプロイされます。 これにより、企業は Web API や関数などのバックエンド サービスをネットワーク レベルでロックダウンできます。 HTTP エンドポイントを使用する ASE アプリケーションには、仮想ネットワーク内から ILB 経由でアクセスできます。 Application Gateway は、ILB を介して Web アプリケーションに要求を転送するように構成されています。 Web アプリケーション自体は、ILB を通じて API にアクセスします。 重要なバックエンド コンポーネント、つまり、API と関数 は、実質的にパブリック インターネットからアクセスできません。
既定の証明書は、ASE によって割り当てられた既定のドメイン名について、各 App サービスに対して作成されます。 この証明書は、ゲートウェイとアプリケーションの間のトラフィックのセキュリティを強化することができ、特定のシナリオで必要になる場合があります。 これらの証明書は、クライアントのブラウザに表示されません。Application Gateway で構成されている証明書にのみ対応できます。
Application Gateway
リファレンス実装では、Application Gateway を appgw. json 内にプログラムによって構成します。 ファイル deploy_std.sh は、ゲートウェイをデプロイするときに、この設定を使用します。
az deployment group create --resource-group $RGNAME --template-file templates/appgw.json --parameters vnetName=$VNET_NAME appgwSubnetAddressPrefix=$APPGW_PREFIX appgwApplications=@appgwApps.parameters.json
APPGW_PUBLIC_IP=$(az deployment group show -g $RGNAME -n appgw --query properties.outputs.appGwPublicIpAddress.value -o tsv)
暗号化
Application Gateway での TLS 終了とエンド ツー エンド TLS の概要で説明しているように、Application Gateway は Transport Layer Security (TLS)/Secure Sockets Layer (SSL) を使用して、Web ブラウザからのすべてのトラフィックを暗号化および保護することができます。 暗号化は、次の方法で構成できます。
ゲートウェイで終了した暗号化 この場合のバックエンド プールは、HTTP に対して構成されています。 ゲートウェイで暗号化が停止し、ゲートウェイとアプリケーション サービス間のトラフィックは暗号化されません。 暗号化は CPU を集中的に使用するため、バックエンドで暗号化されていないトラフィックによってパフォーマンスが向上し、証明書の管理が大幅に単純化されます。 これにより、ネットワーク構成のバックエンドがセキュリティで保護されるため、適度なレベルのセキュリティが提供されます。
エンド ツー エンド暗号化 特定のセキュリティやコンプライアンスの要件など、一部のシナリオでは、ゲートウェイとアプリケーションの間でトラフィックを暗号化する必要がある場合があります。 これを行うには、HTTPS 接続を使用し、バックエンド プールで証明書を構成します。
このリファレンス実装では、Application Gateway に自己署名入り証明書を使用します。 運用環境のコードの場合、証明機関によって発行された証明書を使用する必要があります。 サポートされている証明書の種類の一覧の場合、「TLS 終了でサポートされる証明書」をお読みください。 ゲートウェイによって終了される暗号化を作成する方法については、「Azure portal を使用して TLS ターミネーションでアプリケーション ゲートウェイを構成する」を参照してください。 appgw. json 内の次のコード行は、プログラムでこれを構成します。
{
"name": "httpListeners",
"count": "[length(parameters('appgwApplications'))]",
"input": {
"name": "[concat(variables('appgwListenerName'), parameters('appgwApplications')[copyIndex('httpListeners')].name)]",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(variables('appgwId'), '/frontendIPConfigurations/', variables('appgwFrontendName'))]"
},
"frontendPort": {
"id": "[concat(variables('appgwId'), '/frontendPorts/port_443')]"
},
"protocol": "Https",
"sslCertificate": {
"id": "[concat(variables('appgwId'), '/sslCertificates/', variables('appgwSslCertificateName'), parameters('appgwApplications')[copyIndex('httpListeners')].name)]"
},
"hostName": "[parameters('appgwApplications')[copyIndex('httpListeners')].hostName]",
"requireServerNameIndication": true
}
}
},
ASE とゲートウェイ上の Web アプリ間のトラフィックについては、既定の SSL 証明書が使用されます。 この実装のバックエンド プールは、Web アプリケーションに関連付けられている既定のドメイン名で上書きされたホスト名を使用して、HTTPS トラフィックをリダイレクトするように構成されています。 Microsoft によって発行されるため、Application Gateway は、既定の SSL 証明書を信頼します。 これらの構成がどのように行われるかについては、「Application Gateway を使用した App Service の構成」を参照してください。 appgw.json の次の行は、これがリファレンス実装でどのように構成されているかを示しています。
{
"name": "backendHttpSettingsCollection",
"count": "[length(parameters('appgwApplications'))]",
"input": {
"name": "[concat(variables('appgwHttpSettingsName'), parameters('appgwApplications')[copyIndex('backendHttpSettingsCollection')].name)]",
"properties": {
"Port": 443,
"Protocol": "Https",
"cookieBasedAffinity": "Disabled",
"pickHostNameFromBackendAddress": true,
"requestTimeout": 20,
"probe": {
"id": "[concat(variables('appgwId'), '/probes/', variables('appgwHealthProbeName'), parameters('appgwApplications')[copyIndex('backendHttpSettingsCollection')].name)]"
}
}
}
},
Web アプリケーション ファイアウォール
Application Gateway 上の Web アプリケーション ファイアウォール (WAF) は、SQL インジェクションなどの悪意のある攻撃から Web アプリケーションを保護します。 また、リアルタイム ログを使用して攻撃を監視するために、Azure Monitor とも統合されています。 「Azure portal を使用して Web アプリケーション ファイアウォールのあるアプリケーション ゲートウェイを作成する」で説明しているように、WAF をゲートウェイで有効にする必要があります。 リファレンス実装は、次のスニペットを使用して、プログラムによって appgw. json ファイルで WAF を有効にします。
"webApplicationFirewallConfiguration": {
"enabled": true,
"firewallMode": "Detection",
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
},
Virtual Network
ネットワーク セキュリティ グループは、VNet 内の 1 つ以上のサブネットに関連付けることができます。 これらは、様々な Azure リソース間のトラフィック フローを許可または拒否するセキュリティ規則です。 本アーキテクチャでは、サブネットごとに個別の NSG が関連付けられます。 これにより、そのサブネットに含まれるサービスに従って、サブネットごとにこれらの規則を微調整できます。 たとえば、ASE サブネットの NSG の場合は、ファイル ase.json 内、Application Gateway サブネットの NSG の場合は、ファイル appgw.json 内で "type": "Microsoft.Network/networkSecurityGroups"
に対する構成を調査します。
サービス エンドポイントは、VNet のプライベート アドレス空間と ID を Azure サービスをサポートするように拡張し、これらのサービスへのアクセスを VNet のみに制限します。 セキュリティを強化するには、サービス エンドポイントをサポートする任意の Azure サービスに対する ASE サブネットでサービス エンドポイントを有効にする必要があります。 次に、このサービスは、サービスで仮想ネットワーク規則を設定することによって、企業の VNet に対してセキュリティで保護され、パブリック インターネットからのアクセスを効果的にブロックできます。 ASE インフラストラクチャでは、この記事の「システム アーキテクチャ」セクションで説明したように、アーキテクチャ自体が使用できない場合でも、イベント ハブ、SQL Server、ストレージ用のサービス エンドポイントが独自の管理用に設定されます。 このアーキテクチャでは、使用しているサービスに対してサービス エンドポイントが構成されます。このサービス エンドポイントでは、Service Bus、SQL Server、Key Vault、Azure Cosmos DB をサポートします。 この構成を、ase. json で、 "type": "Microsoft.Network/virtualNetworks/subnets"
-->"properties"
-->"serviceEndpoints"
として探索します。
サブネットでサービス エンドポイントを有効にするプロセスは 2 段階です。 リソース自体は、この仮想ネットワークからサービス エンドポイントでトラフィックを受信するように構成する必要があります。 詳細については、「リソースへのネットワークアクセスを制限する」を参照してください。
ファイアウォール
Azure Firewall とサービス エンドポイントは相互に補完します。 サービス エンドポイントは、仮想ネットワークからの受信トラフィックを制限することでリソースを保護しますが、Azure Firewall では、アプリケーションからの送信トラフィックを制限することができます。 サービス エンドポイントのトラフィックを含め、すべての送信トラフィックが、ファイアウォール サブネットを通過するようにすることをお勧めします。 これにより、送信トラフィックの監視が強化されます。 ただし、ASE インフラストラクチャでは、SQL Server、ストレージ、イベント ハブのサービス エンドポイントを ASE サブネットで構成する必要があります。 ファイアウォールの統合に関する説明については、「App Service 環境をロックする」を参照してください。 さらに、この実装では、直接接続モードで Azure Cosmos DB を使用します。このためには、様々なポートを開く必要があります。 これにより、ファイアウォール構成が複雑になる可能性があります。 わかりやすくするために、このリファレンス アーキテクチャでは、ファイアウォール サブネットではなく、ASE サブネット上のすべてのサービス エンドポイントを構成します。 作業の対象には、ASE インフラストラクチャに必要なエンドポイントに加え、Service Bus、Azure Cosmos DB、Key Vault のエンドポイントも含まれます。
ASE にファイアウォールがどのように統合されているかについては、「ASE に合わせて Azure Firewall を構成する」を参照してください。 サービス エンドポイントと仮想ネットワーク ルート テーブルを経由しないトラフィックは、ファイアウォールによって監視およびゲート管理されます。 ルート テーブルの必要性については、次のセクションで説明します。
ASE 管理 IP
ASE 管理トラフィックは、企業の仮想ネットワーク内を通過します。 本トラフィックは、ファイアウォールを回避するために、仮想ネットワークの外部の専用 IP アドレスに直接ルーティングする必要があります。 これを行うには、ユーザー定義の仮想ネットワーク ルート テーブルを作成します。 これらの IP アドレスは、記事「App Service Environment の管理アドレス」に記載されています。 この一覧は、ファイアウォール内で、手動で構成するには時間がかかりすぎる場合があります。 この実装では、これをプログラムによって設定する方法を示します。 deploy_std sh の次の行は、コマンド ライン JSON パーサーである Azure CLI と jq を使用して一覧を取得します。
ENDPOINTS_LIST=$(az rest --method get --uri $ASE_ID/inboundnetworkdependenciesendpoints?api-version=2016-09-01 | jq '.value[0].endpoints | join(", ")' -j)
これは、API から管理アドレスを取得する方法に関するドキュメントに記載されている方法と同じです。
deploy_std.sh の次のコマンドは、network.json で構成されているように、ルート テーブルと共に仮想ネットワークを作成します。
VNET_NAME=$(az network vnet list -g $RGNAME --query "[?contains(addressSpace.addressPrefixes, '${NET_PREFIX}')]" --query [0].name -o tsv)
az deployment group create --resource-group $RGNAME --template-file templates/network.json --parameters existentVnetName=$VNET_NAME vnetAddressPrefix=$NET_PREFIX
VNET_NAME=$(az deployment group show -g $RGNAME -n network --query properties.outputs.vnetName.value -o tsv)
VNET_ROUTE_NAME=$(az deployment group show -g $RGNAME -n network --query properties.outputs.vnetRouteName.value -o tsv)
ASE サブネットが作成されると、ルート テーブルが関連付けられます。
az deployment group create --resource-group $RGNAME --template-file templates/ase.json -n ase --parameters vnetName=$VNET_NAME vnetRouteName=$VNET_ROUTE_NAME aseSubnetAddressPrefix=$ASE_PREFIX
ファイアウォールが作成されると、firewall. json 構成ファイルによって、このルート テーブルが ASE 管理 IP で更新され、その後にファイアウォール IP が適用されます。 これにより、残りのトラフィックがファイアウォール IP を通過します。
{
"variables": {
"firewallSubnetName": "AzureFirewallSubnet",
"firewallPublicIpName": "[concat('firewallIp', '-', uniqueString(resourceGroup().id))]",
"firewallName": "[concat('firewall', '-', uniqueString(resourceGroup().id))]",
"aseManagementEndpoints": "[split(replace(parameters('aseManagementEndpointsList') ,' ', ''), ',')]",
"copy": [
{
"name": "aseManagementIpRoutes",
"count": "[length(variables('aseManagementEndpoints'))]",
"input": {
"name": "[replace(variables('aseManagementEndpoints')[copyIndex('aseManagementIpRoutes')], '/', '-')]",
"properties": {
"addressPrefix": "[variables('aseManagementEndpoints')[copyIndex('aseManagementIpRoutes')]]",
"nextHopType": "Internet"
}
}
}
]
},
"resources": [
{
"type": "Microsoft.Network/routeTables",
"apiVersion": "2019-11-01",
"name": "[parameters('vnetRouteName')]",
"location": "[parameters('location')]",
"tags": {
"displayName": "UDR - Subnet"
},
"dependsOn": [
"[resourceId('Microsoft.Network/azureFirewalls', variables('firewallName'))]"
],
"properties": {
"routes": "[concat(variables('aseManagementIpRoutes'), array(json(concat('{ \"name\": \"Firewall\", \"properties\": { \"addressPrefix\": \"0.0.0.0/0\", \"nextHopType\": \"VirtualAppliance\", \"nextHopIpAddress\": \"', reference(concat('Microsoft.Network/azureFirewalls/', variables('firewallName')),'2019-09-01','Full').properties.ipConfigurations[0].properties.privateIPAddress, '\" } }'))))]"
}
}
...
...
]
...
...
}
ルート テーブルをデプロイした後、管理 IP の一覧が変更される可能性があります。その場合は、このルート テーブルをもう一度デプロイする必要があります。
Azure Active Directory
Azure Active Directory には、アプリケーションを認証、リソースへのアクセスを承認するためのセキュリティ機能が用意されています。 このリファレンス アーキテクチャでは、Azure Active Directory の 2 つの主要機能、マネージド ID と Azure ロールベースのアクセス制御 を使用します。
クラウド アプリケーションを構築するときは、クラウド サービスに対する認証に必要な資格情報をセキュリティで保護する必要があります。 資格情報は、開発者のワークステーションに一切表示されないか、ソース管理でも確認されないことが理想的です。 Azure Key Vault は、資格情報やその他のシークレットを安全に保管する方法を提供しますが、アプリケーションは、Key Vault に対して認証を行い、それらを取得する必要があります。 Azure リソースのマネージド ID は、Azure AD で自動的に管理される ID を Azure サービスに提供します。 この ID を使用すれば、アプリケーションに資格情報を追加しなくても、Key Vault を含む、Azure AD の認証をサポートする様々なサービスに対して認証を行うことができます。
Azure ロールベースのアクセス制御 (Azure RBAC) を使用して、Azure リソースへのアクセスを管理します。 これには次のものが含まれます
- アクセス権を持つエンティティ: ユーザー、管理対象 ID、セキュリティ プリンシパル。
- アクセスの種類: 所有者、共同作成者、読者、閲覧者、管理者。
- アクセスの範囲: リソース、リソース グループ、サブスクリプション、管理グループ。
必要なロールと各アプリケーションへのアクセスの種類を厳密に制御することで、ASE アプリケーションへのアクセスをロックダウンすることができます。 これにより、複数のアプリケーションを異なる開発チームの同じ ASE にデプロイできます。 たとえば、フロントエンドが 1 つのチームによって処理され、バックエンドが別のチームによって処理される場合があります。 Azure RBAC を使用すると、各チームが作業中のアプリケーションのアクセスを制限できます。 Azure カスタム ロールを調べて、組織に適したロールを作成します。
Key Vault
一部のサービスでは、マネージド ID がサポートされていますが、Azure RBAC を使用してアプリケーションの許可を設定しています。 たとえば、Service Bus の組み込みロールと、Azure Cosmos DB での Azure RBAC を参照してください。 共同作成者アクセス権を持つ担当者がこれらのサービスをデプロイできる場合でも、サブスクリプションへの所有者アクセス権を付与する必要があります。 より広範な開発者チームがデプロイ スクリプトを実行できるようにする場合、次善の策としてサービスのネイティブ アクセス制御ポリシーを使用することをお勧めします。
- Service Bus の場合は、Shared Access Signature になります。
- Azure Cosmos DB の場合は、マスター キーです。
次に、これらのアクセス制御ポリシーの接続文字列は、Key Vault に格納されます。 コンテナー自体には、Azure RBAC を必要としないマネージド ID を使用してアクセスします。 これらの接続文字列のアクセス ポリシーを適切に設定します。 たとえば、バックエンドの場合は読み取り専用、フロントエンドの場合は書き込み専用で、既定のルート アクセス ポリシーは使用しません。
services.json 内の次のスニペットは、これらのサービスのための KeyVault 構成を表示します。
{
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(variables('keyVaultName'), '/CosmosKey')]",
"apiVersion": "2015-06-01",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]",
"[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('cosmosName'))]"
],
"properties": {
"value": "[listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts',variables('cosmosName')),'2015-04-08').primaryMasterKey]"
}
},
{
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(variables('keyVaultName'), '/ServiceBusListenerConnectionString')]",
"apiVersion": "2015-06-01",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]",
"[resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules', variables('serviceBusName'), 'ListenerSharedAccessKey')]"
],
"properties": {
"value": "[listKeys(resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules',variables('serviceBusName'),'ListenerSharedAccessKey'),'2015-08-01').primaryConnectionString]"
}
},
{
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(variables('keyVaultName'), '/ServiceBusSenderConnectionString')]",
"apiVersion": "2015-06-01",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]",
"[resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules', variables('serviceBusName'), 'SenderSharedAccessKey')]"
],
"properties": {
"value": "[listKeys(resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules',variables('serviceBusName'),'SenderSharedAccessKey'),'2015-08-01').primaryConnectionString]"
}
},
これらの接続文字列の値は、Key Vault のキーと値のペアを参照することによって、アプリケーションによってアクセスされます。 これは、投票アプリケーションに対して次のスニペットに示されているように、sites. json ファイルで実行されます。
{
"properties": {
"enabled": true,
"name": "[variables('votingWebName')]",
"hostingEnvironment": "[variables('aseId')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('votingWebPlanName'))]",
"siteConfig": {
"appSettings": [
{
"name": "ConnectionStrings:sbConnectionString",
"value": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), variables('serviceBusSenderConnectionStringSecretName')), '2016-10-01').secretUriWithVersion, ')')]"
},
{
"name": "ConnectionStrings:RedisConnectionString",
"value": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), variables('redisSecretName')), '2016-10-01').secretUriWithVersion, ')')]"
},
{
"name": "ConnectionStrings:CosmosKey",
"value": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), variables('cosmosKeySecretName')), '2016-10-01').secretUriWithVersion, ')')]"
}
]
}
}
}
関数は、同様の方法で Service Bus リスナーの接続文字列にもアクセスします。
スケーラビリティ
スケーラブルなアプリケーションを設計する
このリファレンス アーキテクチャのアプリケーションは、使用量に基づいて個々のコンポーネントをスケールできるように構造化されています。 各 Web アプリ、API、関数は、独自の App Service プランにデプロイされます。 各アプリケーションでパフォーマンスのボトルネックが発生していないかどうかを監視し、必要に応じてスケールアップできます。 Azure App Service を使用してスケーラブルな Web アプリケーションを設計する方法については、「Azure Web アプリケーションのスケーラビリティの向上」を参照してください。
Application Gateway の自動スケーリング
自動スケーリングは、Azure Application Gateway V2 で有効にすることができます。 これにより、トラフィックの負荷パターンに基づいて、Application Gateway をスケールアップまたはスケールダウンすることができます。 このリファレンス アーキテクチャでは、ファイル appgw. json の autoscaleConfiguration
を構成し、0 個から 10 個までの追加インスタンスの間でスケールします。 詳細については、「Application Gateway と WAF v2 のスケーリング」を参照してください。
デプロイ
このリファレンス アーキテクチャのデプロイ スクリプトは、ASE、他のサービス、および ASE 内のアプリケーションをデプロイするために使用されます。 これらのアプリケーションをデプロイした後は、企業は、アプリケーションのメンテナンスとアップグレードのための継続的な統合とデプロイの計画を立てる必要があります。 このセクションでは、開発者が ASE アプリケーションの CI/CD を使用する一般的な方法をいくつか紹介します。
アプリケーションを内部 ASE にデプロイできるのは、仮想ネットワーク内からのみです。 ASE アプリケーションのデプロイには、次の 3 つの方法が広く使用されています。
Virtual Network 内で、手動で行う: デプロイに必要なツールを使用して、ASE VNet 内に仮想マシンを作成します。 NSG 構成を使用して、VM への RDP 接続を開きます。 コード アーティファクトを VM にコピーし、ビルドして、ASE サブネットにデプロイします。 これは、初期のビルドおよびテストの開発環境を設定する簡単な方法です。 ただし、運用環境では、必要なデプロイ スループットを拡張できないため、この方法はお勧めしません。
ローカル ワークステーションからのポイント対サイト接続: これにより、ASE VNet を開発用コンピューターに拡張し、そこからデプロイすることができます。 これは、初期開発環境をセットアップするもう 1 つの方法であり、運用環境ではお勧めしません。
Azure Pipelines: これは、VNet 内にあるエージェントで終了する完全な CI/CD パイプラインを実装します。 これは、デプロイの高スループットを要求する運用環境に最適です。 ビルド パイプラインは完全に VNet の外部に留まります。 デプロイ パイプラインは、構築されたオブジェクトを VNet 内のビルド エージェントにコピーし、ASE サブネットにデプロイします。 詳細については、パイプラインと ASE VNet 間の自己ホスト型ビルド エージェントに関する記事をご覧ください。
Azure Pipelines の使用は、運用環境にお勧めです。 Azure Pipelines YAML schema を使用して CI/CD をスクリプト化すると、ビルドおよびデプロイのプロセスを自動化できます。 このリファレンス実装では、azure-pipelines.yml は、Web アプリケーション用の CI/CD パイプラインを実装します。 Web API には同様の CI/CD スクリプトに加えて、関数もあります。 各アプリケーションの CI/CD を自動化するためにこれらを使用する方法については、「Azure Pipelines の使用」を参照してください。
一部の企業では、VNet 内で永続的なビルド エージェントを維持したくない場合があります。 その場合は、DevOps パイプライン内でビルド エージェントを作成し、デプロイが完了したら、それを破棄することができます。 これにより、DevOps に別のステップが追加されますが、仮想マシンのメンテナンスの複雑さが軽減されます。 VM ではなく、ビルド エージェントとしてコンテナーの使用を検討することもできます。 また、通常はストレージ アカウントで VNet の外部に配置された ZIP ファイルからデプロイすることで、ビルド エージェントを完全に回避できます。 ストレージ アカウントには、ASE からアクセスできる必要があります。 パイプラインは、ストレージにアクセスできる必要があります。 リリース パイプラインの最後には、ZIP ファイルを BLOB ストレージにドロップできます。 次に、ASE はこのファイルを選択してデプロイできます。 この方法の次の制限事項に注意してください。
- DevOps と実際のデプロイ プロセスとの間に断絶があるため、デプロイの問題を監視および追跡するときに問題が発生します。
- セキュリティで保護されたトラフィックを含むロックダウンされた環境では、ストレージ上の ZIP 形式のファイルにアクセスするように規則を変更することが必要になる場合があります。
- ZIP ファイルからデプロイできるようにするには、ASE に特定の拡張機能とツールをインストールする必要があります。
App Service プランにアプリをデプロイするいくつかの方法については、デプロイ戦略に焦点を置いた App Service に関する記事を参照してください。
コスト最適化
コストの見積もりには、Azure 料金計算ツールをご利用ください。 その他の考慮事項については、Microsoft Azure Well-Architected Framework のコストに関するセクションに説明されています。 Azure の予約には、多数の Azure リソースに対する計画を 1 年分または 3 年分コミットすることで、コストを削減する効果があります。 詳細については、記事「予約の購入」をお読みください。
ここでは、このアーキテクチャで使用される重要なサービスの一部について考慮する点について説明します。
App Service 環境
App Service には、様々な価格オプションが用意されています。 App Service 環境は、分離サービス プランを使用してデプロイされます。 このプランでは、CPU サイズに対して、I1、I2、I3 の 3 つのオプションがあります。 このリファレンス実装では、インスタンスごとに 3 つの I1 を使用しています。
Application Gateway
Application Gateway の価格には、Application Gateway の様々な価格オプションが用意されています。 自動スケーリングとゾーンの冗長性をサポートする Application Gateway Standard_v2 WAF_v2 と SKU を使用しています。 この SKU に使用される価格モデルの詳細については、この記事を参照してください。
Azure Cache for Redis
Azure Cache for Redis の価格には、このサービスに対する様々な価格オプションが用意されています。 このアーキテクチャでは、仮想ネットワークのサポートのために Premium SKU を使用します。
ASE をロックダウンするために使用されるその他のサービスの価格ページは次の通りです。
このシナリオのデプロイ
このアーキテクチャのリファレンス実装をデプロイするには、GitHub の readme を参照し、標準的なデプロイのためのスクリプトに従ってください。
共同作成者
この記事は、Microsoft によって保守されています。 当初の寄稿者は以下のとおりです。
プリンシパル作成者:
- Dhanashri Kshirsagar | シニア コンテンツ PM
パブリックでない LinkedIn プロファイルを表示するには、LinkedIn にサインインします。
次のステップ
- ZIP パッケージから Azure App Service のアプリを直接実行する
- Azure Pipelines YAML スキーマ
- API から管理アドレスを取得する
- Azure Key Vault
- Azure Pipelines
関連リソース
高可用性をサポートするためにこのアーキテクチャを拡張する方法については、「App Services Environment を使用した高可用性アプリケーションのデプロイ」を参照してください。