At Ignite this year we saw several announcements around ARM templates and deployments in Azure. One of these was the long-awaited “What-If” feature.
See what I did there…
For a long time, a big differentiator between ARM templates and other deployment tools such as Terraform was the existence of a “plan” feature or similar. Terraform's plan command allows you to determine what a template is going to do before you do it. By running “Terraform Plan” you will receive a list of all the changes, additions and deletions Terraform plans to make, allowing you to validate what is going to happen when you deploy the template.
Unlike Terraform, ARM templates haven't had had this feature. There was no way to confirm what a template was going to do without actually running it. This is where What-If comes in; this new feature finally brings this ability to ARM templates. Using the What-If command, we can now get a report about what the template is going to do, without having to run.
Having this feature brings several benefits. The most obvious is the ability to validate that what the template is going to do is actually what you expect it to do. By running what-if, you can get a list of changes, additions and deletions that this template is going to undertake, right down to resource properties. This feature also opens up new opportunities for automated testing of templates. Before What-If, the only way to test what a template was doing was to run it and deploy the resources. Now with What-If, we can get this data, in an easily consumable format, without deploying any resources. We can run all sorts of automated testing against this data.
Access to What-If
Currently, What-If is in private preview so you will need to register here to get access to it. Once you get access, you'll be able to download the cmdlets and install them.
Once you have the cmdlets installed running a what-if is very similar to creating a new deployment, but with the “New-AzDeploymentWhatIf” command. There's been some conversation about why this is a new command, rather than a “-whatif” parameter on the existing new-AzurermResourceGroupDeployment command, but at present, it is a separate command.
The rest of the parameters are similar to those in the new-AzureRMResourceGroupDeployment command, passing in the template, parameter file and name. There is also a new parameter that defines the scope your running the command against. This command can work with ARM templates that deploy at the resource group or subscription scope. Finally, you also define whether the deployment is in complete or incremental mode.
New-AzDeploymentWhatIf -Name "DeploymentName" -ResourceGroupName "ResourceGroupName" -TemplateFile TemplateFile.json -TemplateParameterFile ParamaterFile.json -ScopeType ResourceGroup -Mode Incremental
The example below shows the results of running a template against an empty resource group, and so everything is an addition. You will also see two resources are being ignored. These are ignored because there are conditions in this template, these are evaluated by what-if, so you see what will happen.
As you can see, there is a lot of information here. Each resource is listed along with all the properties underneath. This information is crucial if you need to know precisely what is being changed, but if you want a summary, you can add the “ResultFormat” parameter. This parameter has two options - “FullResourcePayloads” which provides the data we see above with every resource and property, and then “ResourceIdOnly”, which summarises the data and shows only the top-level resources that are changed.
The image below is from another deployment where there are existing resource in the resource group. Because we are doing a complete deployment, and there are differences between the template and the resources, we see some deletion and change items. You can see that each different type of operation is marked with a different symbol and colour code along with the summary.
All of this is great to be able to visualise the changes, but if you want to use this data programmatically, you will find that the command returns a PowerShell object that can be used to access this data programmatically.
In particular, this object includes a delta object to view the changes between before and after.
One issue you may see when using this command is noise, where the results show that a resource is being changed when no change will occur. This is usually down to the fact that the information you provide to the ARM API to create or update a resource is less than the data returned when querying it, or that defaults are being used. An example seen early in the preview was when deploying a storage account, if you did not specify the encryption settings in the template (so using the defaults), then What-If showed a change because it thought it was removing these settings.
This is something the ARM team is aware of and are working to remove during the preview. They are asking for everyone using this command to keep an eye out for these issues and log them in this Github issues log. Please do log issues when you see them to help improve this command and get it out of preview as soon as possible.