Use Terraform to build enterprise-scale landing zones
Azure provides native services for building your enterprise-scale landing zones. Other third-party tools can also help with this effort. One such tool that customers and partners often use to deploy landing zones is Terraform by HashiCorp.
The caf-enterprise-scale module provides an accelerated path for deploying the recommended platform resources you need to manage Azure landing zones at scale using Terraform.
Prerequisites
If you're new to Terraform, refer to the Install Terraform tutorial on HashiCorp Learn. The article covers installation and use of Terraform. It's also a good idea to check out the AzureRM provider guides for information on how to set up the provider and authenticate with Azure.
For more information on how to set up the provider for deploying across multiple Subscriptions, see the Provider Configuration wiki page.
Overview
These resources align with the enterprise-scale reference architecture. Customize them to meet the requirements of your organization.
You can configure the module to deploy different sets of resources, each aligned to the enterprise-scale critical design areas:
| Resource category | Enterprise-scale critical design areas |
|---|---|
| Core resources | Management group and Subscription organizationSecurity governance and complianceBusiness continuity and disaster recovery |
| Management resources | Management and monitoring |
| Connectivity resources | Network topology and connectivity |
| Identity resources | Identity and access management |
By packaging these capabilities into a single Terraform module, it becomes easier to build and enforce consistency across the Azure platform when operating at scale.
Use standard modules
Reuse of components is a fundamental principle of infrastructure as code. Modules are instrumental in defining standards and consistency across resource deployment within and across environments. The caf-enterprise-scale module is published to the official Terraform Registry and is verified by HashiCorp.
Deploying the module from the Terraform Registry provides strict version control while ensuring you always have access to the latest version. Doing so provides:
- An accelerated delivery of Cloud Adoption Framework enterprise-scale in your environment.
- A tested upgrade path to the latest version of Cloud Adoption Framework enterprise-scale.
Benefits of using the module
There are many benefits of using the caf-enterprise-scale module:
- Managed and extensible core resource hierarchy for Subscription organization using Management Groups.
- Scalable security governance and compliance using Azure Identity and Access Management (IAM) controls, with an extensive library of custom definitions ready to assign.
- Enforcement of policy across Subscriptions through Management Group inheritance.
- Managed resources for Management and Connectivity landing zones, providing:
- Assured policy compliance through tight integration of resources managed by the module and corresponding policy assignments.
- Integration between resources to reduce management overhead and provide an improved end-user experience, like automatic creation of virtual network links for Azure Private DNS.
Tip
The template library is updated programmatically from the Azure/Enterprise-Scale GitHub repository. To stay up to date with the latest archetype configuration, policies, and roles, make sure you're using the latest version of the module.
Capabilities
Resources deployed by the module are split logically into the following capabilities:
You can deploy these resources, by capability, across multiple Subscriptions using the Provider Configuration on the module block.
The following sections outline the different groups of resource types deployed and managed by this module, depending on the configuration options specified.
Core resources
The core capability of this module deploys the foundations of the Cloud Adoption Framework enterprise-scale landing zone architecture, with a focus on the central resource hierarchy and governance:

When using the core resources capability, the module deploys and manages the following resource types:
| Resource | Azure resource type | Terraform resource type |
|---|---|---|
| Management Groups | Microsoft.Management/managementGroups |
azurerm_management_group |
| Management Group Subscriptions | Microsoft.Management/managementGroups/subscriptions |
azurerm_management_group |
| Policy Assignments | Microsoft.Authorization/policyAssignments |
azurerm_management_group_policy_assignment |
| Policy Definitions | Microsoft.Authorization/policyDefinitions |
azurerm_policy_definition |
| Policy Set Definitions | Microsoft.Authorization/policySetDefinitions |
azurerm_policy_set_definition |
| Role Assignments | Microsoft.Authorization/roleAssignments |
azurerm_role_assignment |
| Role Definitions | Microsoft.Authorization/roleDefinitions |
azurerm_role_definition |
The exact number of resources created depends on the module configuration. In general, you can expect the module to create upwards of 180 resources for a default installation, based on the example below.
Tip
None of these resources get deployed at the Subscription scope, but Terraform still requires a Subscription to establish an authenticated session with Azure. For more information on authenticating with Azure, see Azure Provider: Authenticating using the Azure CLI.
Management resources
The module provides an option to enable deployment of management and monitoring resources into the specified Subscription as described on the Provider Configuration wiki page. It also ensures the specified Subscription is placed in the right Management Group. The module provides the benefit of managing the full lifecycle of these resources using Terraform, with native integration, into the corresponding policy assignments to ensure full policy compliance.

