-
Notifications
You must be signed in to change notification settings - Fork 575
[Examples] Deploy Management Resources With Custom Settings
This page describes how to deploy your Azure landing zone with the Management resources created in the current Subscription context, using custom configuration settings.
The module supports customizing almost any part of the configuration, however each subset of resources has it's own configuration block which is designed to simplify setting specific options.
For the Management resources, this is configured through the configure_management_resources
input variable.
In this example, we take the base Deploy Management resources configuration and make the following changes:
- Add input variable on the root module for enabling/disabling Management resources
- Add a local variable for
configure_management_resources
and set custom values for the following:- Update the retention period for data stored in the Log Analytics workspace from 30 days to 50 days (controlled through an input variable on the root module)
- Set a valid email address for Security alerts (controlled through an input variable on the root module)
- Disable Azure Defender for Azure Kubernetes Service (AKS)
- Set a different location for Management resources (controlled through an input variable on the root module)
- Add custom resource tags for Management resources (controlled through an input variable on the root module)
- Disable deployment of specified monitoring solutions in Azure Monitor (
ServiceMap
,SQLAssessment
,SQLAdvancedThreatProtection
,SQLVulnerabilityAssessment
)
The module allows for further customization of the Management resources through the advanced
setting, however this is out-of-scope for this example.
Use of the
advanced
setting is currently undocumented and experimental. Please be aware that using this setting may result in future breaking changes.
If you've already deployed the Management resources using default settings, you will be able to see the changes made when moving to this configuration.
Due to the way the Azure RM Provider manages dependencies, you may see a number of
azurerm_role_assignment
resources being replaced when updating Policy Assignments. Unfortunately this is a product limitation, but should have minimal impact due to the way Azure Policy works.
If location is not specified, the resources will default to the same location set by default_location
input variable.
IMPORTANT: Ensure the module version is set to the latest, and don't forget to run
terraform init
if upgrading to a later version of the module.
To make the code easier to maintain when extending your configuration, we recommend splitting the root module into multiple files. For the purpose of this example, we use the following:
TIP: The exact number of resources created depends on the module configuration, but you can expect upwards of 190 resources to be created by the module for this example.
The terraform.tf
file is used to set the provider configuration, including pinning to a specific version (or range of versions) for the AzureRM Provider. For production use, we recommend pinning to a specific version, and not using ranges.
# Configure Terraform to set the required AzureRM provider
# version and features{} block.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.107"
}
}
}
provider "azurerm" {
features {}
}
If you wish to deploy the Management resources to a different Subscription context than the one used for Core resources, please refer to our guide for Multi-Subscription deployment.
The variables.tf
file is used to declare a couple of example variables which are used to customize deployment of this root module. Defaults are provided for simplicity, but these should be replaced or over-ridden with values suitable for your environment.
# Use variables to customize the deployment
variable "root_id" {
type = string
default = "myorg"
}
variable "root_name" {
type = string
default = "My Organization"
}
variable "deploy_management_resources" {
type = bool
default = true
}
variable "log_retention_in_days" {
type = number
default = 50
}
variable "security_alerts_email_address" {
type = string
default = "my_valid_security_contact@replace_me" # Replace this value with your own email address.
}
variable "management_resources_location" {
type = string
default = "uksouth"
}
variable "management_resources_tags" {
type = map(string)
default = {
demo_type = "deploy_management_resources_custom"
}
}
The main.tf
file contains the azurerm_client_config
resource, which is used to determine the Tenant ID and Subscription ID values from your user connection to Azure. These are used to ensure the deployment will target your Tenant Root Group
by default, and to populate the subscription_id_management
input variable.
It also contains the module declaration for this module, containing a number of customizations as needed to meet the specification defined in the overview above.
# Get the current client configuration from the AzureRM provider.
# This is used to populate the root_parent_id variable with the
# current Tenant ID used as the ID for the "Tenant Root Group"
# Management Group.
data "azurerm_client_config" "core" {}
# Declare the Azure landing zones Terraform module
# and provide a base configuration.
module "enterprise_scale" {
source = "Azure/caf-enterprise-scale/azurerm"
version = "<version>" # change this to your desired version, https://www.terraform.io/language/expressions/version-constraints
default_location = "<YOUR_LOCATION>"
providers = {
azurerm = azurerm
azurerm.connectivity = azurerm
azurerm.management = azurerm
}
root_parent_id = data.azurerm_client_config.core.tenant_id
root_id = var.root_id
root_name = var.root_name
deploy_management_resources = var.deploy_management_resources
subscription_id_management = data.azurerm_client_config.core.subscription_id
configure_management_resources = local.configure_management_resources
}
The settings.management.tf
file contains a local variable containing the custom configuration for the configure_management_resources
input variable.
This helps to keep the module block clean, whilst providing clear separation between settings for different groups of resources.
# Configure the management resources settings.
locals {
configure_management_resources = {
settings = {
ama = {
enable_uami = true
enable_vminsights_dcr = true
enable_change_tracking_dcr = true
enable_mdfc_defender_for_sql_dcr = false
enable_mdfc_defender_for_sql_query_collection_for_security_research = false
}
log_analytics = {
enabled = true
config = {
retention_in_days = var.log_retention_in_days
enable_monitoring_for_vm = true
enable_monitoring_for_vmss = true
enable_sentinel = true
enable_change_tracking = true
}
}
security_center = {
enabled = true
config = {
email_security_contact = var.security_alerts_email_address
enable_defender_for_apis = true
enable_defender_for_app_services = true
enable_defender_for_arm = true
enable_defender_for_containers = true
enable_defender_for_cosmosdbs = true
enable_defender_for_cspm = true
enable_defender_for_dns = true
enable_defender_for_key_vault = true
enable_defender_for_oss_databases = true
enable_defender_for_servers = true
enable_defender_for_servers_vulnerability_assessments = true
enable_defender_for_sql_servers = true
enable_defender_for_sql_server_vms = true
enable_defender_for_storage = true
}
}
}
location = var.management_resources_location
tags = var.management_resources_tags
advanced = null
}
}
You have successfully created the default Management Group resource hierarchy, along with the recommended Azure Policy and Access control (IAM) settings for your Azure landing zone.
You have also assigned the current Subscription from your provider configuration to the management
Management Group.
Check the following Policy Assignments to see how these have been configured with settings matching your Management resources configuration set by configure_management_resources
:
- Scope =
root
Audit-UnusedResources
Deny-Classic-Resources
Deny-UnmanagedDisk
Deploy-ASC-Monitoring
Deploy-AzActivity-Log
Deploy-MDEndpoints
Deploy-MDFC-Config
Deploy-MDFC-OssDb
Deploy-MDFC-SqlAtp
Deploy-Resource-Diag
Deploy-VM-Monitoring
Deploy-VMSS-Monitoring
Enforce-ACSB
- Scope =
management
Deploy-Log-Analytics
These Policy Assignments should all be assigned with custom parameter values based on your configuration, with enforcement_mode
correctly set.
Once evaluated, the compliance state should also be updated and you can run remediation tasks to remediate any non-compliant resources.
The following shows the Deploy-AzActivity-Log
Policy Assignment with a user-defined value set by the module for the logAnalytics
parameter.
You will see that this value matches the resource ID of the Log Analytics workspace deployed by this module.
When reviewing the Policy Assignment compliance, you will see that some Policies may need remediation.
You should also have the following resources deployed in your assigned Management Subscription:
If you are using Archetype Exclusions or custom Archetypes in your code, make sure to not disable Log Analytics or Security Center policies if you require policy integration using this module. The relationship between the resources deployed and the Policy parameters is dependent on specific Policy Assignments being used.
Take particular note of the following changes:
-
The
retentionInDays
setting is now configured to50
days on the Log Analytics workspace. -
The
dataRetention
parameter value is also configured to50
days on theDeploy-Log-Analytics
Policy Assignment. -
The
emailSecurityContact
parameter value is set to your own email address on theDeploy-MDFC-Config
(Deploy Azure Security Center configuration) Policy Assignment. Once this policy is remediated, you can also view this setting in Azure Security Center. -
The
pricingTierKubernetesService
parameter value is set toFree
on theDeploy-MDFC-Config
(Deploy Azure Security Center configuration) Policy Assignment. In Security Center, you should be able to see that Azure Defender is set toOn
for all resource types exceptKubernetes
1 which is set toOff
.1 - Due to a pending feature addition, Azure Defender is also
Off
forOpen-source relational databases
. We plan to add this feature in a future release (date TBC).
Although not Policy Assignment related, also note the following changes:
- All Resource Groups and Resources created by the module for Management are now located in
uksouth
. - All Resource Groups and Resources (which support tags) created by the module for Management have the custom tags applied.
Try updating the configuration settings in the configure_management_resources
local variable to see how this changes your configuration.
Also try setting your own values in the input variables, and toggling the deploy_management_resources
input variable to see which resources are created/destroyed.
To learn more about module configuration using input variables, please refer to the Module Variables documentation.
Looking for further inspiration? Why not try some of our other examples?
This wiki is being actively developed
If you discover any documentation bugs or would like to request new content, please raise them as an issue or feel free to contribute to the wiki via a pull request. The wiki docs are located in the repository in the docs/wiki/
folder.
- Home
- User guide
- Video guides
-
Examples
- Level 100
- Level 200
-
Level 300
- Deploy multi region networking with custom settings (Hub and Spoke)
- Deploy multi region networking with custom settings (Virtual WAN)
- Deploy with Zero Trust network principles (Hub and Spoke)
- Deploy identity resources with custom settings
- Deploy management resources with custom settings
- Expand built-in archetype definitions
- Create custom policies, initiatives and assignments
- Override module role assignments
- Control policy enforcement mode
- Policy assignments with user assigned managed identities
- Level 400
- Frequently Asked Questions
- Troubleshooting
- Contributing