Convert ARM Template to Bicep and Deploy with Azure DevOps - Part 4 - Test
This is the fourth part of the series where an ARM Template is converted to Bicep. In this article, we should continue on Phase 4 - Test.
Phased Migration
As a reference to Part 3, Microsoft suggests a migration in 5 phases, to convert the ARM Template into Bicep Template.
The comprehensive details provided by Microsoft Docs are available as a reference1.
Phase 4 - Test
In this phase, it is important to validate the integrity of the new bicep template, by performing tests in a Test environment.
Check the PlayGoKids repository for this article demo.
Some actions need to be verified to give us confidence that the migrated template will work:
- Deployment what-if operation
This is a very clever way of checking any possible differences in the templates, by running the what-if operation. It compares the state of components/services deployed in Azure, by checking the current state of the deployed services with the new state of the converted template. The beauty of it is that it doesn't apply the changes to the environment, but the tool gives you an output of findings. There are 2 modes that you can run the tool: Incremental and Complete mode.
- Run a test deployment
Define a strategy to release the new template, either with a parallel release or an in-place release. The important thing is that this is thoroughly tested and validated.
what-if operation
Before you get an ARM/Bicep template released, you can preview the changes. That's what this tool allows you to do, preview without applying any changes.
If you remember the original ARM Template from Phase 1 - Convert, it had params:
Partial File: azuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"type": "string",
"minLength": 1,
"maxLength": 3
},
"hostingPlanName": {
"type": "string",
"minLength": 3
},
"skuName": {
"type": "string",
"defaultValue": "F1",
"allowedValues": [
"F1",
"D1",
"B1",
"B2",
"B3",
"S1",
"S2",
"S3",
"P1",
"P2",
"P3",
"P4"
],
"metadata": {
"description": "Describes plan's pricing tier and capacity. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service?WT.mc_id=AZ-MVP-5005172"
}
}
},
...
}
They were environment
, hostingPlanName
and skuName
.
What about the new Bicep file?
Partial File: azuredeploy.bicep
@minLength(1)
@maxLength(3)
param environment string
@minLength(3)
param appPlanName string
@description('Describes plan\'s pricing tier and capacity. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/?WT.mc_id=AZ-MVP-5005172')
@allowed([
'F1'
'D1'
'B1'
'B2'
'B3'
'S1'
'S2'
'S3'
'P1'
'P2'
'P3'
'P4'
])
param appPlanSku string = 'F1'
...
They are environment
, appPlanName
and appPlanSku
.
In summary, the changes were:
Before | After |
---|---|
environment | environment |
hostingPlanName | appPlanName |
skuName | appPlanSku |
To be able to run the what-if operation, we need to provide those parameters, but how is that done? We need to use the parameters file. This file should be already created for each environment (as a DevOps best practice). So looking at the directory folders we should have something like this:
|--ExistingARMTemplate
|--|--azuredeploy.json
|--|--azuredeploy.parameters.dev.json
|--|--azuredeploy.parameters.tst.json
|--|--azuredeploy.parameters.uat.json
|--|--azuredeploy.parameters.prd.json
|--ConvertedBicepTemplate
|--|--azuredeploy.bicep
|--|--azuredeploy.parameters.dev.json
|--|--azuredeploy.parameters.tst.json
|--|--azuredeploy.parameters.uat.json
|--|--azuredeploy.parameters.prd.json
|--|--modules
|--|--|--appPlan.bicep
|--|--|--apps.bicep
|--|--|--insights.bicep
Because of the Before and After changes, make sure the parameters' names match.
File: azuredeploy.parameters.dev.json
from ExistingARMTemplate
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"value": "dev"
},
"hostingPlanName": {
"value": "sample-app-nonprd"
},
"skuName": {
"value": "B1"
}
}
}
File: azuredeploy.parameters.dev.json
from ConvertedBicepTemplate
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"value": "dev"
},
"appPlanName": {
"value": "sample-app-nonprd"
},
"appPlanSku": {
"value": "B1"
}
}
}
Now we can run the what-if operation.
To be able to compare the differences, run these commands with az cli
, although you could also run with PowerShell:
// This will create the Resource group
az group create --name sample-rg-nonprd --location "Australia East"
// This will provision the dev environment using the old ARM definition
az deployment group create --resource-group sample-rg-nonprd --template-file .\azuredeploy.json --parameters .\azuredeploy.parameters.dev.json
// Here is the comparison we've been waiting for
az deployment group what-if --resource-group sample-rg-nonprd --template-file .\azuredeploy.bicep --parameters .\azuredeploy.parameters.dev.json
what-if operation results
This is the result we got after converting the ARM Template onto Bicep. It is important to notice that through visual colours you can see the changes:
Is that going to break the resources? That's a question you need to be able to answer for your own templates. On this one, they seem to be very minor, and wouldn't break the template I need, so I'm accepting the Resource changes.
Run the following command:
Mode = Complete
az deployment group create --mode Complete --confirm-with-what-if --resource-group sample-rg-nonprd --template-file .\azuredeploy.bicep --parameters .\azuredeploy.parameters.dev.json
What is interesting is that because I enforced the mode Complete
, the resource was displayed as to be deleted during confirmation. What it did was to delete and reprovision the resource, because in the end the webApp was there with the updated information.
Mode = Incremental
az deployment group create --mode Incremental --confirm-with-what-if --resource-group sample-rg-nonprd --template-file .\azuredeploy.bicep --parameters .\azuredeploy.parameters.dev.json
On Incremental
mode, we get the same level of warnings when we run the previous what-if command.
Services provisioned and updated
In both cases the same objects were there provisioned:
To understand more about the modes, check this link
In Phase 5 we'll check the Deploy Phase, prepping for Continuous Deployment.
Full Series
Phase 4 - Test
- References: Migrate to Bicep↩