When you enable the Management resources capability, the module deploys and manages the following resource types:
| Resource | Azure resource type | Terraform resource type |
|---|---|---|
| Resource Groups | Microsoft.Resources/resourceGroups |
azurerm_resource_group |
| Log Analytics Workspace | Microsoft.OperationalInsights/workspaces |
azurerm_log_analytics_workspace |
| Log Analytics Solutions | Microsoft.OperationsManagement/solutions |
azurerm_log_analytics_solution |
| Automation Account | Microsoft.Automation/automationAccounts |
azurerm_automation_account |
| Log Analytics Linked Service | Microsoft.OperationalInsights/workspaces /linkedServices |
azurerm_log_analytics_linked_service |
For more information about how to use this capability, see the Deploy Management Resources wiki page.
Connectivity resources
The module provides an option to enable deployment of network topology and connectivity resources into the current Subscription context. It also ensures the specified Subscription is placed in the right Management Group. This capability currently enables deployment of a multi-region Hub & Spoke network topology. Virtual WAN is on the product roadmap.

Note
The module currently only configures the networking hub and dependent resources for the connectivity Subscription.
Although we provide an option to enable outbound Virtual Network Peering from hub to spoke, users will still need to initiate peering from spoke to hub.
This is caused by limitations in how the azurerm provider targets a specific Subscription for deployment.
When you enable the Connectivity resources capability, the module deploys and manages the following resource types:
| Resource | Azure resource type | Terraform resource type |
|---|---|---|
| Resource Groups | Microsoft.Resources/resourceGroups |
azurerm_resource_group |
| Virtual Networks | Microsoft.Network/virtualNetworks |
azurerm_virtual_network |
| Subnets | Microsoft.Network/virtualNetworks/subnets |
azurerm_subnet |
| Virtual Network Gateways | Microsoft.Network/virtualNetworkGateways |
azurerm_virtual_network_gateway |
| Azure Firewalls | Microsoft.Network/azureFirewalls |
azurerm_firewall |
| Public IP Addresses | Microsoft.Network/publicIPAddresses |
azurerm_public_ip |
| DDoS Protection Plans | Microsoft.Network/ddosProtectionPlans |
azurerm_network_ddos_protection_plan |
| DNS Zones (pending) | Microsoft.Network/dnsZones |
azurerm_dns_zone |
| Virtual Network Peerings (pending) | Microsoft.Network/virtualNetworks/virtualNetworkPeerings |
azurerm_virtual_network_peering |
For more information about how to use this capability, see the Deploy Connectivity Resources wiki page.
Identity resources
The module provides an option to enable deployment of identity and access management resources into the current Subscription context. It also ensures the specified Subscription is placed in the right Management Group.

No other resources are deployed by this capability.
If you'd like to update policy settings related to the identity Management Group, you can do so via the configure_identity_resources input variable.
For more information about how to use this capability, see the Deploy Identity Resources wiki page.
Getting started
The module requires Terraform v0.15.0 or later.
To simplify getting started, the module has been published to the Terraform Registry.
You can reference it directly within your code, as per the simple example below.
Running terraform init will automatically download the module and all dependencies.
You can view module and provider dependencies on the Dependencies tab in the Terraform Registry.
Important
There are known issues with some Terraform and AzureRM provider version combinations.
You can resolve some known issues by upgrading to the latest Terraform and AzureRM provider versions. Other known issues are transient errors that you can typically fix by re-running your deployment.
We generally recommend pinning to specific versions, and testing thoroughly before upgrading.
We will release major versions of the module when changes are needed. New major releases will ensure compatibility with the latest Terraform and AzureRM provider versions. It may result in a change in the minimum supported versions.
To get the latest features, ensure the module version is set to the latest version.
If you're upgrading to a later version of the module, don't forget to run terraform init -upgrade.
Simple example
This example code will deploy the minimum recommended Management Group and Subscription organization from the enterprise-scale reference architecture. Once you've got this simple example up and running, you can start to customize your deployment.
Tip
Even though root_parent_id is the module's only mandatory variable, we also recommend setting root_id.
Changing the root_id value will initiate a full redeployment of all resources managed by the module, including downstream dependencies.
The following code is a simple starting configuration for your main.tf root module:
# Configure Terraform to set the required AzureRM provider
# version and features{} block.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 2.77.0"
}
}
}
provider "azurerm" {
features {}
}
# 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" {}
# Use variables to customize the deployment
variable "root_id" {
type = string
default = "es"
}
variable "root_name" {
type = string
default = "Enterprise-Scale"
}
# Declare the Terraform Module for Cloud Adoption Framework
# Enterprise-scale and provide a base configuration.
module "enterprise_scale" {
source = "Azure/caf-enterprise-scale/azurerm"
version = ">= 1.0.0"
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
}
Next steps
The Terraform module for Cloud Adoption Framework enterprise-scale provides an accelerated path to building out your enterprise-scale landing zones. It also provides the flexibility to expand and customize your deployment while maintaining a simplified approach to managing the configuration of each landing zone.
To find out more, review the module on Terraform Registry, and explore the module documentation on GitHub. We'll post more examples and tutorials there that will cover how to customize your deployment.
Learn how to Deploy the Microsoft Cloud Adoption Framework Enterprise-Scale Module through HashiCorp Learn. Once there, you can also discover how some parts of the module work.
