BICEP / GOVERNANCE BASELINE
MANAGEMENT-GROUP GOVERNANCE AS A REUSABLE PLATFORM.
These are the real Bicep files from the final build: the management-group entry point, the working modify remediation policy, and the workbook resource module.
Bicep – management-group baseline deployment
The main management-group template orchestrates the baseline: audit policy, remediation policy, initiative wiring, and assignment. This is the central entry point that turned the project into a reusable governance platform instead of a manual portal build.
mg/main-mg-platform.bicepmanagementGroup scopeinitiative + assignment
BICEPmg/main-mg-platform.bicep
READ ONLY / REAL IMPLEMENTATIONtargetScope = 'managementGroup'
@description('Management group ID where the governance baseline will be deployed.')
param mgId string
module policyPublicNetworkAccess './policy-public-network-access.bicep' = {
name: 'policy-public-network-access'
scope: managementGroup(mgId)
params: {}
}
module policyRemediateStorage './policy-remediate-storage-network-default-deny.bicep' = {
name: 'policy-remediate-storage-disable-blob-public-access'
scope: managementGroup(mgId)
params: {}
}
module initiativeCloudGovernance './initiative-cloud-governance.bicep' = {
name: 'initiative-cloud-governance'
scope: managementGroup(mgId)
params: {
publicNetworkAuditPolicyDefinitionId: policyPublicNetworkAccess.outputs.policyDefinitionId
publicNetworkRemediationPolicyDefinitionId: policyRemediateStorage.outputs.policyDefinitionId
}
}
module assignmentCloudGovernance './assignment-cloud-governance.bicep' = {
name: 'assignment-cloud-governance'
scope: managementGroup(mgId)
params: {
initiativeDefinitionId: initiativeCloudGovernance.outputs.initiativeDefinitionId
}
}
output policyDefinitionId string = policyPublicNetworkAccess.outputs.policyDefinitionId
output remediationPolicyDefinitionId string = policyRemediateStorage.outputs.policyDefinitionId
output initiativeDefinitionId string = initiativeCloudGovernance.outputs.initiativeDefinitionId
output assignmentId string = assignmentCloudGovernance.outputs.assignmentId
output assignmentPrincipalId string = assignmentCloudGovernance.outputs.assignmentPrincipalId
Bicep – final remediation policy definition
The final working remediation path used Azure Policy modify against Storage Account blob public access. This replaced an earlier remediation approach that did not produce a reliable remediable target.
modify effectallowBlobPublicAccessroleDefinitionIds
BICEPmg/policy-remediate-storage-network-default-deny.bicep
READ ONLY / REAL IMPLEMENTATIONtargetScope = 'managementGroup'
@description('Name of the remediation policy definition.')
param policyName string = 'modify-storage-disable-blob-public-access'
@description('Display name shown in Azure Policy.')
param policyDisplayName string = 'Remediate Storage Accounts to disable blob public access'
@description('Description for the remediation policy.')
param policyDescription string = 'Modifies Storage Accounts so allowBlobPublicAccess is set to false when found non-compliant.'
resource policyDefinition 'Microsoft.Authorization/policyDefinitions@2025-03-01' = {
name: policyName
properties: {
policyType: 'Custom'
mode: 'Indexed'
displayName: policyDisplayName
description: policyDescription
metadata: {
category: 'Storage'
version: '2.0.0'
}
parameters: {}
policyRule: {
if: {
allOf: [
{
field: 'type'
equals: 'Microsoft.Storage/storageAccounts'
}
{
field: 'Microsoft.Storage/storageAccounts/allowBlobPublicAccess'
notEquals: false
}
]
}
then: {
effect: 'modify'
details: {
roleDefinitionIds: [
'/providers/Microsoft.Authorization/roleDefinitions/17d1049b-9a84-46fb-8f53-869881c3d3ab'
]
conflictEffect: 'audit'
operations: [
{
operation: 'addOrReplace'
field: 'Microsoft.Storage/storageAccounts/allowBlobPublicAccess'
value: false
}
]
}
}
}
}
}
output policyDefinitionId string = policyDefinition.id
output policyDefinitionName string = policyDefinition.name
Bicep – workbook resource module
The workbook is also deployed as code. That matters because the visual layer stays versioned in the same repository as the policy and alert logic.
BICEPinfra/modules/workbook.bicep
READ ONLY / REAL IMPLEMENTATIONtargetScope = 'resourceGroup'
@description('Location for the workbook resource.')
param location string
@description('Name of the workbook.')
param workbookDisplayName string = 'Cloud Policy Compliance Dashboard'
@description('Resource ID of the Log Analytics workspace.')
param logAnalyticsWorkspaceId string
@description('Serialized workbook data JSON.')
param workbookData string
resource workbook 'Microsoft.Insights/workbooks@2023-06-01' = {
name: guid(workbookDisplayName, resourceGroup().id)
location: location
kind: 'shared'
properties: {
displayName: workbookDisplayName
sourceId: logAnalyticsWorkspaceId
category: 'workbook'
serializedData: workbookData
}
}
output workbookId string = workbook.id
output workbookName string = workbook.name