ARM template deployment what-if operation (Preview)

Before deploying an Azure Resource Manager template (ARM template), you can preview the changes that will happen. Azure Resource Manager provides the what-if operation to let you see how resources will change if you deploy the template. The what-if operation doesn't make any changes to existing resources. Instead, it predicts the changes if the specified template is deployed.

Note

The what-if operation is currently in preview. As a preview release, the results may sometimes show that a resource will change when actually no change will happen. We're working to reduce these issues, but we need your help. Please report these issues at https://aka.ms/whatifissues.

You can use the what-if operation with Azure PowerShell, Azure CLI, or REST API operations. What-if is supported for resource group, subscription, management group, and tenant level deployments.

Install Azure PowerShell module

To use what-if in PowerShell, you must have version 4.2 or later of the Az module.

But, before installing the required module, make sure you have PowerShell Core (6.x or 7.x). If you have PowerShell 5.x or earlier, update your version of PowerShell. You can't install the required module on PowerShell 5.x or earlier.

Install latest version

To install the module, use:

Install-Module -Name Az -Force

For more information about installing modules, see Install Azure PowerShell.

Uninstall alpha version

If you previously installed an alpha version of the what-if module, uninstall that module. The alpha version was only available to users who signed up for an early preview. If you didn't install that preview, you can skip this section.

  1. Run PowerShell as administrator

  2. Check your installed versions of the Az.Resources module.

    Get-InstalledModule -Name Az.Resources -AllVersions | select Name,Version
    
  3. If you have an installed version with a version number in the format 2.x.x-alpha, uninstall that version.

    Uninstall-Module Az.Resources -RequiredVersion 2.0.1-alpha5 -AllowPrerelease
    
  4. Unregister the what-if repository that you used to install the preview.

    Unregister-PSRepository -Name WhatIfRepository
    

You're ready to use what-if.

Install Azure CLI module

To use what-if in Azure CLI, you must have Azure CLI 2.5.0 or later. If needed, install the latest version of Azure CLI.

See results

When you use what-if in PowerShell or Azure CLI, the output includes color-coded results that help you see the different types of changes.

Resource Manager template deployment what-if operation fullresourcepayload and change types

The text output is:

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.

Note

The what-if operation can't resolve the reference function. Every time you set a property to a template expression that includes the reference function, what-if reports the property will change. This behavior happens because what-if compares the current value of the property (such as true or false for a boolean value) with the unresolved template expression. Obviously, these values will not match. When you deploy the template, the property will only change when the template expression resolves to a different value.

What-if commands

Azure PowerShell

To preview changes before deploying a template, use New-AzResourceGroupDeployment or New-AzSubscriptionDeployment. Add the -Whatif switch parameter to the deployment command.

  • New-AzResourceGroupDeployment -Whatif for resource group deployments
  • New-AzSubscriptionDeployment -Whatif and New-AzDeployment -Whatif for subscription level deployments

You can use the -Confirm switch parameter to preview the changes and get prompted to continue with the deployment.

  • New-AzResourceGroupDeployment -Confirm for resource group deployments
  • New-AzSubscriptionDeployment -Confirm and New-AzDeployment -Confirm for subscription level deployments

The preceding commands return a text summary that you can manually inspect. To get an object that you can programmatically inspect for changes, use Get-AzResourceGroupDeploymentWhatIfResult or Get-AzSubscriptionDeploymentWhatIfResult.

  • $results = Get-AzResourceGroupDeploymentWhatIfResult for resource group deployments
  • $results = Get-AzSubscriptionDeploymentWhatIfResult or $results = Get-AzDeploymentWhatIfResult for subscription level deployments

Azure CLI

To preview changes before deploying a template, use:

You can use the --confirm-with-what-if switch (or its short form -c) to preview the changes and get prompted to continue with the deployment. Add this switch to:

For example, use az deployment group create --confirm-with-what-if or -c for resource group deployments.

