MS Defender for Cloud Continuous export via BICEP - help needed

Roman King 21 Reputation points
2025-08-06T16:37:45.74+00:00

Hello, all!

I am trying to set up MS Defender for Cloud Continuous export via BICEP and need some help. The MS Documentation for this specific part leaves to be desired; there are no examples or explanations, so I am stuck.

Here is the code:

resource automation 'Microsoft.Security/automations@2023-12-01-preview' = {
  name: 'ExportToWorkspace'
  location: 'canadacentral'
  properties: {
    isEnabled: true
    actions: [
      {
        actionType: 'Workspace'
        workspaceResourceId: '/subscriptions/27b032a0-0cef-4de2-be0b-ec67b408c026/resourceGroups/rg-prd-logging-cc/providers/Microsoft.OperationalInsights/workspaces/log-prd-logging-cc'
      }
    ]
    scopes: [
      {
        description: 'Security Export for the subscription'
        scopePath: '/subscriptions/fcc63316-3030-43c9-b243-7c0a2a2c66f1'
      }
    ]
    sources: [
      {
        eventSource: 'Assessments' // For streaming updates of security recommendations (Security recommendations)
        ruleSets: [
          {
            rules: [
              {
                propertyJPath: 'type'
                propertyType: 'String'
                expectedValue: 'Microsoft.Security/assessments'
                operator: 'Contains'
              }
            ]
          }
        ]
      }
      {
        eventSource: 'AssessmentsSnapshot' // For snapshots of security recommendations
      }
      {
        eventSource: 'SubAssessments' // To include security findings (sub-assessments) as streaming updates (Include security findings)
      }
      {
        eventSource: 'SubAssessmentsSnapshot' // To include security findings (sub-assessments) as snapshots
      }

      // Secure score (Streaming updates and Snapshots)
      {
        eventSource: 'SecureScores' // For streaming updates of secure scores
      }
      {
        eventSource: 'SecureScoresSnapshot' // For snapshots of secure scores
      }
      {
        eventSource: 'SecureScoreControls' // For streaming updates of secure score controls
      }
      {
        eventSource: 'SecureScoreControlsSnapshot' // For snapshots of secure score controls
      }

      // Regulatory compliance (Streaming updates and Snapshots)
      {
        eventSource: 'RegulatoryComplianceAssessment' // For streaming updates of regulatory compliance assessments
      }
      {
        eventSource: 'RegulatoryComplianceAssessmentSnapshot' // For snapshots of regulatory compliance assessments
      }
    ]
  }
  tags: {
    environment: 'production'
  }
}


The goal is to enable:
Exported data types:
Security Recommendations
Security Score
Regulatory compliance

Export frequency:
Streaming updates
Snapshots

So, if I have AssessmentsSnapshot as my eventSource, I have a banner that states "Custom export settings were applied programmatically for this subscription - click here to learn more." and I can't make any changes.

If I remove AssessmentsSnapshot, the banner says that "Please note that the following data types are now available for snapshot export: security recommendations. In order to enable snapshot export for these data types, click on Save to update your export configuration", and the Save button is active, and I can make changes in the portal.

So, what's wrong with my code? How to have data types and export frequency enabled, disable the Save button and be able to make changes via UI?

