Azure Spring Clean 2023: Configure Microsoft Defender For Cloud Continuous Export for an Azure Virtual Desktop Subscription with Terraform

Hi there,

Welcome to my contribution for this year’s Azure Spring Clean 2023. It’s a community event taking place from march 13 until march 17th. For more info check the website here.

Security is a very important part of your journey to and in Azure. If anything happens in your environment you need to be able to search the logs. Microsoft Defender For cloud generates security alerts and recommendations. You can have them send to an Event hub, Log Analytics workspace or another SIEM solution like Sentinel.

To customize these alerts and what exactly is sent you can configure Continuous Export. In this blog post I’ll explain how you can configure it via the Azure Portal but also with Terraform. I’ll take my AVD subscription as an example.

If you need to configure this for multiple subscriptions I recommend doing this with an Azure policy and assigning it to your top level company management group. You can find the correct policy in the AzPolicyAdvertizer here

Prerequisites

  • It’s recommended to use a separate subscription for your AVD workloads.
  • A central Log Analytics Workspace in your Management subscription

What Alerts can be exported and where can you find these settings

First of all type Defender in the global search bar and you will see Defender for Cloud

Next we go to Environment Settings where we can see all our subscriptions and select the one we need.

when you select Continuous Export you will see that it selects the Eventhub option as default. You can choose to use a Log Analytics Workspace instead. As you see below you can edit all the settings through the portal.

Important to know is what alerts can be exported. Below you can see all the alerts types that you can select. You don’t have to enable them all. It really depends of the needs of the environment.

Deploy with Terraform

Of course we want to automate this so I’m going to show how you can enable these settings using Terraform.

The first thing we need since we are exporting the data types to Log Analytics is the workspace. Using the following code I’m importing the existing one in my main.tf file.

data "azurerm_log_analytics_workspace" "law" {
  provider            = azurerm.hub
  name                = "law-${var.env}-${var.prefix}-01"
  resource_group_name = "rg-${var.env}-${var.prefix}-management-01"
}

Important if you want to see the date in the workspace you need to enable Security and Audit or SecurityCenterFree solution on the workspace. I already wrote a blog about deploying a Log Analytics Workspace with solutions. You can see that blog post here .

Next we define the code for the Continuous Export. Important to know is that the name is fixed, if you choose to give it a name yourself, the code won’t change the settings in the portal. For Log Analytics you need to use the name “ExportToWorkspace”.

As you can see in the code below I didn’t use the Azurerm provider but the AzApi provider.

Change the yoursubid in the code to your own subscription id.

terraform {
  required_providers {
    azapi = {
      source = "Azure/azapi"
    }
  }
}

provider "azapi" {
}

provider "azurerm" {
  features {}
}

provider "azurerm" {
  features {}
  alias           = "hub"
  subscription_id = var.subscription_id_mgmt
}
provider "azurerm" {
  features {}
  alias           = "prod"
  subscription_id = var.subscription_id_prd
}
provider "azurerm" {
  features {}
  alias           = "identity"
  subscription_id = var.subscription_id_identity
}
provider "azurerm" {
  features {}
  alias           = "avd"
  subscription_id = var.subscription_id_avd
}


data "azurerm_log_analytics_workspace" "law" {
  provider            = azurerm.hub
  name                = "law-${var.env}-${var.prefix}-01"
  resource_group_name = "rg-${var.env}-${var.prefix}-management-01"
}
data "azurerm_client_config" "current" {}
data "azurerm_subscription" "current" {}

data "azurerm_resource_group" "mgmt" {
  provider = azurerm.hub
  name     = "rg-hub-jvn-management-01"
}
resource "azapi_resource" "continuous_export" {
  type      = "Microsoft.Security/automations@2019-01-01-preview"
  name      = "ExportToWorkspace"
  parent_id = data.azurerm_resource_group.mgmt.id

  location = data.azurerm_resource_group.mgmt.location
  body = jsonencode({
    properties = {
      description = "",
      isEnabled   = true,
      scopes = [
        {
          description = "Security Export for the subscription",
          scopePath   = data.azurerm_resource_group.mgmt.id
        }
      ],
      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 = "SecureScores"
        },
        {
          eventSource = "SecureScoresSnapshot"
        },
        {
          eventSource = "SecureScoreControls"
        },
        {
          eventSource = "SecureScoreControlsSnapshot"
        },
        {
          eventSource = "RegulatoryComplianceAssessment"
        },
        {
          eventSource = "RegulatoryComplianceAssessmentSnapshot"
        }
      ],
      actions = [
        {
          workspaceResourceId = data.azurerm_log_analytics_workspace.law.id
          actionType          = "Workspace"
        }
      ]
    }
  })
}

When you run this code it will activate the following data types:

  • Security recommendations
  • Alerts: All values
  • SecureScore
  • Controls
  • Security Alerts
  • Regulatory Compliance

The rest of the config is to set the resource group and to select the correct subscription and Log Analytics Workspace.

Costs of Continuous Export

Since costs are a big topic in azure it’s good to know that configuring this feature doesn’t cost any money. You only pay the ingestion cost when you save data in your Log Analytics Workspace.

If you want to learn more about this topic go to the Learn page here.

The complete can be found on my Github page.

I hope this blog post will help you setup Defender for Cloud Continuous Export. If you have any questions about this feel free to contact me on my socials.

Leave a Reply

Your email address will not be published. Required fields are marked *