Azure Resource Manager テンプレート (ARM テンプレート) をデプロイする前に、発生する変更をプレビューできます。 Azure Resource Manager には、テンプレートをデプロイした場合にリソースがどのように変化するかを確認できる What-If 操作が用意されています。 what-if 操作では、既存のリソースに対していかなる変更も行われません。 代わりに、指定したテンプレートがデプロイされた場合の変更が予測されます。
what-if 操作は Azure PowerShell、Azure CLI、または REST API 操作で使用できます。 What-if は、リソース グループ、サブスクリプション、管理グループ、テナント レベルのデプロイでサポートされています。
トレーニング リソース
what-if の詳細とハンズオン ガイダンスについては、「 what-if を使用して Azure デプロイの変更をプレビューする」を参照してください。
[前提条件]
必要なアクセス許可
Bicep ファイルまたは Azure Resource Manager (ARM) テンプレートをデプロイするには、デプロイするリソースに対する書き込みアクセス権と、 Microsoft.Resources/deployments リソースの種類に対するすべての操作へのアクセス権が必要です。 たとえば、仮想マシンをデプロイするには、Microsoft.Compute/virtualMachines/write および Microsoft.Resources/deployments/* アクセス許可が必要です。  What-If 操作のアクセス許可要件も同じです。
Azure CLI バージョン 2.76.0 以降 と Azure PowerShell バージョン 13.4.0 以降 では、このプロセス中に ARM が Bicep テンプレートを徹底的に検証する方法を決定する ValidationLevel スイッチが導入されています。 詳細については、「What-if コマンド」を参照してください。
ロールとアクセス許可の一覧については、Azure の組み込みロールに関するページを参照してください。
What-if 制限
What-if は、次の制限に達するまで、入れ子になったテンプレートを展開します。
- 500 個の入れ子になったテンプレート。
 - クロス リソース グループのデプロイにおける 800 個のリソース グループ。
 - 入れ子になったテンプレートの展開に 5 分かかる。
 
これらの制限のいずれかに達すると、残りのリソースの変更の種類が "無視" に設定されます。
Azure PowerShell モジュールをインストールする
PowerShell で What-if を使用するには、Az モジュールの 4.2 以降のバージョンが必要です。
モジュールをインストールするには、次を使用します。
Install-Module -Name Az -Force
モジュールのインストールの詳細については、「Azure PowerShell をインストールする」を参照してください。
Azure CLI モジュールのインストール
Azure CLI で what-if を使用するには、Azure CLI 2.14.0 以降である必要があります。 必要であれば、Azure CLI の最新バージョンをインストールします。
結果を表示する
what-if を PowerShell または Azure CLI で使用する際、さまざまな種類の変更を確認するのに役立つ、色分けされた結果が出力されます。
              
              
              
              
            
テキスト出力は次のとおりです。
Resource and property changes are indicated with these symbols:
  - Delete
  + Create
  ~ Modify
The deployment will update the following scope:
Scope: /subscriptions/./resourceGroups/ExampleGroup
  ~ Microsoft.Network/virtualNetworks/vnet-001 [2018-10-01]
    - tags.Owner: "Team A"
    ~ properties.addressSpace.addressPrefixes: [
      - 0: "10.0.0.0/16"
      + 0: "10.0.0.0/15"
      ]
    ~ properties.subnets: [
      - 0:
          name:                     "subnet001"
          properties.addressPrefix: "10.0.0.0/24"
      ]
Resource changes: 1 to modify.
注
What-if 操作では、reference 関数を解決できません。 reference 関数を含むテンプレート式にプロパティを設定するたびに、What-if は、そのプロパティが変更されることを報告します。 この動作は、What-if がそのプロパティの現在の値 (ブール値の場合は true や false など) を未解決のテンプレート式と比較するために発生します。 当然、これらの値は一致しません。 テンプレートをデプロイすると、テンプレート式が別の値に解決された場合にのみ、プロパティが変更されます。
What-if コマンド
Azure PowerShell
テンプレートをデプロイする前に変更をプレビューするには、 New-AzResourceGroupDeployment または New-AzSubscriptionDeployment を使用します。 デプロイ コマンドに -Whatif スイッチ パラメーターを追加します。
リソース グループ デプロイの場合は
New-AzResourceGroupDeployment -Whatifサブスクリプション レベルのデプロイの場合は
New-AzSubscriptionDeployment -WhatifおよびNew-AzDeployment -Whatif
              -Confirm スイッチ パラメーターを使用して、変更をプレビューし、デプロイを続行するかどうかを確認するプロンプトを表示することもできます。
- リソース グループ デプロイの場合は 
New-AzResourceGroupDeployment -Confirm - サブスクリプション レベルのデプロイの場合は 
New-AzSubscriptionDeployment -ConfirmおよびNew-AzDeployment -Confirm 
上記のコマンドは、手動で検査できるテキストの概要を返します。 プログラムで変更を検査できるオブジェクトを取得するには、Get-AzResourceGroupDeploymentWhatIfResult または Get-AzSubscriptionDeploymentWhatIfResult を使用します。
- リソース グループ デプロイの場合は 
$results = Get-AzResourceGroupDeploymentWhatIfResult - サブスクリプション レベルのデプロイの場合は 
$results = Get-AzSubscriptionDeploymentWhatIfResultまたは$results = Get-AzDeploymentWhatIfResult 
Azure CLI
テンプレートをデプロイする前に変更をプレビューするには、次を使用します。
- az deployment group what-if (リソース グループのデプロイの場合)
 - az deployment sub what-if (サブスクリプション レベルのデプロイの場合)
 - az deployment mg what-if (管理グループのデプロイの場合)
 - az deployment tenant what-if (テナントのデプロイの場合)
 
              --confirm-with-what-if (または短縮形式 -c) を使用して、変更をプレビューし、デプロイを続行するかどうかを確認するプロンプトを表示することもできます。 このスイッチを次のコマンドに追加します。
- az deployment group create コマンドを実行する
 - az deployment sub create
 - az deployment mg create
 - az deployment tenant create コマンドを使用して、新しいテナントのデプロイメントを作成します。
 
たとえば、リソース グループのデプロイの場合は az deployment group create --confirm-with-what-if または -c を使用します。
上記のコマンドは、手動で検査できるテキストの概要を返します。 プログラムによって変更を検査できる JSON オブジェクトを取得するには、--no-pretty-print スイッチを使用します。 たとえば、リソース グループのデプロイの場合は az deployment group what-if --no-pretty-print を使用します。
カラーなしの結果を返す場合は、Azure CLI 構成ファイルを開きます。 no_color を yes に設定します。
Azure REST API
REST API については、以下を使用します。
- リソース グループ デプロイの場合は「デプロイ - What If」
 - サブスクリプションのデプロイの場合は「デプロイ - サブスクリプション スコープでの What If」
 - 管理グループのデプロイの場合は「デプロイ - 管理グループ スコープでの What If」
 - テナントのデプロイの場合は「デプロイ - テナント スコープでの What If」
 
変更の種類
what-if 操作では、7 種類の異なる変更が一覧表示されます:
- 作成: リソースは現在存在しませんが、テンプレートで定義されています。 リソースが作成されます。
 - 削除: この変更の種類は、デプロイに 完全モード を使用する場合にのみ適用されます。 リソースは存在しますが、テンプレートでは定義されていません。 完全モードでは、リソースが削除されます。 この変更の種類には、完全モードの削除をサポートしているリソースのみが含まれます。
 - 無視: リソースは存在しますが、テンプレートでは定義されていません。 リソースはデプロイまたは変更されません。 入れ子になったテンプレートを拡張するための制限に達すると、この種類の変更が発生します。 「What-if 制限」を参照してください。
 - 
              NoChange: リソースが存在し、テンプレートで定義されています。 リソースは再デプロイされますが、リソースのプロパティは変更されません。 この変更の種類は、ResultFormat が 
FullResourcePayloadsに設定されている場合に返されます。これは既定値です。 - 
              NoEffect: プロパティは読み取り専用であり、サービスによって無視されます。 たとえば、
sku.tierプロパティは常にsku.name名前空間でMicrosoft.ServiceBusに一致するように設定されます。 - 
              変更: リソースが存在し、テンプレートで定義されています。 リソースは再デプロイされ、リソースのプロパティが変更されます。 この変更の種類は、ResultFormat が 
FullResourcePayloadsに設定されている場合に返されます。これは既定値です。 - 
              デプロイ: リソースが存在し、テンプレートで定義されています。 リソースは再デプロイされます。 リソースのプロパティは、変更される場合と変更されない場合があります。 いずれかのプロパティが変更されるかどうか判断するのに十分な情報がない場合、操作ではこの変更の種類が返されます。 この状況は、ResultFormat が 
ResourceIdOnlyに設定されている場合にのみ表示されます。 
結果の形式
予測される変更に関して返される詳細さのレベルを制御します。 次の 2 つのオプションがあります。
- FullResourcePayloads - 変更されるリソースの一覧と、変更されるプロパティの詳細を返します
 - ResourceIdOnly - 変更されるリソースの一覧を返します
 
既定値は FullResourcePayloads です。
PowerShell のデプロイ コマンドでは、-WhatIfResultFormat パラメーターを使用します。 プログラム オブジェクト コマンドでは、ResultFormat パラメーターを使用します。
Azure CLI の場合は、--result-format パラメーターを使用します。
次の結果では、2 つの異なる出力形式が示されています。
完全なリソース ペイロード
Resource and property changes are indicated with these symbols: - Delete + Create ~ Modify The deployment will update the following scope: Scope: /subscriptions/./resourceGroups/ExampleGroup ~ Microsoft.Network/virtualNetworks/vnet-001 [2018-10-01] - tags.Owner: "Team A" ~ properties.addressSpace.addressPrefixes: [ - 0: "10.0.0.0/16" + 0: "10.0.0.0/15" ] ~ properties.subnets: [ - 0: name: "subnet001" properties.addressPrefix: "10.0.0.0/24" ] Resource changes: 1 to modify.リソース ID のみ
Resource and property changes are indicated with this symbol: ! Deploy The deployment will update the following scope: Scope: /subscriptions/./resourceGroups/ExampleGroup ! Microsoft.Network/virtualNetworks/vnet-001 Resource changes: 1 to deploy.
what-if 操作を実行する
環境を設定する
what-if がどのように動作するか見るため、いくつかのテストを実行してみましょう。 まず、 仮想ネットワークを作成するテンプレートをデプロイします。 この仮想ネットワークを使用して、what-if により変更がどのように報告されるかをテストします。
New-AzResourceGroup `
  -Name ExampleGroup `
  -Location centralus
New-AzResourceGroupDeployment `
  -ResourceGroupName ExampleGroup `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/what-if/what-if-before.json"
変更をテストする
デプロイが完了すると、what-if 操作をテストできる状態になります。 今回は、 仮想ネットワークを変更するテンプレートをデプロイします。 元のタグが見つかりません。サブネットが削除され、アドレス プレフィックスが変更されました。
New-AzResourceGroupDeployment `
  -Whatif `
  -ResourceGroupName ExampleGroup `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/what-if/what-if-after.json"
what-if の出力は次のようになります。
              
              
              
              
            
テキスト出力は次のとおりです。
Resource and property changes are indicated with these symbols:
  - Delete
  + Create
  ~ Modify
The deployment will update the following scope:
Scope: /subscriptions/./resourceGroups/ExampleGroup
  ~ Microsoft.Network/virtualNetworks/vnet-001 [2018-10-01]
    - tags.Owner: "Team A"
    ~ properties.addressSpace.addressPrefixes: [
      - 0: "10.0.0.0/16"
      + 0: "10.0.0.0/15"
      ]
    ~ properties.subnets: [
      - 0:
        name:                     "subnet001"
        properties.addressPrefix: "10.0.0.0/24"
      ]
Resource changes: 1 to modify.
出力の上部で、変更の種類を示す色が定義されていることに注意してください。
出力の下部には、タグ Owner が削除されたことが表示されています。 アドレス プレフィックスが 10.0.0.0/16 から 10.0.0.0/15 に変更されました。 subnet001 という名前のサブネットが削除されました。 これらの変更は、デプロイされていないことに注意してください。 テンプレートをデプロイした場合に発生する変更のプレビューが表示されます。
削除済みとして一覧されたプロパティの一部は、実際には変更されません。 プロパティは、テンプレートに含まれていないときに誤って削除済みとして報告される可能性がありますが、デプロイ時に既定値として自動的に設定されます。 この結果は、what-if 応答では "ノイズ" と見なされます。 最後にデプロイされたリソースには、プロパティ用の値セットがあります。 what-if 操作が成熟すると、これらのプロパティは結果から除外されます。
what-if 結果のプログラムによる評価
次に、コマンドを変数に設定して、what-if 結果をプログラムで評価してみましょう。
$results = Get-AzResourceGroupDeploymentWhatIfResult `
  -ResourceGroupName ExampleGroup `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/what-if/what-if-after.json"
それぞれの変更の概要を確認できます。
foreach ($change in $results.Changes)
{
  $change.Delta
}
削除の確定
What-If 操作では 、デプロイ モードの使用がサポートされます。 完了モードに設定すると、テンプレートにないリソースが削除されます。 次の例では、完全モードで 定義されたリソースがないテンプレート をデプロイします。
テンプレートをデプロイする前に変更をプレビューするには、デプロイ コマンドで confirm switch パラメーターを使用します。 変更が期待どおりの場合は、デプロイを完了すると応答します。
New-AzResourceGroupDeployment `
  -ResourceGroupName ExampleGroup `
  -Mode Complete `
  -Confirm `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/what-if/azuredeploy.json"
テンプレートでリソースが定義されておらず、デプロイ モードが完了するように設定されているため、仮想ネットワークは削除されます。
              
              
              
              
            
テキスト出力は次のとおりです。
Resource and property changes are indicated with this symbol:
  - Delete
The deployment will update the following scope:
Scope: /subscriptions/./resourceGroups/ExampleGroup
  - Microsoft.Network/virtualNetworks/vnet-001
      id:
"/subscriptions/./resourceGroups/ExampleGroup/providers/Microsoft.Network/virtualNet
works/vnet-001"
      ___location:        "centralus"
      name:            "vnet-001"
      tags.CostCenter: "12345"
      tags.Owner:      "Team A"
      type:            "Microsoft.Network/virtualNetworks"
Resource changes: 1 to delete.
Are you sure you want to execute the deployment?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):
期待通りの変更が表示され、デプロイを実行することを確認できます。
SDK
what-if 操作は、Azure SDK を介して使用できます。
Python の場合は、what-if を使用します。
Java の場合は、DeploymentWhatIf クラスを使用します。
.NET の場合は、DeploymentWhatIf クラスを使用します。
次のステップ
- ARM Deployment Insights 拡張機能を使用すると、What-If 操作を Azure DevOps パイプラインに簡単に統合できます。
 - パイプラインで what-if 操作を使用するには、パイプライン 内の What-If を使用して ARM テンプレートをテストする方法に関するページを参照してください。
 - what-if 操作の結果が正しくない場合は、 https://aka.ms/whatifissuesで問題を報告してください。
 - What if の使用方法について説明する Learn モジュールについては、「 What-if と ARM テンプレート のテスト ツールキットを使用して変更をプレビューし、Azure リソースを検証する」を参照してください。