Azure Policy Compliance Monitoring: A Solution in Bicep


  1. Create all resources except Event Grid Topic and Subscription
  2. Deploy the Azure Function (Manual or via AZ CLI / Azure Pipeline / VSCode)
  3. Create the Event Grid Topic and Subscription

Resources details

  • Log Analytics Workspace
  • Event Grid Topic and Subscription
  • Function App (Triggered Manually using AZ CLI or from VSCode)
  • Azure Monitor Alert Rule
  • Storage Account
  • Azure Monitor Metrics
  • Key Vault


Understanding the Code

targetScope = 'subscription'
param policyMonitorData object
module PolicyMonitorFunctionAppDep 'deploymentZone.bicep' = [for (rg, i) in policyMonitorData.resourceGroupArray: {
name: '${policyMonitorData.client}-PolicyMonitorFunctionAppDeployment-${i}'
params: {
commonTags: policyMonitorData.commonTagsForResources
customer: policyMonitorData.client
resourceGroup: rg
"storageAccountArray": [
"name": "logs",
"skuName": "Standard_LRS",
"logAnalytics": {
"logStorageAccountNameRef": "logs",
"logWorkSpaceNameRef": "PolicyMonitor"
"tags": {
"App": "Storage"
"name": "pmfn",
"skuName": "Standard_LRS",
"logAnalytics": {
"logStorageAccountNameRef": "logs",
"logWorkSpaceNameRef": "PolicyMonitor"
"tags": {
"App": "Storage"
resource rgs 'Microsoft.Resources/resourceGroups@2021-04-01' = {
name: 'RG-${customer}-${resourceGroup.rgName}'
location: resourceGroup.rgLocation
tags: union(commonTags, resourceGroup.tags)

Deploying the Function app

Deploying using Azure DevOps Pipeline

functionWorkingDirectory: 'function'
functionAppName: 'FN-PolicyMonitor'
- task: ArchiveFiles@2
displayName: 'Archive Function directory'
rootFolderOrFile: $(functionWorkingDirectory)
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/
replaceExistingArchive: true
- publish: $(Build.ArtifactStagingDirectory)/
artifact: drop
- task: AzureFunctionApp@1
displayName: 'Azure functions app deploy'
appType: functionAppLinux
appName: $(functionAppName)
package: '$(Pipeline.Workspace)/drop/'

Deploy using AZ cli

az functionapp deploy --resource-group <Reosurce group Name> --name <Function App Name> --src-path <Path to the zip file> --type zip

Deploy using Powershell

$creds = Invoke-AzureRmResourceAction -ResourceGroupName <Reosurce group Name> -ResourceType Microsoft.Web/sites/config -ResourceName <App Name>/publishingcredentials -Action list -ApiVersion 2015-08-01 -Force$username = $creds.Properties.PublishingUserName$password = $creds.Properties.PublishingPassword$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))$apiUrl = "https://<yourFunctionApp>"$filePath = "<yourFunctionName>.zip"Invoke-RestMethod -Uri $apiUrl -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method PUT -InFile $filePath -ContentType "multipart/form-data"

Install Azure CLI

Authenticate Azure CLI

Trigger Manually




Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Announcing the Launch of Unloc on Devnet — Put Your NFTs to Work

Python Socket Communication

Generate API client with OpenApi codegen

MesosCon Europe 2017: themes and trends

Kubernetes in nutshell

Literal 0 and Enum relation in C#


No-code 101: What, Why, and How?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Arlan Nugara

Arlan Nugara

More from Medium

Your Future in Azure Cloud Technology.

Network Security Groups in Azure — The Fundamentals , Which Direction to Apply Rules, What would…

Your Azure Architecture Diagrams Explained — Excerpt

Azure architecture diagram generated with Clouduockit

Creating VM on a virtual network in Azure