The preceding commands return a text summary that you can manually inspect. To get a JSON object that you can programmatically inspect for changes, use the --no-pretty-print switch. For example, use az deployment group what-if --no-pretty-print for resource group deployments.

If you want to return the results without colors, open your Azure CLI configuration file. Set no_color to yes.

Azure REST API

For REST API, use:

Change types

The what-if operation lists six different types of changes:

  • Create: The resource doesn't currently exist but is defined in the template. The resource will be created.

  • Delete: This change type only applies when using complete mode for deployment. The resource exists, but isn't defined in the template. With complete mode, the resource will be deleted. Only resources that support complete mode deletion are included in this change type.

  • Ignore: The resource exists, but isn't defined in the template. The resource won't be deployed or modified.

  • NoChange: The resource exists, and is defined in the template. The resource will be redeployed, but the properties of the resource won't change. This change type is returned when ResultFormat is set to FullResourcePayloads, which is the default value.

  • Modify: The resource exists, and is defined in the template. The resource will be redeployed, and the properties of the resource will change. This change type is returned when ResultFormat is set to FullResourcePayloads, which is the default value.

  • Deploy: The resource exists, and is defined in the template. The resource will be redeployed. The properties of the resource may or may not change. The operation returns this change type when it doesn't have enough information to determine if any properties will change. You only see this condition when ResultFormat is set to ResourceIdOnly.

Result format

You control the level of detail that is returned about the predicted changes. You have two options:

  • FullResourcePayloads - returns a list of resources that will change and details about the properties that will change
  • ResourceIdOnly - returns a list of resources that will change

The default value is FullResourcePayloads.

For PowerShell deployment commands, use the -WhatIfResultFormat parameter. In the programmatic object commands, use the ResultFormat parameter.

For Azure CLI, use the --result-format parameter.

The following results show the two different output formats:

  • Full resource payloads

    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.
    
  • Resource ID only

    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.
    

Run what-if operation

Set up environment

To see how what-if works, let's runs some tests. First, deploy a template that creates a virtual network. You'll use this virtual network to test how changes are reported by 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"

Test modification

After the deployment completes, you're ready to test the what-if operation. This time you deploy a template that changes the virtual network. It's missing one the original tags, a subnet has been removed, and the address prefix has changed.

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"

The what-if output appears similar to:

Resource Manager template deployment what-if operation output

The text output is:

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.

Notice at the top of the output that colors are defined to indicate the type of changes.

At the bottom of the output, it shows the tag Owner was deleted. The address prefix changed from 10.0.0.0/16 to 10.0.0.0/15. The subnet named subnet001 was deleted. Remember these changes weren't deployed. You see a preview of the changes that will happen if you deploy the template.

Some of the properties that are listed as deleted won't actually change. Properties can be incorrectly reported as deleted when they aren't in the template, but are automatically set during deployment as default values. This result is considered "noise" in the what-if response. The final deployed resource will have the values set for the properties. As the what-if operation matures, these properties will be filtered out of the result.

Programmatically evaluate what-if results

Now, let's programmatically evaluate the what-if results by setting the command to a variable.

$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"

You can see a summary of each change.

foreach ($change in $results.Changes)
{
  $change.Delta
}

Confirm deletion

The what-if operation supports using deployment mode. When set to complete mode, resources not in the template are deleted. The following example deploys a template that has no resources defined in complete mode.

To preview changes before deploying a template, use the confirm switch parameter with the deployment command. If the changes are as you expected, acknowledge that you want the deployment to complete.

New-AzResourceGroupDeployment `
  -ResourceGroupName ExampleGroup `
  -Mode Complete `
  -Confirm `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/empty-template/azuredeploy.json"

Because no resources are defined in the template and the deployment mode is set to complete, the virtual network will be deleted.

Resource Manager template deployment what-if operation output deployment mode complete

The text output is:

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"):

You see the expected changes and can confirm that you want the deployment to run.

SDKs

You can use the what-if operation through the Azure SDKs.

Next steps