azure-resource-managerazure-virtual-machineazure-rm-templateazure-bicepazure-policy

Azure Policy fails to deploy AzureNetworkWatcherExtension on Windows VMs (Error: "resource not found")


I'm currently working on creating Azure Policies to manage our virtual machines, and one of the policies is not behaving as expected.

The goal of this custom policy is to automatically deploy the AzureNetworkWatcherExtension on all Windows VMs. However, while the compliance logic seems to work (since VMs that already have the extension, are flagged as compliant), the policy fails to deploy the extension when it’s missing. For these VMs, I receive a "resource not found" compliance message. I suspect the issue is within the deployment section, but I'm not sure what’s wrong. Below are the full definitions of both the policy and the assignment. I'd appreciate any insights!

The complete compliance error is :

Reason for non-compliance

No related resources match the effect details in the policy definition. (Error code: ResourceNotFound) Existence condition

Type

Microsoft.Compute/virtualMachines/extensions

targetScope = 'managementGroup'

resource networkWatcherAgentPolicy 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
  name: 'deploy-network-watcher-agent-windows'
  properties: {
    policyType: 'Custom'
    displayName: '[Custom - MyOrg] Deploy Network Watcher Agent on Windows VMs'
    description: 'Automatically deploys the Network Watcher Agent extension on all Windows virtual machines.'
    mode: 'All'
    metadata: {
      version: '1.0.0'
      category: 'Monitoring'
    }
    policyRule: {
      if: {
        allOf: [
          {
            field: 'type'
            equals: 'Microsoft.Compute/virtualMachines'
          }
          {
            field: 'Microsoft.Compute/virtualMachines/storageProfile.osDisk.osType'
            equals: 'Windows'
          }
        ]
      }
      then: {
        effect: 'deployIfNotExists'
        details: {
          type: 'Microsoft.Compute/virtualMachines/extensions'
          name: 'AzureNetworkWatcherExtension'
          roleDefinitionIds: [
            '/providers/Microsoft.Authorization/roleDefinitions/9980e02c-c2be-4d73-94e8-173b1dc7cf3c'
          ]
          existenceCondition: {
            allOf: [
              {
                field: 'Microsoft.Compute/virtualMachines/extensions/publisher'
                equals: 'Microsoft.Azure.NetworkWatcher'
              }
              {
                field: 'Microsoft.Compute/virtualMachines/extensions/type'
                equals: 'NetworkWatcherAgentWindows'
              }
              {
                field: 'Microsoft.Compute/virtualMachines/extensions/provisioningState'
                equals: 'Succeeded'
              }              
            ]
          }
          deployment: {
            properties: {
              mode: 'Incremental'
              template: {
                '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
                contentVersion: '1.0.0.0'
                resources: [
                  {
                    type: 'Microsoft.Compute/virtualMachines'
                    apiVersion: '2023-03-01'
                    name: '[parameters(\'vmName\')]'
                    location: '[parameters(\'location\')]'
                    properties: {}
                  }
                  {
                    type: 'Microsoft.Compute/virtualMachines/extensions'
                    apiVersion: '2023-03-01'
                    name: '[concat(parameters(\'vmName\'), \'/AzureNetworkWatcherExtension\')]'
                    dependsOn: [
                      '[concat(\'Microsoft.Compute/virtualMachines/\', parameters(\'vmName\'))]'
                    ]
                    location: '[parameters(\'location\')]'
                    properties: {
                      publisher: 'Microsoft.Azure.NetworkWatcher'
                      type: 'NetworkWatcherAgentWindows'
                      typeHandlerVersion: '1.4'
                      autoUpgradeMinorVersion: true
                    }
                  }
                ]
              }
              parameters: {
                vmName: {
                  value: '[field(\'name\')]'
                }
                location: {
                  value: '[field(\'location\')]'
                }
              }
            }
          }
        }
      }
    }
  }
}
resource networkWatcherAgentAssignment 'Microsoft.Authorization/policyAssignments@2021-06-01' = {
  scope: subscription()
  name: 'MyOrg - Deploy Network Watcher Agent on Windows VMs'
  dependsOn: [
    dcrVmInsight
    azureMonitorAgentPolicyAssignment
  ]  
  location: location
  properties: {
    displayName: 'MyOrg - Deploy Network Watcher Agent on Windows VMs'
    description: 'Automatically deploys the Network Watcher Agent extension on all Windows virtual machines.'
    nonComplianceMessages: [
      {
        message: 'The Network Watcher Agent extension is not deployed on the virtual machine. Please deploy the extension to ensure proper monitoring.'
        policyDefinitionReferenceId: null
      }
    ]
    policyDefinitionId: '/providers/Microsoft.Management/managementGroups/EnvOrg-MyOrg/providers/Microsoft.Authorization/policyDefinitions/deploy-network-watcher-agent-windows'
    parameters: {}
  }
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${userIdentity.id}': {}
    }
  }  
}

