diff --git a/src/bicep/README.md b/src/bicep/README.md index feb4e4ca2..ae0419a0e 100644 --- a/src/bicep/README.md +++ b/src/bicep/README.md @@ -129,5 +129,8 @@ spokes.value[0..2].subnetResourceId spokes.value[0..2].subscriptionId spokes.value[0..2].virtualNetworkName spokes.value[0..2].virtualNetworkResourceId +deployPolicy.value +policyName.value deployDefender.value emailSecurityContact.value + diff --git a/src/bicep/add-ons/tier3/README.md b/src/bicep/add-ons/tier3/README.md index 30ab414fe..91a164354 100644 --- a/src/bicep/add-ons/tier3/README.md +++ b/src/bicep/add-ons/tier3/README.md @@ -27,6 +27,8 @@ resourcePrefix | mlz | A prefix, 3 to 10 characters in length, to append to reso Optional Parameters | Default | Description ------------------- | ------- | ----------- virtualNetworkAddressPrefix | 10.0.125.0/26 | The address prefix for the network spoke vnet. +deployPolicy | Output from mlz.bicep (false) | When set to "true", deploys the Azure Policy set defined at by the parameter "policy" to the resource groups generated in the deployment. It defaults to "false". +policy | Output from mlz.bicep (Nist) | [NIST/IL5/CMMC] Built-in policy assignments to assign, it defaults to "NIST". IL5 is only available for AzureUsGovernment and will switch to NIST if tried in AzureCloud. ### Generate MLZ Variable File diff --git a/src/bicep/add-ons/tier3/tier3.bicep b/src/bicep/add-ons/tier3/tier3.bicep index 79b2a9a79..db6f9a9fd 100644 --- a/src/bicep/add-ons/tier3/tier3.bicep +++ b/src/bicep/add-ons/tier3/tier3.bicep @@ -42,6 +42,11 @@ param hubVirtualNetworkResourceId string = mlzDeploymentVariables.hub.Value.virt param logAnalyticsWorkspaceResourceId string = mlzDeploymentVariables.logAnalyticsWorkspaceResourceId.Value param logAnalyticsWorkspaceName string = mlzDeploymentVariables.logAnalyticsWorkspaceName.Value param firewallPrivateIPAddress string = mlzDeploymentVariables.firewallPrivateIPAddress.Value +@description('[NIST/IL5/CMMC] Built-in policy assignments to assign, it defaults to "NIST". IL5 is only available for AzureUsGovernment and will switch to NIST if tried in AzureCloud.') +param policy string = mlzDeploymentVariables.policyName.Value +@description('When set to "true", deploys the Azure Policy set defined at by the parameter "policy" to the resource groups generated in the deployment. It defaults to "false".') +param deployPolicy bool = mlzDeploymentVariables.deployPolicy.Value + @description('When set to "true", enables Microsoft Defender for Cloud for the subscriptions used in the deployment. It defaults to "false".') param deployDefender bool = mlzDeploymentVariables.deployDefender.Value @@ -85,7 +90,10 @@ param subnetServiceEndpoints array = [] param logStorageSkuName string = 'Standard_GRS' @description('A string dictionary of tags to add to deployed resources. See https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json#arm-templates for valid settings.') -param tags object = {} +param tags object = {} + +@description('A suffix to use for naming deployments uniquely. It defaults to the Bicep resolution of the "utcNow()" function.') +param deploymentNameSuffix string = utcNow() /* @@ -117,6 +125,7 @@ var workloadLogStorageAccountName = take(workloadLogStorageAccountUniqueName, 23 var workloadVirtualNetworkName = replace(virtualNetworkNamingConvention, nameToken, workloadName) var workloadNetworkSecurityGroupName = replace(networkSecurityGroupNamingConvention, nameToken, workloadName) var workloadSubnetName = replace(subnetNamingConvention, nameToken, workloadName) +var logAnalyticsWorkspaceResourceId_split = split(logAnalyticsWorkspaceResourceId, '/') var defaultTags = { DeploymentType: 'MissionLandingZoneARM' @@ -199,6 +208,18 @@ module workloadSubscriptionActivityLogging '../../modules/central-logging.bicep' ] } +module workloadPolicyAssignment '../../modules/policy-assignment.bicep' = if (deployPolicy) { + name: 'assign-policy-${workloadName}-${deploymentNameSuffix}' + scope: az.resourceGroup(workloadSubscriptionId, resourceGroup.name) + params: { + builtInAssignment: policy + logAnalyticsWorkspaceName: logAnalyticsWorkspaceResourceId_split[8] + logAnalyticsWorkspaceResourceGroupName: logAnalyticsWorkspaceResourceId_split[4] + location: location + operationsSubscriptionId: logAnalyticsWorkspaceResourceId_split[2] + } + } + module spokeDefender '../../modules/defender.bicep' = if (deployDefender) { name: 'set-${workloadName}-sub-defender' scope: subscription(workloadSubscriptionId) diff --git a/src/bicep/mlz.bicep b/src/bicep/mlz.bicep index e08253a80..6aa1db9ea 100644 --- a/src/bicep/mlz.bicep +++ b/src/bicep/mlz.bicep @@ -1107,6 +1107,10 @@ output logAnalyticsWorkspaceResourceId string = logAnalyticsWorkspace.outputs.id output diagnosticStorageAccountName string = operationsLogStorageAccountName +output policyName string = policy + +output deployPolicy bool = deployPolicy + output spokes array = [for (spoke, i) in spokes: { name: spoke.name subscriptionId: spoke.subscriptionId