Azure Automation
Azure Automation
An Azure service that is used to automate, configure, and install updates across hybrid environments.
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Stanislav Zhelyazkov 28,986 Reputation points MVP Volunteer Moderator
    2025-08-07T06:40:52.3533333+00:00

    Hi,

    To my understanding this is intended behavior. The UI has certain patterns of configuration that is applied and if some reason that pattern is not according to what it expects it locks the UI to avoid making any mess by applying some other configuration and wiping some existing one. I think even if you change the resource from ExportToWorkspace to something else will not understand that there is existing configuration. So if you are managing the resource via Bicep you should not try to use the portal at all and just use Bicep. As far as I can see you have all the even sources in your template with exception of Alerts but it is up to you if you want to export those or not. If you want to mimic the exact configuration that is applied when you enable all the options without changing any other defaults you can apply these sources:

    [
      {
        eventSource: 'Assessments'
        ruleSets: [
          {
            rules: [
              {
                propertyJPath: 'type'
                propertyType: 'String'
                expectedValue: 'Microsoft.Security/assessments'
                operator: 'Contains'
              }
            ]
          }
        ]
      }
      {
        eventSource: 'AssessmentsSnapshot'
        ruleSets: [
          {
            rules: [
              {
                propertyJPath: 'type'
                propertyType: 'String'
                expectedValue: 'Microsoft.Security/assessments'
                operator: 'Contains'
              }
            ]
          }
        ]
      }
      {
        eventSource: 'SubAssessments'
      }
      {
        eventSource: 'SubAssessmentsSnapshot'
      }
      {
        eventSource: 'Alerts'
        ruleSets: [
          {
            rules: [
              {
                propertyJPath: 'Severity'
                propertyType: 'String'
                expectedValue: 'low'
                operator: 'Equals'
              }
            ]
          }
          {
            rules: [
              {
                propertyJPath: 'Severity'
                propertyType: 'String'
                expectedValue: 'medium'
                operator: 'Equals'
              }
            ]
          }
          {
            rules: [
              {
                propertyJPath: 'Severity'
                propertyType: 'String'
                expectedValue: 'high'
                operator: 'Equals'
              }
            ]
          }
          {
            rules: [
              {
                propertyJPath: 'Severity'
                propertyType: 'String'
                expectedValue: 'informational'
                operator: 'Equals'
              }
            ]
          }
        ]
      }
      {
        eventSource: 'AttackPathsSnapshot'
        ruleSets: [
          {
            rules: [
              {
                propertyJPath: 'attackPath.riskLevel'
                propertyType: 'String'
                expectedValue: 'Low'
                operator: 'Equals'
              }
            ]
          }
          {
            rules: [
              {
                propertyJPath: 'attackPath.riskLevel'
                propertyType: 'String'
                expectedValue: 'Medium'
                operator: 'Equals'
              }
            ]
          }
          {
            rules: [
              {
                propertyJPath: 'attackPath.riskLevel'
                propertyType: 'String'
                expectedValue: 'High'
                operator: 'Equals'
              }
            ]
          }
          {
            rules: [
              {
                propertyJPath: 'attackPath.riskLevel'
                propertyType: 'String'
                expectedValue: 'Critical'
                operator: 'Equals'
              }
            ]
          }
        ]
      }
      {
        eventSource: 'AttackPaths'
        ruleSets: [
          {
            rules: [
              {
                propertyJPath: 'attackPath.riskLevel'
                propertyType: 'String'
                expectedValue: 'Low'
                operator: 'Equals'
              }
            ]
          }
          {
            rules: [
              {
                propertyJPath: 'attackPath.riskLevel'
                propertyType: 'String'
                expectedValue: 'Medium'
                operator: 'Equals'
              }
            ]
          }
          {
            rules: [
              {
                propertyJPath: 'attackPath.riskLevel'
                propertyType: 'String'
                expectedValue: 'High'
                operator: 'Equals'
              }
            ]
          }
          {
            rules: [
              {
                propertyJPath: 'attackPath.riskLevel'
                propertyType: 'String'
                expectedValue: 'Critical'
                operator: 'Equals'
              }
            ]
          }
        ]
      }
      {
        eventSource: 'SecureScores'
      }
      {
        eventSource: 'SecureScoresSnapshot'
      }
      {
        eventSource: 'SecureScoreControls'
      }
      {
        eventSource: 'SecureScoreControlsSnapshot'
      }
      {
        eventSource: 'RegulatoryComplianceAssessment'
      }
      {
        eventSource: 'RegulatoryComplianceAssessmentSnapshot'
      }
    ]
    

    As you can see certain rule sets are applied to different categories. Most likely the UI expect those to be present in order to be able to edit it via the UI. My recommendation is still to use just Bicep to manage that at it is more flexible. The UI makes it more complex by requiring specific patterns to be present in the configuration.

    Please "Accept the answer" if the information helped you. This will help us and others in the community as well.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.