Has anyone run into this issue when deploying extensions via Azure Policy? Do I need to explicitly define additional properties inside the virtualMachines resource stub, or is there another deployment gotcha I’m missing?

Thanks for your help!


EDIT: Clarification

The deployIfNotExists does not seem to work for new resources (virtual machines) created after the policy was implemented. The AzureNetworkWatcherExtension extension does not install automatically. The machines show an error in the compliance section with the following message:

Reason for non-compliance No related resources match the effect details in the policy definition. (Error code: ResourceNotFound) Existence condition

Type Microsoft.Compute/virtualMachines/extensions

I don’t understand the error, which seems to indicate that I’m referencing a resource that doesn’t exist, even though I’m sure about the name of the extension.

Here is the updated script, following everyone's suggestions:

targetScope = 'managementGroup'

resource networkWatcherAgentPolicy 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
  name: 'deploy-network-watcher-agent-windows'
  properties: {
    policyType: 'Custom'
    displayName: '[Custom - MyOrg] Deploy Network Watcher Agent on Windows VMs'
    description: 'Automatically deploys the Network Watcher Agent extension on all Windows virtual machines.'
    mode: 'indexed' // https://learn.microsoft.com/en-us/azure/governance/policy/concepts/definition-structure-basics#resource-manager-modes
    metadata: {
      version: '1.0.0'
      category: 'Monitoring'
    }
    policyRule: {
      if: {
        allOf: [
          {
            field: 'type'
            equals: 'Microsoft.Compute/virtualMachines'
          }
          {
            field: 'Microsoft.Compute/virtualMachines/storageProfile.osDisk.osType'
            like: 'Windows*'
          }
        ]
      }
      then: {
        effect: 'deployIfNotExists'
        details: {
          type: 'Microsoft.Compute/virtualMachines/extensions'
          evaluationDelay: 'AfterProvisioning'
          name: 'AzureNetworkWatcherExtension'
          roleDefinitionIds: [
            '/providers/Microsoft.Authorization/roleDefinitions/9980e02c-c2be-4d73-94e8-173b1dc7cf3c'  // Virtual Machine Contributor role
          ]
          existenceCondition: {
            allOf: [
              {
                field: 'Microsoft.Compute/virtualMachines/extensions/publisher'
                equals: 'Microsoft.Azure.NetworkWatcher'
              }
              {
                field: 'Microsoft.Compute/virtualMachines/extensions/type'
                equals: 'NetworkWatcherAgentWindows'
              }
              {
                field: 'Microsoft.Compute/virtualMachines/extensions/provisioningState'
                in: [
                  'Succeeded'
                  'Provisioning succeeded'
                ]
              }                  
            ]
          }
          deployment: {
            properties: {
              mode: 'Incremental'
              template: {
                '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
                contentVersion: '1.0.0.0'
                parameters: {
                  vmName: {
                    type: 'string'
                  }
                  location: {
                    type: 'string'
                  }
                }
                resources: [
                  {
                    type: 'Microsoft.Compute/virtualMachines/extensions'
                    apiVersion: '2023-03-01'
                    name: '[concat(parameters(\'vmName\'), \'/AzureNetworkWatcherExtension\')]'
                    location: '[parameters(\'location\')]'
                    properties: {
                      publisher: 'Microsoft.Azure.NetworkWatcher'
                      type: 'NetworkWatcherAgentWindows'
                      typeHandlerVersion: '1.4'
                      autoUpgradeMinorVersion: true
                    }
                  }
                ]
              }
              parameters: {
                vmName: {
                  value: '[field(\'name\')]'
                }
                location: {
                  value: '[field(\'location\')]'
                }
              }
            }
          }
        }
      }
    }
  }
}
 

