Infrastructure Changes Are Too Risky to Deploy Blindly? Validate and Test Bicep

Published on:

A Bicep file can compile successfully and still contain an unintended infrastructure change. For example, a one-line edit could change storage redundancy or remove a container before anyone notices.

CloudTrips needs a repeatable safety gate that catches code regressions locally, checks the template with Azure, and shows the effect on live resources before deployment.

Understand the Three Checks

Each check answers a different question:

Check Question answered
Snapshot Did the Bicep result change from the approved code baseline?
Preflight validation Will Azure accept this template, configuration, and access?
What-if How would the deployment change the current Azure resources?

Snapshots are local and deterministic. Preflight and what-if contact Azure.

Make the Snapshot Command Available

Snapshots require Bicep CLI version 0.41.2 or later. Check the installed version:

az bicep version

The Azure CLI installation used in this project stores the Bicep executable in $HOME/.azure/bin. Run snapshot commands through that executable:

"$HOME/.azure/bin/bicep" --version

If the file does not exist, install it:

az bicep install

If the reported version is older than 0.41.2, run az bicep upgrade.

Capture the Approved TEST Baseline

From cloudtrips-bicep, create a snapshot:

"$HOME/.azure/bin/bicep" snapshot environments/test.bicepparam \
  --mode overwrite \
  --subscription-id 00000000-0000-0000-0000-000000000000 \
  --resource-group rg-cloudtrips-bicep-test-weu \
  --location westeurope \
  --deployment-name deploy-cloudtrips-storage-test

This creates environments/test.snapshot.json. Commit this file because it is the approved test baseline, not disposable build output.

The zero-filled subscription ID is deliberate. Snapshot runs locally and does not authenticate with that ID. It supplies stable context for expressions such as resourceGroup().id and uniqueString(), so every developer produces the same result. The snapshot is not expected to contain the live storage-account name.

Do not edit the generated JSON manually.

Confirm That Unchanged Code Passes

Validate the current Bicep result against the snapshot:

"$HOME/.azure/bin/bicep" snapshot environments/test.bicepparam \
  --mode validate \
  --subscription-id 00000000-0000-0000-0000-000000000000 \
  --resource-group rg-cloudtrips-bicep-test-weu \
  --location westeurope \
  --deployment-name deploy-cloudtrips-storage-test

No output and exit code 0 mean that the current result matches the baseline. Always reuse exactly the same context values when validating it.

Prove That the Test Detects a Risk

Temporarily change this line in environments/test.bicepparam:

param storageSku = 'Standard_GRS'

Run the same snapshot command with --mode validate. It should fail and show the storage SKU changing from Standard_LRS to Standard_GRS.

Failed Bicep snapshot validation showing the unintended TEST storage SKU change

Restore the approved value:

param storageSku = 'Standard_LRS'

Run snapshot validation again. It should now succeed with no output. Use --mode overwrite only after a change has been reviewed and intentionally approved; never overwrite the baseline simply to silence a failed test.

Run Azure Preflight Validation

Select the real TEST subscription and ask Azure to validate the deployment:

az account set \
  --subscription "<CloudTrips TEST subscription name or ID>"

az deployment group validate \
  --name validate-cloudtrips-storage-test \
  --resource-group rg-cloudtrips-bicep-test-weu \
  --parameters environments/test.bicepparam \
  --validation-level Provider \
  --query "properties.provisioningState" \
  --output tsv

Provider performs template, resource-provider, and permission checks. A successful result is Succeeded, but it does not prove that the live environment is unchanged.

Compare with the Live Environment

Finish with what-if:

az deployment group what-if \
  --resource-group rg-cloudtrips-bicep-test-weu \
  --parameters environments/test.bicepparam \
  --validation-level Provider

Review every proposed change. The known Storage provider defaults can still appear as noise, but there must be no unexpected create, delete, replacement, SKU, container, or tag change.

Successful Azure preflight and reviewed what-if result for CloudTrips TEST

CloudTrips now has three separate gates: snapshot catches unintended code changes, preflight checks whether Azure accepts the deployment, and what-if compares the approved code with live resources. A later automation trip can run the same checks for every pull request.