Terraform is an Infrastructure as a Code tool created by Hashicorp. It’s used to manage your infrastructure in Azure, as well as other clouds. In this article, we’ll be showing you how to deploy Microsoft Defender for Cloud (MDC) using Terraform from scratch. This way if you use Terraform, it’s recommended that you stick entirely with Terraform and don’t use any other management methods such as the Azure Portal.
As part of using Terraform to manage MDC, you will need to setup the Terraform configuration in a workspace including the Azure Resource Manager (RM) provider which configures your Azure resources. In this workspace, you’ll have the following files:
The following commands for Terraform are most crucial for you to know:
Terraform init
Terraform plan
Terraform apply
$env:PATH =$env:PATH+";'<path to Terraform installation directory>”"
terraform -version
Now you have confirmed that Terraform has been correctly installed.
To manage Azure resources with Terraform, you need to use the Azure RM provider. In a providers.tf file, you will place the following Terraform declarations, which state you are going to work with a minimum Terraform and Azure RM version:
terraform {
required_version = ">=0.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.0"
}
}
provider "azurerm" {
features {}
}
This providers declaration will be used next by the Terraform initialization procedure to set itself up for Azure management. See more guidance on this provider in the Terraform resources for MDC section.
az login
2. You will need to initialize Terraform to prepare the current working directory to be used with Terraform and to install the required providers, using the following command:
terraform init
terraform plan
This allows you to see what changes are different from your main.tf and what is in your Azure environment. All the Azure configuration should go in the main.tf file.
terraform apply
You now have the configuration needed for MDC.
You can make further changes to your main.tf file which will be incorporated to your Azure environment when you run the terraform apply command again.
Note: Once you start using Terraform to deploy your Azure resources, it’s a best practise to continue using terraform for this. Try to avoid using the Azure Portal UI to make further changes as that may cause issues in your Terraform configuration.
There are many Terraform resources available for setting up MDfC. You can browse for them in the Azure RM Terraform provider documentation. You will notice they appear aggregated under “Security Center”, which was the previous brand for MDfC. In this section, you will learn which Terraform resources to use for each MDfC setup step, for a particular Azure subscription.
Many of the Terraform examples below are going to reference the current Azure subscription ID we are working with. This is done by means of a data declaration which stores the current Azure subscription properties:
data "azurerm_subscription" "current" {}
Note: The example code below should go into your main.tf file.
After an Azure Subscription is registered for the Microsoft.Security resource provider – this should have at least happened automatically after you ran terraform init –, MDC will eventually enable the default Azure Policy initiative for Azure Security Benchmark, which fuels its Security Posture recommendations. As this will happen only after some hours, you may want to leverage Terraform to enable it yourself and speed things up.
resource "azurerm_subscription_policy_assignment" "asb_assignment" {
name = "azuresecuritybenchmark"
display_name = "Azure Security Benchmark"
policy_definition_id = "/providers/Microsoft.Authorization/policySetDefinitions/1f3afdf9-d0c9-4c3d-847f-89da613e70a8"
subscription_id = data.azurerm_subscription.current.id
}
We are using the Policy Assignment resource applied at the Subscription level and we are referring to the Azure Security Benchmark Policy Initiative ID. You will notice the use of the data.azurerm_subscription.current data resource we declared earlier, to populate the Subscription ID.
Now that we’ve already set up Security Posture, let’s move on to Workload Protection. After choosing which Defender Plans you want to enable, you’ll declare a Terraform resource for each plan.
resource "azurerm_security_center_subscription_pricing" "mdc_arm" {
tier = "Standard"
resource_type = "Arm"
}
resource "azurerm_security_center_subscription_pricing" "mdc_servers" {
tier = "Standard"
resource_type = "VirtualMachines"
}
In the examples above, we are enabling Defender for ARM and Defender for Servers. For other plans, check out the Terraform documentation.
The integrations with Microsoft Defender for Endpoint and Microsoft Defender for Cloud Apps are enabled by default, but you may want to manage them as code.
resource "azurerm_security_center_setting" "setting_mcas" {
setting_name = "MCAS"
enabled = false
}
resource "azurerm_security_center_setting" "setting_mde" {
setting_name = "WDATP"
enabled = true
}
Again, there is a specific Terraform resource to enable MDC integrations. We are using the same resource for both integrations, just changing the setting name: MCAS for Microsoft Defender for Cloud Apps and WDATP for Microsoft Defender for Endpoint.
If MDC needs to notify you about a security incident, it’s a good idea to have e-mail and phone contacts set up.
resource "azurerm_security_center_contact" "mdc_contact" {
email = "john.doe@contoso.com"
phone = "+351919191919"
alert_notifications = true
alerts_to_admins = true
}
The phone property is the only optional one. The alert_notifications property enables/disables sending notifications to the security contact, while the alerts_to_admins is about sending notifications to the Azure Subscription administrators.
OK, now that we have set the basics up, let’s configure more advanced features, such as auto-provisioning Log Analytics agents, in the context of the Defender for Servers plan. This involves multiple steps and Azure resources. First, we must turn auto-provisioning on:
resource "azurerm_security_center_auto_provisioning" "auto-provisioning" {
auto_provision = "On"
}
There’s a specific resource for that and it’s very simple to deal with. It’s just an On/Off property. Next, we are going to associate Defender for Servers to a specific Log Analytics workspace.
resource "azurerm_security_center_workspace" "la_workspace" {
scope = data.azurerm_subscription.current.id
workspace_id = "/subscriptions/<subscription id>/resourcegroups/<resource group name>/providers/microsoft.operationalinsights/workspaces/<workspace name>"
}
The declaration above will work for an existing Log Analytics workspace. If you want to create the Log Analytics workspace together with MDC, you will use a slightly different approach:
resource "azurerm_resource_group" "security_rg" {
name = "security-rg"
location = "West Europe"
}
resource "azurerm_log_analytics_workspace" "la_workspace" {
name = "mdc-security-workspace"
location = azurerm_resource_group.security_rg.location
resource_group_name = azurerm_resource_group.security_rg.name
sku = "PerGB2018"
}
resource "azurerm_security_center_workspace" "la_workspace" {
scope = data.azurerm_subscription.current.id
workspace_id = azurerm_log_analytics_workspace.la_workspace.id
}
In the declarations above, we create a Resource Group and Log Analytics Workspace and then reference its ID it in the MDC workspace resource.
Unlike the Log Analytics counterpart, Vulnerability Assessment auto-provisioning is configured with the help of an Azure Policy assignment. The choice between leveraging Qualys or MDE vulnerability assessment is done as a Policy assignment parameter.
resource "azurerm_subscription_policy_assignment" "va-auto-provisioning" {
name = "mdc-va-autoprovisioning"
display_name = "Configure machines to receive a vulnerability assessment provider"
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/13ce0167-8ca6-4048-8e6b-f996402e3c1b"
subscription_id = data.azurerm_subscription.current.id
identity {
type = "SystemAssigned"
}
location = "West Europe"
parameters = <<PARAMS
{ "vaType": { "value": "mdeTvm" } }
PARAMS
}
resource "azurerm_role_assignment" "va-auto-provisioning-identity-role" {
scope = data.azurerm_subscription.current.id
role_definition_id = "/providers/Microsoft.Authorization/roleDefinitions/fb1c8493-542b-48eb-b624-b4c8fea62acd"
principal_id = azurerm_subscription_policy_assignment.va-auto-provisioning.identity[0].principal_id
}
In the example above, we chose the MDE vulnerability assessment (mdeTvm value for the vaType Policy parameter). If you prefer to use Qualys, then you must specify default for the vaType parameter or simply remove the parameters block.
We are also assigning the Security Admin role to the Managed Identity that will be used to perform the automatic provisioning of the Vulnerability Assessment solution.
The last Terraform resource for MDC we cover in this article is the one allowing you to configure Continuous Export settings. You have many configuration possibilities available. In the example below, we are exporting to a specific Log Analytics workspace High/Medium Security Alerts and all the Secure Score controls. We are referring to a Log Analytics workspace ID that was declared in the same Main.tf file.
resource "azurerm_security_center_automation" "la-exports" {
name = "ExportToWorkspace"
location = azurerm_resource_group.security_rg.location
resource_group_name = azurerm_resource_group.security_rg.name
action {
type = "loganalytics"
resource_id = azurerm_log_analytics_workspace.la_workspace.id
}
source {
event_source = "Alerts"
rule_set {
rule {
property_path = "Severity"
operator = "Equals"
expected_value = "High"
property_type = "String"
}
rule {
property_path = "Severity"
operator = "Equals"
expected_value = "Medium"
property_type = "String"
}
}
}
source {
event_source = "SecureScores"
}
source {
event_source = "SecureScoreControls"
}
scopes = [ data.azurerm_subscription.current.id ]
}
In summary, this article covered how to deploy Microsoft Defender for Cloud using Terraform.
Huge thanks to the reviewers of this post:
@Safeena Begum Lepakshi, Senior Program Manager, Microsoft Defender for Cloud
@Yuri Diogenes , Principal PM Manager, Microsoft Defender for Cloud
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.