EDIT: Update 2

After removing the name property from the details object, I got a slightly different error and a new one:

Reason for non-compliance
No related resources match the effect details in the policy definition.
Existence condition
Type
Microsoft.Compute/virtualMachines/extensions
Last evaluated resource (out of 2)
/subscriptions/xxxx--xxxxx-xxxx-xxxxx/resourceGroups/rg-tests-vms/providers/Microsoft.Compute/virtualMachines/vm-win0sserver/extensions/DependencyAgentWindows
Reason for non-compliance
Current value must be equal to the target value.
Field
Microsoft.Compute/virtualMachines/extensions/publisher
Path
properties.publisher
Current value
"Microsoft.Azure.Monitoring.DependencyAgent"
Target value
"Microsoft.Azure.NetworkWatcher"

Edit 3

I tried Stanislav Zhelyazkov's suggestion. To no avail. Here is the result:

The error mesage


Solution

  • I think you are missing the parameters for the template. There are two parameters sections when dealing with policies that have deployments. One set of parameters that are passed by the policy to the template and another set of parameters that are for the template itself so it should look like this:

    targetScope = 'managementGroup'
    
    resource networkWatcherAgentPolicy 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
      name: 'deploy-network-watcher-agent-windows'
      properties: {
        policyType: 'Custom'
        displayName: '[Custom - MyOrg] Deploy Network Watcher Agent on Windows VMs'
        description: 'Automatically deploys the Network Watcher Agent extension on all Windows virtual machines.'
        mode: 'All'
        metadata: {
          version: '1.0.0'
          category: 'Monitoring'
        }
        policyRule: {
          if: {
            allOf: [
              {
                field: 'type'
                equals: 'Microsoft.Compute/virtualMachines'
              }
              {
                field: 'Microsoft.Compute/virtualMachines/storageProfile.osDisk.osType'
                equals: 'Windows'
              }
            ]
          }
          then: {
            effect: 'deployIfNotExists'
            details: {
              type: 'Microsoft.Compute/virtualMachines/extensions'
              name: 'AzureNetworkWatcherExtension'
              roleDefinitionIds: [
                '/providers/Microsoft.Authorization/roleDefinitions/9980e02c-c2be-4d73-94e8-173b1dc7cf3c'
              ]
              existenceCondition: {
                allOf: [
                  {
                    field: 'Microsoft.Compute/virtualMachines/extensions/publisher'
                    equals: 'Microsoft.Azure.NetworkWatcher'
                  }
                  {
                    field: 'Microsoft.Compute/virtualMachines/extensions/type'
                    equals: 'NetworkWatcherAgentWindows'
                  }
                  {
                    field: 'Microsoft.Compute/virtualMachines/extensions/provisioningState'
                    equals: 'Succeeded'
                  }
                ]
              }
              deployment: {
                properties: {
                  mode: 'Incremental'
                  template: {
                    '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
                    contentVersion: '1.0.0.0'
                    parameters: {
                      vmName: {
                        type: 'string'
                      }
                      location: {
                        type: 'string'
                      }
                    }
                    resources: [
                      {
                        type: 'Microsoft.Compute/virtualMachines'
                        apiVersion: '2023-03-01'
                        name: '[parameters(\'vmName\')]'
                        location: '[parameters(\'location\')]'
                        properties: {}
                      }
                      {
                        type: 'Microsoft.Compute/virtualMachines/extensions'
                        apiVersion: '2023-03-01'
                        name: '[concat(parameters(\'vmName\'), \'/AzureNetworkWatcherExtension\')]'
                        dependsOn: [
                          '[concat(\'Microsoft.Compute/virtualMachines/\', parameters(\'vmName\'))]'
                        ]
                        location: '[parameters(\'location\')]'
                        properties: {
                          publisher: 'Microsoft.Azure.NetworkWatcher'
                          type: 'NetworkWatcherAgentWindows'
                          typeHandlerVersion: '1.4'
                          autoUpgradeMinorVersion: true
                        }
                      }
                    ]
                  }
                  parameters: {
                    vmName: {
                      value: '[field(\'name\')]'
                    }
                    location: {
                      value: '[field(\'location\')]'
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    

    Update 1: I have changed a few things and I think now it should work. Things that I have changed according to the original:

    
    targetScope = 'managementGroup'
    
    resource networkWatcherAgentPolicy 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
      name: 'deploy-network-watcher-agent-windows'
      properties: {
        policyType: 'Custom'
        displayName: '[Custom - MyOrg] Deploy Network Watcher Agent on Windows VMs'
        description: 'Automatically deploys the Network Watcher Agent extension on all Windows virtual machines.'
        mode: 'Indexed'
        metadata: {
          version: '1.0.0'
          category: 'Monitoring'
        }
        policyRule: {
          if: {
            allOf: [
              {
                field: 'type'
                equals: 'Microsoft.Compute/virtualMachines'
              }
              {
                field: 'Microsoft.Compute/virtualMachines/storageProfile.osDisk.osType'
                equals: 'Windows'
              }
            ]
          }
          then: {
            effect: 'deployIfNotExists'
            details: {
              type: 'Microsoft.Compute/virtualMachines/extensions'
              roleDefinitionIds: [
                '/providers/Microsoft.Authorization/roleDefinitions/9980e02c-c2be-4d73-94e8-173b1dc7cf3c'
              ]
              existenceCondition: {
                allOf: [
                  {
                    field: 'Microsoft.Compute/virtualMachines/extensions/publisher'
                    equals: 'Microsoft.Azure.NetworkWatcher'
                  }
                  {
                    field: 'Microsoft.Compute/virtualMachines/extensions/type'
                    equals: 'NetworkWatcherAgentWindows'
                  }
                  {
                    field: 'Microsoft.Compute/virtualMachines/extensions/provisioningState'
                    equals: 'Succeeded'
                  }
                ]
              }
              deployment: {
                properties: {
                  mode: 'Incremental'
                  template: {
                    '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
                    contentVersion: '1.0.0.0'
                    parameters: {
                      vmName: {
                        type: 'string'
                      }
                      location: {
                        type: 'string'
                      }
                    }
                    resources: [
                      {
                        type: 'Microsoft.Compute/virtualMachines/extensions'
                        apiVersion: '2023-03-01'
                        name: '[concat(parameters(\'vmName\'), \'/AzureNetworkWatcherExtension\')]'
                        location: '[parameters(\'location\')]'
                        properties: {
                          publisher: 'Microsoft.Azure.NetworkWatcher'
                          type: 'NetworkWatcherAgentWindows'
                          typeHandlerVersion: '1.4'
                          autoUpgradeMinorVersion: true
                        }
                      }
                    ]
                  }
                  parameters: {
                    vmName: {
                      value: '[field(\'name\')]'
                    }
                    location: {
                      value: '[field(\'location\')]'
                    }
                  }
                }
              }
            }
          }
        }
      }
    }