diff --git a/policyDefinitions/Security Center/deploy-export-to-event-hub-for-mdfc/azurepolicy.json b/policyDefinitions/Security Center/deploy-export-to-event-hub-for-mdfc/azurepolicy.json new file mode 100644 index 00000000..ca9b9478 --- /dev/null +++ b/policyDefinitions/Security Center/deploy-export-to-event-hub-for-mdfc/azurepolicy.json @@ -0,0 +1,737 @@ +{ + "name": "57ef7078-bc66-4739-83d8-d1715a70d91a", + "type": "Microsoft.Authorization/policyDefinitions", + "properties": { + "displayName": "Deploy export to Event Hub for MDfC", + "description": "Deploys Microsoft Defender for Cloud continuous export to an Event Hub via a SAS authorization rule, and applies resource group tags. Why: the built-in export policies create the resource group without tags, so where mandatory tags are enforced at creation the remediation is blocked and export never deploys. Pass resourceGroupTags so the group is created or merged with the required tags. Use createResourceGroup true for a new group or false to merge tags into an existing one.", + "metadata": { + "version": "1.0.0", + "category": "Security Center" + }, + "mode": "All", + "parameters": { + "resourceGroupName": { + "type": "String", + "metadata": { + "displayName": "Resource group name", + "description": "The resource group name where the export to Event Hub configuration is created. If you enter a name for a resource group that doesn't exist, it'll be created in the subscription. Note that each resource group can only have one export to Event Hub configured." + } + }, + "resourceGroupLocation": { + "type": "String", + "metadata": { + "displayName": "Resource group location", + "description": "The location where the resource group and the export to Event Hub configuration are created.", + "strongType": "location" + } + }, + "createResourceGroup": { + "type": "Boolean", + "metadata": { + "displayName": "Create resource group", + "description": "Use true only for a new resource group. Use false for an existing group to preserve and merge its tags. After initial creation, change this to false before subsequent remediation. True redeploys the group and can replace existing tags." + }, + "allowedValues": [ + true, + false + ], + "defaultValue": true + }, + "resourceGroupTags": { + "type": "Object", + "metadata": { + "displayName": "Resource group tags", + "description": "Tags applied at creation or merged into an existing group when createResourceGroup is false. Supplied values override matching tag names; an empty object leaves existing tags unchanged in existing-group mode." + }, + "defaultValue": {} + }, + "exportedDataTypes": { + "type": "Array", + "metadata": { + "displayName": "Exported data types", + "description": "Select at least one data type. Snapshot data is exported once a week; other data is streamed in real time. Empty arrays are rejected during deployment." + }, + "allowedValues": [ + "Security recommendations", + "Security alerts", + "Overall secure score", + "Secure score controls", + "Regulatory compliance", + "Overall secure score - snapshot", + "Secure score controls - snapshot", + "Regulatory compliance - snapshot", + "Security recommendations - snapshot", + "Security findings - snapshot" + ], + "defaultValue": [ + "Security recommendations", + "Security alerts", + "Overall secure score", + "Secure score controls", + "Regulatory compliance", + "Overall secure score - snapshot", + "Secure score controls - snapshot", + "Regulatory compliance - snapshot", + "Security recommendations - snapshot", + "Security findings - snapshot" + ] + }, + "recommendationNames": { + "type": "Array", + "metadata": { + "displayName": "Recommendation IDs", + "description": "Applicable only for export of security recommendations. To export all recommendations, leave this empty. To export specific recommendations, enter a list of recommendation IDs separated by semicolons (';'). Recommendation IDs are available through the Assessments API (https://docs.microsoft.com/rest/api/securitycenter/assessments), or Azure Resource Graph Explorer, choose securityresources and microsoft.security/assessments." + }, + "defaultValue": [] + }, + "recommendationSeverities": { + "type": "Array", + "metadata": { + "displayName": "Recommendation severities", + "description": "Recommendation severities to export. Select at least one severity; empty arrays are rejected during deployment. Example: High;Medium;Low;" + }, + "allowedValues": [ + "High", + "Medium", + "Low" + ], + "defaultValue": [ + "High", + "Medium", + "Low" + ] + }, + "isSecurityFindingsEnabled": { + "type": "Boolean", + "metadata": { + "displayName": "Include security findings", + "description": "Security findings are results from vulnerability assessment solutions, and can be thought of as 'sub' recommendations grouped into a 'parent' recommendation." + }, + "allowedValues": [ + true, + false + ], + "defaultValue": true + }, + "secureScoreControlsNames": { + "type": "Array", + "metadata": { + "displayName": "Secure Score Controls IDs", + "description": "Applicable only for export of secure score controls. To export all secure score controls, leave this empty. To export specific secure score controls, enter a list of secure score controls IDs separated by semicolons (';'). Secure score controls IDs are available through the Secure score controls API (https://docs.microsoft.com/rest/api/securitycenter/securescorecontrols), or Azure Resource Graph Explorer, choose securityresources and microsoft.security/securescores/securescorecontrols." + }, + "defaultValue": [] + }, + "alertSeverities": { + "type": "Array", + "metadata": { + "displayName": "Alert severities", + "description": "Alert severities to export. Select at least one severity; empty arrays are rejected during deployment. Example: High;Medium;Low;" + }, + "allowedValues": [ + "High", + "Medium", + "Low" + ], + "defaultValue": [ + "High", + "Medium", + "Low" + ] + }, + "regulatoryComplianceStandardsNames": { + "type": "Array", + "metadata": { + "displayName": "Regulatory compliance standards names", + "description": "Applicable only for export of regulatory compliance. To export all regulatory compliance, leave this empty. To export specific regulatory compliance standards, enter a list of these standards names separated by semicolons (';'). Regulatory compliance standards names are available through the regulatory compliance standards API (https://docs.microsoft.com/rest/api/securitycenter/regulatorycompliancestandards), or Azure Resource Graph Explorer, choose securityresources and microsoft.security/regulatorycompliancestandards." + }, + "defaultValue": [] + }, + "eventHubDetails": { + "type": "String", + "metadata": { + "displayName": "Event Hub details", + "description": "The Event Hub details of where the data should be exported to: Subscription, Event Hub Namespace, Event Hub, and Authorizations rules with 'Send' claim.", + "strongType": "Microsoft.EventHub/namespaces/eventhubs/authorizationrules", + "assignPermissions": true + } + }, + "effect": { + "type": "String", + "metadata": { + "displayName": "Effect", + "description": "DeployIfNotExists, AuditIfNotExists or Disabled the execution of the Policy" + }, + "allowedValues": [ + "DeployIfNotExists", + "AuditIfNotExists", + "Disabled" + ], + "defaultValue": "DeployIfNotExists" + } + }, + "policyRule": { + "if": { + "field": "type", + "equals": "Microsoft.Resources/subscriptions" + }, + "then": { + "effect": "[parameters('effect')]", + "details": { + "type": "Microsoft.Security/automations", + "name": "exportToEventHub", + "existenceScope": "resourcegroup", + "ResourceGroupName": "[parameters('resourceGroupName')]", + "deploymentScope": "subscription", + "roleDefinitionIds": [ + "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" + ], + "existenceCondition": { + "allOf": [ + { + "field": "Microsoft.Security/automations/isEnabled", + "equals": true + }, + { + "count": { + "field": "Microsoft.Security/automations/actions[*]", + "where": { + "allOf": [ + { + "field": "Microsoft.Security/automations/actions[*].actionType", + "equals": "EventHub" + }, + { + "field": "Microsoft.Security/automations/actions[*].EventHub.eventHubResourceId", + "equals": "[join(take(split(parameters('eventHubDetails'), '/'), 11), '/')]" + }, + { + "anyOf": [ + { + "field": "Microsoft.Security/automations/actions[*].EventHub.isTrustedServiceEnabled", + "exists": "false" + }, + { + "field": "Microsoft.Security/automations/actions[*].EventHub.isTrustedServiceEnabled", + "equals": false + } + ] + } + ] + } + }, + "equals": 1 + }, + { + "count": { + "field": "Microsoft.Security/automations/sources[*]" + }, + "equals": "[if(parameters('isSecurityFindingsEnabled'),add(length(parameters('exportedDataTypes')),1),length(parameters('exportedDataTypes')))]" + }, + { + "count": { + "value": "[parameters('exportedDataTypes')]", + "name": "dataType", + "where": { + "count": { + "field": "Microsoft.Security/automations/sources[*]", + "where": { + "anyOf": [ + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "Assessments" + }, + { + "value": "[current('dataType')]", + "equals": "Security recommendations" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "Alerts" + }, + { + "value": "[current('dataType')]", + "equals": "Security alerts" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SecureScores" + }, + { + "value": "[current('dataType')]", + "equals": "Overall secure score" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SecureScoreControls" + }, + { + "value": "[current('dataType')]", + "equals": "Secure score controls" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "RegulatoryComplianceAssessment" + }, + { + "value": "[current('dataType')]", + "equals": "Regulatory compliance" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SecureScoresSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Overall secure score - snapshot" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SecureScoreControlsSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Secure score controls - snapshot" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "RegulatoryComplianceAssessmentSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Regulatory compliance - snapshot" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "AssessmentsSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Security recommendations - snapshot" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SubAssessmentsSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Security findings - snapshot" + } + ] + } + ] + } + }, + "equals": 1 + } + }, + "equals": "[length(parameters('exportedDataTypes'))]" + } + ] + }, + "deployment": { + "location": "westeurope", + "properties": { + "mode": "incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string" + }, + "resourceGroupLocation": { + "type": "string" + }, + "createResourceGroup": { + "type": "bool" + }, + "resourceGroupTags": { + "type": "object" + }, + "exportedDataTypes": { + "type": "array", + "minLength": 1 + }, + "isSecurityFindingsEnabled": { + "type": "bool" + }, + "recommendationNames": { + "type": "array" + }, + "secureScoreControlsNames": { + "type": "array" + }, + "regulatoryComplianceStandardsNames": { + "type": "array" + }, + "recommendationSeverities": { + "type": "array", + "minLength": 1 + }, + "alertSeverities": { + "type": "array", + "minLength": 1 + }, + "eventHubDetails": { + "type": "string" + }, + "guidValue": { + "type": "string", + "defaultValue": "[newGuid()]" + } + }, + "variables": { + "scopeDescription": "scope for subscription {0}", + "subAssessmentRuleExpectedValue": "/assessments/{0}/", + "recommendationNamesLength": "[length(parameters('recommendationNames'))]", + "secureScoreControlsNamesLength": "[length(parameters('secureScoreControlsNames'))]", + "secureScoreControlsLengthIfEmpty": "[if(equals(variables('secureScoreControlsNamesLength'), 0), 1, variables('secureScoreControlsNamesLength'))]", + "regulatoryComplianceStandardsNamesLength": "[length(parameters('regulatoryComplianceStandardsNames'))]", + "regulatoryComplianceStandardsNamesLengthIfEmpty": "[if(equals(variables('regulatoryComplianceStandardsNamesLength'), 0), 1, variables('regulatoryComplianceStandardsNamesLength'))]", + "recommendationSeveritiesLength": "[length(parameters('recommendationSeverities'))]", + "alertSeveritiesLength": "[length(parameters('alertSeverities'))]", + "recommendationNamesLengthIfEmpty": "[if(equals(variables('recommendationNamesLength'), 0), 1, variables('recommendationNamesLength'))]", + "recommendationSeveritiesLengthIfEmpty": "[if(equals(variables('recommendationSeveritiesLength'), 0), 1, variables('recommendationSeveritiesLength'))]", + "alertSeveritiesLengthIfEmpty": "[if(equals(variables('alertSeveritiesLength'), 0), 1, variables('alertSeveritiesLength'))]", + "totalRuleCombinationsForOneRecommendationName": "[variables('recommendationSeveritiesLengthIfEmpty')]", + "totalRuleCombinationsForOneRecommendationSeverity": 1, + "exportedDataTypesLength": "[length(parameters('exportedDataTypes'))]", + "exportedDataTypesLengthIfEmpty": "[if(equals(variables('exportedDataTypesLength'), 0), 1, variables('exportedDataTypesLength'))]", + "dataTypeMap": { + "Security recommendations": "Assessments", + "Security alerts": "Alerts", + "Overall secure score": "SecureScores", + "Secure score controls": "SecureScoreControls", + "Regulatory compliance": "RegulatoryComplianceAssessment", + "Overall secure score - snapshot": "SecureScoresSnapshot", + "Secure score controls - snapshot": "SecureScoreControlsSnapshot", + "Regulatory compliance - snapshot": "RegulatoryComplianceAssessmentSnapshot", + "Security recommendations - snapshot": "AssessmentsSnapshot", + "Security findings - snapshot": "SubAssessmentsSnapshot" + }, + "alertSeverityMap": { + "High": "high", + "Medium": "medium", + "Low": "low" + }, + "ruleSetsForAssessmentsObj": { + "copy": [ + { + "name": "ruleSetsForAssessmentsArr", + "count": "[mul(variables('recommendationNamesLengthIfEmpty'),variables('recommendationSeveritiesLengthIfEmpty'))]", + "input": { + "rules": [ + { + "propertyJPath": "[if(equals(variables('recommendationNamesLength'),0),'type','name')]", + "propertyType": "string", + "expectedValue": "[if(equals(variables('recommendationNamesLength'),0),'Microsoft.Security/assessments',parameters('recommendationNames')[mod(div(copyIndex('ruleSetsForAssessmentsArr'),variables('totalRuleCombinationsForOneRecommendationName')),variables('recommendationNamesLength'))])]", + "operator": "Contains" + }, + { + "propertyJPath": "properties.metadata.severity", + "propertyType": "string", + "expectedValue": "[parameters('recommendationSeverities')[mod(div(copyIndex('ruleSetsForAssessmentsArr'),variables('totalRuleCombinationsForOneRecommendationSeverity')),variables('recommendationSeveritiesLength'))]]", + "operator": "Equals" + } + ] + } + } + ] + }, + "customRuleSetsForSubAssessmentsObj": { + "copy": [ + { + "name": "ruleSetsForSubAssessmentsArr", + "count": "[variables('recommendationNamesLengthIfEmpty')]", + "input": { + "rules": [ + { + "propertyJPath": "id", + "propertyType": "string", + "expectedValue": "[if(equals(variables('recommendationNamesLength'), 0), json('null'), replace(variables('subAssessmentRuleExpectedValue'),'{0}', parameters('recommendationNames')[copyIndex('ruleSetsForSubAssessmentsArr')]))]", + "operator": "Contains" + } + ] + } + } + ] + }, + "ruleSetsForAlertsObj": { + "copy": [ + { + "name": "ruleSetsForAlertsArr", + "count": "[variables('alertSeveritiesLengthIfEmpty')]", + "input": { + "rules": [ + { + "propertyJPath": "Severity", + "propertyType": "string", + "expectedValue": "[variables('alertSeverityMap')[parameters('alertSeverities')[mod(copyIndex('ruleSetsForAlertsArr'),variables('alertSeveritiesLengthIfEmpty'))]]]", + "operator": "Equals" + } + ] + } + } + ] + }, + "customRuleSetsForSecureScoreControlsObj": { + "copy": [ + { + "name": "ruleSetsForSecureScoreControlsArr", + "count": "[variables('secureScoreControlsLengthIfEmpty')]", + "input": { + "rules": [ + { + "propertyJPath": "name", + "propertyType": "string", + "expectedValue": "[if(equals(variables('secureScoreControlsNamesLength'), 0), json('null'), parameters('secureScoreControlsNames')[copyIndex('ruleSetsForSecureScoreControlsArr')])]", + "operator": "Equals" + } + ] + } + } + ] + }, + "customRuleSetsForRegulatoryComplianceObj": { + "copy": [ + { + "name": "ruleSetsForRegulatoryCompliancArr", + "count": "[variables('regulatoryComplianceStandardsNamesLengthIfEmpty')]", + "input": { + "rules": [ + { + "propertyJPath": "id", + "propertyType": "string", + "expectedValue": "[if(equals(variables('regulatoryComplianceStandardsNamesLength'), 0), json('null'), parameters('regulatoryComplianceStandardsNames')[copyIndex('ruleSetsForRegulatoryCompliancArr')])]", + "operator": "Contains" + } + ] + } + } + ] + }, + "ruleSetsForSecureScoreControlsObj": "[if(equals(variables('secureScoreControlsNamesLength'), 0), json('null'), variables('customRuleSetsForSecureScoreControlsObj').ruleSetsForSecureScoreControlsArr)]", + "ruleSetsForSecureRegulatoryComplianceObj": "[if(equals(variables('regulatoryComplianceStandardsNamesLength'), 0), json('null'), variables('customRuleSetsForRegulatoryComplianceObj').ruleSetsForRegulatoryCompliancArr)]", + "ruleSetsForSubAssessmentsObj": "[if(equals(variables('recommendationNamesLength'), 0), json('null'), variables('customRuleSetsForSubAssessmentsObj').ruleSetsForSubAssessmentsArr)]", + "subAssessmentSource": [ + { + "eventSource": "SubAssessments", + "ruleSets": "[variables('ruleSetsForSubAssessmentsObj')]" + } + ], + "ruleSetsMap": { + "Security recommendations": "[variables('ruleSetsForAssessmentsObj').ruleSetsForAssessmentsArr]", + "Security alerts": "[variables('ruleSetsForAlertsObj').ruleSetsForAlertsArr]", + "Overall secure score": null, + "Secure score controls": "[variables('ruleSetsForSecureScoreControlsObj')]", + "Regulatory compliance": "[variables('ruleSetsForSecureRegulatoryComplianceObj')]", + "Overall secure score - snapshot": null, + "Secure score controls - snapshot": "[variables('ruleSetsForSecureScoreControlsObj')]", + "Regulatory compliance - snapshot": "[variables('ruleSetsForSecureRegulatoryComplianceObj')]", + "Security recommendations - snapshot": "[variables('ruleSetsForAssessmentsObj').ruleSetsForAssessmentsArr]", + "Security findings - snapshot": "[variables('ruleSetsForSubAssessmentsObj')]" + }, + "sourcesWithoutSubAssessments": { + "copy": [ + { + "name": "sources", + "count": "[variables('exportedDataTypesLengthIfEmpty')]", + "input": { + "eventSource": "[variables('dataTypeMap')[parameters('exportedDataTypes')[copyIndex('sources')]]]", + "ruleSets": "[variables('ruleSetsMap')[parameters('exportedDataTypes')[copyIndex('sources')]]]" + } + } + ] + }, + "sourcesWithSubAssessments": "[concat(variables('subAssessmentSource'),variables('sourcesWithoutSubAssessments').sources)]", + "sources": "[if(equals(parameters('isSecurityFindingsEnabled'),bool('true')),variables('sourcesWithSubAssessments'),variables('sourcesWithoutSubAssessments').sources)]" + }, + "resources": [ + { + "condition": "[parameters('createResourceGroup')]", + "name": "[parameters('resourceGroupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2019-10-01", + "location": "[parameters('resourceGroupLocation')]", + "tags": "[parameters('resourceGroupTags')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2019-10-01", + "name": "[concat('nestedAutomationDeployment', '_', parameters('guidValue'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('resourceGroupName'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupTags": { + "type": "object" + }, + "sources": { + "type": "array" + }, + "scopeDescription": { + "type": "string" + }, + "eventHubResourceId": { + "type": "string" + }, + "connectionString": { + "type": "securestring" + } + }, + "variables": { + "mergedTags": "[union(if(equals(resourceGroup().tags, json('null')), json('{}'), resourceGroup().tags), parameters('resourceGroupTags'))]" + }, + "resources": [ + { + "condition": "[not(empty(parameters('resourceGroupTags')))]", + "apiVersion": "2021-04-01", + "name": "default", + "type": "Microsoft.Resources/tags", + "properties": { + "tags": "[variables('mergedTags')]" + } + }, + { + "tags": "[variables('mergedTags')]", + "apiVersion": "2019-01-01-preview", + "location": "[resourceGroup().location]", + "name": "exportToEventHub", + "type": "Microsoft.Security/automations", + "dependsOn": [ + "[resourceId('Microsoft.Resources/tags', 'default')]" + ], + "properties": { + "description": "Export Microsoft Defender for Cloud data to Event Hub via policy", + "isEnabled": true, + "scopes": [ + { + "description": "[parameters('scopeDescription')]", + "scopePath": "[subscription().id]" + } + ], + "sources": "[parameters('sources')]", + "actions": [ + { + "actionType": "EventHub", + "eventHubResourceId": "[parameters('eventHubResourceId')]", + "connectionString": "[parameters('connectionString')]" + } + ] + } + } + ] + }, + "parameters": { + "resourceGroupTags": { + "value": "[parameters('resourceGroupTags')]" + }, + "sources": { + "value": "[variables('sources')]" + }, + "scopeDescription": { + "value": "[replace(variables('scopeDescription'), '{0}', subscription().subscriptionId)]" + }, + "eventHubResourceId": { + "value": "[join(take(split(parameters('eventHubDetails'), '/'), 11), '/')]" + }, + "connectionString": { + "value": "[listKeys(parameters('eventHubDetails'), '2017-04-01').primaryConnectionString]" + } + } + } + } + ] + }, + "parameters": { + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "resourceGroupLocation": { + "value": "[parameters('resourceGroupLocation')]" + }, + "createResourceGroup": { + "value": "[parameters('createResourceGroup')]" + }, + "resourceGroupTags": { + "value": "[parameters('resourceGroupTags')]" + }, + "exportedDataTypes": { + "value": "[parameters('exportedDataTypes')]" + }, + "recommendationNames": { + "value": "[parameters('recommendationNames')]" + }, + "isSecurityFindingsEnabled": { + "value": "[parameters('isSecurityFindingsEnabled')]" + }, + "secureScoreControlsNames": { + "value": "[parameters('secureScoreControlsNames')]" + }, + "recommendationSeverities": { + "value": "[parameters('recommendationSeverities')]" + }, + "alertSeverities": { + "value": "[parameters('alertSeverities')]" + }, + "regulatoryComplianceStandardsNames": { + "value": "[parameters('regulatoryComplianceStandardsNames')]" + }, + "eventHubDetails": { + "value": "[parameters('eventHubDetails')]" + } + } + } + } + } + } + } + } +} diff --git a/policyDefinitions/Security Center/deploy-export-to-event-hub-for-mdfc/azurepolicy.parameters.json b/policyDefinitions/Security Center/deploy-export-to-event-hub-for-mdfc/azurepolicy.parameters.json new file mode 100644 index 00000000..bdd0f0d6 --- /dev/null +++ b/policyDefinitions/Security Center/deploy-export-to-event-hub-for-mdfc/azurepolicy.parameters.json @@ -0,0 +1,160 @@ +{ + "resourceGroupName": { + "type": "String", + "metadata": { + "displayName": "Resource group name", + "description": "The resource group name where the export to Event Hub configuration is created. If you enter a name for a resource group that doesn't exist, it'll be created in the subscription. Note that each resource group can only have one export to Event Hub configured." + } + }, + "resourceGroupLocation": { + "type": "String", + "metadata": { + "displayName": "Resource group location", + "description": "The location where the resource group and the export to Event Hub configuration are created.", + "strongType": "location" + } + }, + "createResourceGroup": { + "type": "Boolean", + "metadata": { + "displayName": "Create resource group", + "description": "Use true only for a new resource group. Use false for an existing group to preserve and merge its tags. After initial creation, change this to false before subsequent remediation. True redeploys the group and can replace existing tags." + }, + "allowedValues": [ + true, + false + ], + "defaultValue": true + }, + "resourceGroupTags": { + "type": "Object", + "metadata": { + "displayName": "Resource group tags", + "description": "Tags applied at creation or merged into an existing group when createResourceGroup is false. Supplied values override matching tag names; an empty object leaves existing tags unchanged in existing-group mode." + }, + "defaultValue": {} + }, + "exportedDataTypes": { + "type": "Array", + "metadata": { + "displayName": "Exported data types", + "description": "Select at least one data type. Snapshot data is exported once a week; other data is streamed in real time. Empty arrays are rejected during deployment." + }, + "allowedValues": [ + "Security recommendations", + "Security alerts", + "Overall secure score", + "Secure score controls", + "Regulatory compliance", + "Overall secure score - snapshot", + "Secure score controls - snapshot", + "Regulatory compliance - snapshot", + "Security recommendations - snapshot", + "Security findings - snapshot" + ], + "defaultValue": [ + "Security recommendations", + "Security alerts", + "Overall secure score", + "Secure score controls", + "Regulatory compliance", + "Overall secure score - snapshot", + "Secure score controls - snapshot", + "Regulatory compliance - snapshot", + "Security recommendations - snapshot", + "Security findings - snapshot" + ] + }, + "recommendationNames": { + "type": "Array", + "metadata": { + "displayName": "Recommendation IDs", + "description": "Applicable only for export of security recommendations. To export all recommendations, leave this empty. To export specific recommendations, enter a list of recommendation IDs separated by semicolons (';'). Recommendation IDs are available through the Assessments API (https://docs.microsoft.com/rest/api/securitycenter/assessments), or Azure Resource Graph Explorer, choose securityresources and microsoft.security/assessments." + }, + "defaultValue": [] + }, + "recommendationSeverities": { + "type": "Array", + "metadata": { + "displayName": "Recommendation severities", + "description": "Recommendation severities to export. Select at least one severity; empty arrays are rejected during deployment. Example: High;Medium;Low;" + }, + "allowedValues": [ + "High", + "Medium", + "Low" + ], + "defaultValue": [ + "High", + "Medium", + "Low" + ] + }, + "isSecurityFindingsEnabled": { + "type": "Boolean", + "metadata": { + "displayName": "Include security findings", + "description": "Security findings are results from vulnerability assessment solutions, and can be thought of as 'sub' recommendations grouped into a 'parent' recommendation." + }, + "allowedValues": [ + true, + false + ], + "defaultValue": true + }, + "secureScoreControlsNames": { + "type": "Array", + "metadata": { + "displayName": "Secure Score Controls IDs", + "description": "Applicable only for export of secure score controls. To export all secure score controls, leave this empty. To export specific secure score controls, enter a list of secure score controls IDs separated by semicolons (';'). Secure score controls IDs are available through the Secure score controls API (https://docs.microsoft.com/rest/api/securitycenter/securescorecontrols), or Azure Resource Graph Explorer, choose securityresources and microsoft.security/securescores/securescorecontrols." + }, + "defaultValue": [] + }, + "alertSeverities": { + "type": "Array", + "metadata": { + "displayName": "Alert severities", + "description": "Alert severities to export. Select at least one severity; empty arrays are rejected during deployment. Example: High;Medium;Low;" + }, + "allowedValues": [ + "High", + "Medium", + "Low" + ], + "defaultValue": [ + "High", + "Medium", + "Low" + ] + }, + "regulatoryComplianceStandardsNames": { + "type": "Array", + "metadata": { + "displayName": "Regulatory compliance standards names", + "description": "Applicable only for export of regulatory compliance. To export all regulatory compliance, leave this empty. To export specific regulatory compliance standards, enter a list of these standards names separated by semicolons (';'). Regulatory compliance standards names are available through the regulatory compliance standards API (https://docs.microsoft.com/rest/api/securitycenter/regulatorycompliancestandards), or Azure Resource Graph Explorer, choose securityresources and microsoft.security/regulatorycompliancestandards." + }, + "defaultValue": [] + }, + "eventHubDetails": { + "type": "String", + "metadata": { + "displayName": "Event Hub details", + "description": "The Event Hub details of where the data should be exported to: Subscription, Event Hub Namespace, Event Hub, and Authorizations rules with 'Send' claim.", + "strongType": "Microsoft.EventHub/namespaces/eventhubs/authorizationrules", + "assignPermissions": true + } + }, + "effect": { + "type": "String", + "metadata": { + "displayName": "Effect", + "description": "DeployIfNotExists, AuditIfNotExists or Disabled the execution of the Policy" + }, + "allowedValues": [ + "DeployIfNotExists", + "AuditIfNotExists", + "Disabled" + ], + "defaultValue": "DeployIfNotExists" + } +} diff --git a/policyDefinitions/Security Center/deploy-export-to-event-hub-for-mdfc/azurepolicy.rules.json b/policyDefinitions/Security Center/deploy-export-to-event-hub-for-mdfc/azurepolicy.rules.json new file mode 100644 index 00000000..48330aef --- /dev/null +++ b/policyDefinitions/Security Center/deploy-export-to-event-hub-for-mdfc/azurepolicy.rules.json @@ -0,0 +1,564 @@ +{ + "if": { + "field": "type", + "equals": "Microsoft.Resources/subscriptions" + }, + "then": { + "effect": "[parameters('effect')]", + "details": { + "type": "Microsoft.Security/automations", + "name": "exportToEventHub", + "existenceScope": "resourcegroup", + "ResourceGroupName": "[parameters('resourceGroupName')]", + "deploymentScope": "subscription", + "roleDefinitionIds": [ + "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c" + ], + "existenceCondition": { + "allOf": [ + { + "field": "Microsoft.Security/automations/isEnabled", + "equals": true + }, + { + "count": { + "field": "Microsoft.Security/automations/actions[*]", + "where": { + "allOf": [ + { + "field": "Microsoft.Security/automations/actions[*].actionType", + "equals": "EventHub" + }, + { + "field": "Microsoft.Security/automations/actions[*].EventHub.eventHubResourceId", + "equals": "[join(take(split(parameters('eventHubDetails'), '/'), 11), '/')]" + }, + { + "anyOf": [ + { + "field": "Microsoft.Security/automations/actions[*].EventHub.isTrustedServiceEnabled", + "exists": "false" + }, + { + "field": "Microsoft.Security/automations/actions[*].EventHub.isTrustedServiceEnabled", + "equals": false + } + ] + } + ] + } + }, + "equals": 1 + }, + { + "count": { + "field": "Microsoft.Security/automations/sources[*]" + }, + "equals": "[if(parameters('isSecurityFindingsEnabled'),add(length(parameters('exportedDataTypes')),1),length(parameters('exportedDataTypes')))]" + }, + { + "count": { + "value": "[parameters('exportedDataTypes')]", + "name": "dataType", + "where": { + "count": { + "field": "Microsoft.Security/automations/sources[*]", + "where": { + "anyOf": [ + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "Assessments" + }, + { + "value": "[current('dataType')]", + "equals": "Security recommendations" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "Alerts" + }, + { + "value": "[current('dataType')]", + "equals": "Security alerts" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SecureScores" + }, + { + "value": "[current('dataType')]", + "equals": "Overall secure score" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SecureScoreControls" + }, + { + "value": "[current('dataType')]", + "equals": "Secure score controls" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "RegulatoryComplianceAssessment" + }, + { + "value": "[current('dataType')]", + "equals": "Regulatory compliance" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SecureScoresSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Overall secure score - snapshot" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SecureScoreControlsSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Secure score controls - snapshot" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "RegulatoryComplianceAssessmentSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Regulatory compliance - snapshot" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "AssessmentsSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Security recommendations - snapshot" + } + ] + }, + { + "allOf": [ + { + "field": "Microsoft.Security/automations/sources[*].eventSource", + "equals": "SubAssessmentsSnapshot" + }, + { + "value": "[current('dataType')]", + "equals": "Security findings - snapshot" + } + ] + } + ] + } + }, + "equals": 1 + } + }, + "equals": "[length(parameters('exportedDataTypes'))]" + } + ] + }, + "deployment": { + "location": "westeurope", + "properties": { + "mode": "incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupName": { + "type": "string" + }, + "resourceGroupLocation": { + "type": "string" + }, + "createResourceGroup": { + "type": "bool" + }, + "resourceGroupTags": { + "type": "object" + }, + "exportedDataTypes": { + "type": "array", + "minLength": 1 + }, + "isSecurityFindingsEnabled": { + "type": "bool" + }, + "recommendationNames": { + "type": "array" + }, + "secureScoreControlsNames": { + "type": "array" + }, + "regulatoryComplianceStandardsNames": { + "type": "array" + }, + "recommendationSeverities": { + "type": "array", + "minLength": 1 + }, + "alertSeverities": { + "type": "array", + "minLength": 1 + }, + "eventHubDetails": { + "type": "string" + }, + "guidValue": { + "type": "string", + "defaultValue": "[newGuid()]" + } + }, + "variables": { + "scopeDescription": "scope for subscription {0}", + "subAssessmentRuleExpectedValue": "/assessments/{0}/", + "recommendationNamesLength": "[length(parameters('recommendationNames'))]", + "secureScoreControlsNamesLength": "[length(parameters('secureScoreControlsNames'))]", + "secureScoreControlsLengthIfEmpty": "[if(equals(variables('secureScoreControlsNamesLength'), 0), 1, variables('secureScoreControlsNamesLength'))]", + "regulatoryComplianceStandardsNamesLength": "[length(parameters('regulatoryComplianceStandardsNames'))]", + "regulatoryComplianceStandardsNamesLengthIfEmpty": "[if(equals(variables('regulatoryComplianceStandardsNamesLength'), 0), 1, variables('regulatoryComplianceStandardsNamesLength'))]", + "recommendationSeveritiesLength": "[length(parameters('recommendationSeverities'))]", + "alertSeveritiesLength": "[length(parameters('alertSeverities'))]", + "recommendationNamesLengthIfEmpty": "[if(equals(variables('recommendationNamesLength'), 0), 1, variables('recommendationNamesLength'))]", + "recommendationSeveritiesLengthIfEmpty": "[if(equals(variables('recommendationSeveritiesLength'), 0), 1, variables('recommendationSeveritiesLength'))]", + "alertSeveritiesLengthIfEmpty": "[if(equals(variables('alertSeveritiesLength'), 0), 1, variables('alertSeveritiesLength'))]", + "totalRuleCombinationsForOneRecommendationName": "[variables('recommendationSeveritiesLengthIfEmpty')]", + "totalRuleCombinationsForOneRecommendationSeverity": 1, + "exportedDataTypesLength": "[length(parameters('exportedDataTypes'))]", + "exportedDataTypesLengthIfEmpty": "[if(equals(variables('exportedDataTypesLength'), 0), 1, variables('exportedDataTypesLength'))]", + "dataTypeMap": { + "Security recommendations": "Assessments", + "Security alerts": "Alerts", + "Overall secure score": "SecureScores", + "Secure score controls": "SecureScoreControls", + "Regulatory compliance": "RegulatoryComplianceAssessment", + "Overall secure score - snapshot": "SecureScoresSnapshot", + "Secure score controls - snapshot": "SecureScoreControlsSnapshot", + "Regulatory compliance - snapshot": "RegulatoryComplianceAssessmentSnapshot", + "Security recommendations - snapshot": "AssessmentsSnapshot", + "Security findings - snapshot": "SubAssessmentsSnapshot" + }, + "alertSeverityMap": { + "High": "high", + "Medium": "medium", + "Low": "low" + }, + "ruleSetsForAssessmentsObj": { + "copy": [ + { + "name": "ruleSetsForAssessmentsArr", + "count": "[mul(variables('recommendationNamesLengthIfEmpty'),variables('recommendationSeveritiesLengthIfEmpty'))]", + "input": { + "rules": [ + { + "propertyJPath": "[if(equals(variables('recommendationNamesLength'),0),'type','name')]", + "propertyType": "string", + "expectedValue": "[if(equals(variables('recommendationNamesLength'),0),'Microsoft.Security/assessments',parameters('recommendationNames')[mod(div(copyIndex('ruleSetsForAssessmentsArr'),variables('totalRuleCombinationsForOneRecommendationName')),variables('recommendationNamesLength'))])]", + "operator": "Contains" + }, + { + "propertyJPath": "properties.metadata.severity", + "propertyType": "string", + "expectedValue": "[parameters('recommendationSeverities')[mod(div(copyIndex('ruleSetsForAssessmentsArr'),variables('totalRuleCombinationsForOneRecommendationSeverity')),variables('recommendationSeveritiesLength'))]]", + "operator": "Equals" + } + ] + } + } + ] + }, + "customRuleSetsForSubAssessmentsObj": { + "copy": [ + { + "name": "ruleSetsForSubAssessmentsArr", + "count": "[variables('recommendationNamesLengthIfEmpty')]", + "input": { + "rules": [ + { + "propertyJPath": "id", + "propertyType": "string", + "expectedValue": "[if(equals(variables('recommendationNamesLength'), 0), json('null'), replace(variables('subAssessmentRuleExpectedValue'),'{0}', parameters('recommendationNames')[copyIndex('ruleSetsForSubAssessmentsArr')]))]", + "operator": "Contains" + } + ] + } + } + ] + }, + "ruleSetsForAlertsObj": { + "copy": [ + { + "name": "ruleSetsForAlertsArr", + "count": "[variables('alertSeveritiesLengthIfEmpty')]", + "input": { + "rules": [ + { + "propertyJPath": "Severity", + "propertyType": "string", + "expectedValue": "[variables('alertSeverityMap')[parameters('alertSeverities')[mod(copyIndex('ruleSetsForAlertsArr'),variables('alertSeveritiesLengthIfEmpty'))]]]", + "operator": "Equals" + } + ] + } + } + ] + }, + "customRuleSetsForSecureScoreControlsObj": { + "copy": [ + { + "name": "ruleSetsForSecureScoreControlsArr", + "count": "[variables('secureScoreControlsLengthIfEmpty')]", + "input": { + "rules": [ + { + "propertyJPath": "name", + "propertyType": "string", + "expectedValue": "[if(equals(variables('secureScoreControlsNamesLength'), 0), json('null'), parameters('secureScoreControlsNames')[copyIndex('ruleSetsForSecureScoreControlsArr')])]", + "operator": "Equals" + } + ] + } + } + ] + }, + "customRuleSetsForRegulatoryComplianceObj": { + "copy": [ + { + "name": "ruleSetsForRegulatoryCompliancArr", + "count": "[variables('regulatoryComplianceStandardsNamesLengthIfEmpty')]", + "input": { + "rules": [ + { + "propertyJPath": "id", + "propertyType": "string", + "expectedValue": "[if(equals(variables('regulatoryComplianceStandardsNamesLength'), 0), json('null'), parameters('regulatoryComplianceStandardsNames')[copyIndex('ruleSetsForRegulatoryCompliancArr')])]", + "operator": "Contains" + } + ] + } + } + ] + }, + "ruleSetsForSecureScoreControlsObj": "[if(equals(variables('secureScoreControlsNamesLength'), 0), json('null'), variables('customRuleSetsForSecureScoreControlsObj').ruleSetsForSecureScoreControlsArr)]", + "ruleSetsForSecureRegulatoryComplianceObj": "[if(equals(variables('regulatoryComplianceStandardsNamesLength'), 0), json('null'), variables('customRuleSetsForRegulatoryComplianceObj').ruleSetsForRegulatoryCompliancArr)]", + "ruleSetsForSubAssessmentsObj": "[if(equals(variables('recommendationNamesLength'), 0), json('null'), variables('customRuleSetsForSubAssessmentsObj').ruleSetsForSubAssessmentsArr)]", + "subAssessmentSource": [ + { + "eventSource": "SubAssessments", + "ruleSets": "[variables('ruleSetsForSubAssessmentsObj')]" + } + ], + "ruleSetsMap": { + "Security recommendations": "[variables('ruleSetsForAssessmentsObj').ruleSetsForAssessmentsArr]", + "Security alerts": "[variables('ruleSetsForAlertsObj').ruleSetsForAlertsArr]", + "Overall secure score": null, + "Secure score controls": "[variables('ruleSetsForSecureScoreControlsObj')]", + "Regulatory compliance": "[variables('ruleSetsForSecureRegulatoryComplianceObj')]", + "Overall secure score - snapshot": null, + "Secure score controls - snapshot": "[variables('ruleSetsForSecureScoreControlsObj')]", + "Regulatory compliance - snapshot": "[variables('ruleSetsForSecureRegulatoryComplianceObj')]", + "Security recommendations - snapshot": "[variables('ruleSetsForAssessmentsObj').ruleSetsForAssessmentsArr]", + "Security findings - snapshot": "[variables('ruleSetsForSubAssessmentsObj')]" + }, + "sourcesWithoutSubAssessments": { + "copy": [ + { + "name": "sources", + "count": "[variables('exportedDataTypesLengthIfEmpty')]", + "input": { + "eventSource": "[variables('dataTypeMap')[parameters('exportedDataTypes')[copyIndex('sources')]]]", + "ruleSets": "[variables('ruleSetsMap')[parameters('exportedDataTypes')[copyIndex('sources')]]]" + } + } + ] + }, + "sourcesWithSubAssessments": "[concat(variables('subAssessmentSource'),variables('sourcesWithoutSubAssessments').sources)]", + "sources": "[if(equals(parameters('isSecurityFindingsEnabled'),bool('true')),variables('sourcesWithSubAssessments'),variables('sourcesWithoutSubAssessments').sources)]" + }, + "resources": [ + { + "condition": "[parameters('createResourceGroup')]", + "name": "[parameters('resourceGroupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2019-10-01", + "location": "[parameters('resourceGroupLocation')]", + "tags": "[parameters('resourceGroupTags')]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2019-10-01", + "name": "[concat('nestedAutomationDeployment', '_', parameters('guidValue'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('resourceGroupName'))]" + ], + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "resourceGroupTags": { + "type": "object" + }, + "sources": { + "type": "array" + }, + "scopeDescription": { + "type": "string" + }, + "eventHubResourceId": { + "type": "string" + }, + "connectionString": { + "type": "securestring" + } + }, + "variables": { + "mergedTags": "[union(if(equals(resourceGroup().tags, json('null')), json('{}'), resourceGroup().tags), parameters('resourceGroupTags'))]" + }, + "resources": [ + { + "condition": "[not(empty(parameters('resourceGroupTags')))]", + "apiVersion": "2021-04-01", + "name": "default", + "type": "Microsoft.Resources/tags", + "properties": { + "tags": "[variables('mergedTags')]" + } + }, + { + "tags": "[variables('mergedTags')]", + "apiVersion": "2019-01-01-preview", + "location": "[resourceGroup().location]", + "name": "exportToEventHub", + "type": "Microsoft.Security/automations", + "dependsOn": [ + "[resourceId('Microsoft.Resources/tags', 'default')]" + ], + "properties": { + "description": "Export Microsoft Defender for Cloud data to Event Hub via policy", + "isEnabled": true, + "scopes": [ + { + "description": "[parameters('scopeDescription')]", + "scopePath": "[subscription().id]" + } + ], + "sources": "[parameters('sources')]", + "actions": [ + { + "actionType": "EventHub", + "eventHubResourceId": "[parameters('eventHubResourceId')]", + "connectionString": "[parameters('connectionString')]" + } + ] + } + } + ] + }, + "parameters": { + "resourceGroupTags": { + "value": "[parameters('resourceGroupTags')]" + }, + "sources": { + "value": "[variables('sources')]" + }, + "scopeDescription": { + "value": "[replace(variables('scopeDescription'), '{0}', subscription().subscriptionId)]" + }, + "eventHubResourceId": { + "value": "[join(take(split(parameters('eventHubDetails'), '/'), 11), '/')]" + }, + "connectionString": { + "value": "[listKeys(parameters('eventHubDetails'), '2017-04-01').primaryConnectionString]" + } + } + } + } + ] + }, + "parameters": { + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "resourceGroupLocation": { + "value": "[parameters('resourceGroupLocation')]" + }, + "createResourceGroup": { + "value": "[parameters('createResourceGroup')]" + }, + "resourceGroupTags": { + "value": "[parameters('resourceGroupTags')]" + }, + "exportedDataTypes": { + "value": "[parameters('exportedDataTypes')]" + }, + "recommendationNames": { + "value": "[parameters('recommendationNames')]" + }, + "isSecurityFindingsEnabled": { + "value": "[parameters('isSecurityFindingsEnabled')]" + }, + "secureScoreControlsNames": { + "value": "[parameters('secureScoreControlsNames')]" + }, + "recommendationSeverities": { + "value": "[parameters('recommendationSeverities')]" + }, + "alertSeverities": { + "value": "[parameters('alertSeverities')]" + }, + "regulatoryComplianceStandardsNames": { + "value": "[parameters('regulatoryComplianceStandardsNames')]" + }, + "eventHubDetails": { + "value": "[parameters('eventHubDetails')]" + } + } + } + } + } + } +}