Azure / AzOps

AzOps is a PowerShell module which deploys (Push) ARM Resource Templates & Bicep files at all Azure scope levels and exports (Pull) ARM resource hierarchy.
https://aka.ms/AzOps
MIT License
371 stars 158 forks source link

AllowMultipleTemplateParameterFiles: Updating a Bicep template and deleting a parameter file in the same PR causes the deleted parameter file to redeploy #879

Closed Xitric closed 2 months ago

Xitric commented 2 months ago

Describe the bug

AzOps version: 2.6.2

Using Azure DevOps pipelines from the AzOps accelerator, given AllowMultipleTemplateParameterFiles and DeployAllMultipleTemplateParameterFiles are enabled, when we merge a pull requests which both 1) modifies a Bicep template and 2) deletes one or more parameter files associated with that Bicep template, then a deployment is performed for each of the deleted parameter files. This is surprising since:

  1. A deletion of a parameter file should not signal an intent to deploy anything
  2. We do not know how AzOps obtains the parameters from the file which has been deleted, since the file no longer exists in the git repository

If we run the redeploy pipeline against the Bicep template on the same commit that the push pipeline was executed on, only the parameter files that actually exist in the git repository are deployed, as we would expect. The parameter files that were removed in that commit are not deployed.

Steps to reproduce

  1. Enable both AllowMultipleTemplateParameterFiles and DeployAllMultipleTemplateParameterFiles
  2. Create a pull request which modifies a Bicep template and deletes one or more parameter files associated with that Bicep template
  3. The validation pipeline will now specify that new deployments are performed for each of the deleted parameter files
  4. Upon merging the pull request, a deployment is in fact performed for each of the deleted parameter files, somehow using the content of the now deleted files as deployment input

Screenshots

The diff stage generates the following output:

D   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.1.bicepparam
M   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.bicep
D   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.2.bicepparam

The deployment stage then outputs:

[09:37:22][Invoke-AzOpsPush] Deployment required
[09:37:22][Invoke-AzOpsPush] Adding or modifying:
[09:37:22][Invoke-AzOpsPush]   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.bicep
[09:37:22][Invoke-AzOpsPush] Deleting:
[09:37:22][Invoke-AzOpsPush]   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.1.bicepparam
[09:37:22][Invoke-AzOpsPush]   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.2.bicepparam
[09:38:04][New-AzOpsDeployment] Processing deployment AzOps-main.1-B9EE for template /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json with parameter "/__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.1.parameters.json" in mode Incremental
Getting the latest status of all resources...

[09:56:55][New-AzOpsDeployment] Processing deployment AzOps-main.2-B9EE for template /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json with parameter "/__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.2.parameters.json" in mode Incremental
Getting the latest status of all resources...

Both of these deployments are unexpected, since the parameter files were deleted.

Workaround

Use separate pull requests for deleting parameter files and updating Bicep templates. If the pull request only contains deleted parameter files, no effort is made to deploy anything:

[11:10:21][Invoke-AzOpsPush] Deployment required
[11:10:21][Invoke-AzOpsPush] Deleting:
[11:10:21][Invoke-AzOpsPush]   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.1.bicepparam
[11:10:21][Invoke-AzOpsPush]   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.2.bicepparam
[11:10:21][Invoke-AzOpsPush]   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.3.bicepparam
[11:10:21][Invoke-AzOpsPush]   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.4.bicepparam
[11:10:21][Invoke-AzOpsPush]   root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.5.bicepparam
[11:10:47][Remove-AzOpsDeployment] Processing removal AzOps-RemoveResource-main for template /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json
WARNING: [11:10:47][Remove-AzOpsDeployment] Detected custom template: /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json, and Core.CustomTemplateResourceDeletion is not set to true
[11:10:47][Remove-AzOpsDeployment] Processing removal AzOps-RemoveResource-main for template /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json
WARNING: [11:10:47][Remove-AzOpsDeployment] Detected custom template: /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json, and Core.CustomTemplateResourceDeletion is not set to true
[11:10:47][Remove-AzOpsDeployment] Processing removal AzOps-RemoveResource-main for template /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json
WARNING: [11:10:47][Remove-AzOpsDeployment] Detected custom template: /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json, and Core.CustomTemplateResourceDeletion is not set to true
[11:10:47][Remove-AzOpsDeployment] Processing removal AzOps-RemoveResource-main for template /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json
WARNING: [11:10:48][Remove-AzOpsDeployment] Detected custom template: /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json, and Core.CustomTemplateResourceDeletion is not set to true
[11:10:48][Remove-AzOpsDeployment] Processing removal AzOps-RemoveResource-main for template /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json
WARNING: [11:10:48][Remove-AzOpsDeployment] Detected custom template: /__w/1/s/root/my management group (00000000-0000-0000-0000-000000000000)/my subscription (00000000-0000-0000-0000-000000000000)/main.json, and Core.CustomTemplateResourceDeletion is not set to true
[11:10:48][Invoke-AzOpsPush] AzOps Push completed in 00:00:26.8132035
Jefajers commented 2 months ago

Hi @Xitric, no good deed goes unpunished ;). I can reproduce the issue and agree this is not how we want it to behave.

The reason for the un-expected outcome is basically a consequence of how deletion is handled by "re-creating" the file during module processing based on pipeline input to temporarily handle template content processing for deletion. Due to that the file suddenly exists, during that time the module identifies the file as a friend to the main template and thus join the deployment effort.

We will look into compensating factors to overcome this undesired state.