The landing zone Terraform module is designed to accelerate deployment of individual landing zones within an Azure tenant.
We use the AzAPI provider to create the subscription and deploy the resources in a single terraform apply step.
The module is designed to be instantiated many times, once for each desired landing zone.
This is currently split logically into the following capabilities:
- Subscription creation and management group placement
- Networking - deploy multiple vnets with:
- Hub & spoke connectivity (peering to a hub network)
- vWAN connectivity
- Mesh peering (peering between spokes)
- IPAM pool allocation (dynamic address space from Azure Virtual Network Manager IPAM)
- Role assignments
- Resource provider (and feature) registration
- Resource group creation
- User assigned managed identity creation
- Federated credential configuration for GitHub Actions, Terraform Cloud, and other providers.
When creating virtual network peerings, be aware of the limit of peerings per virtual network.
We would like feedback on what's missing in the module. Please raise an issue if you have any suggestions.
The below example created a landing zone subscription with two virtual networks. One virtual network is in the default location of the subscription, the other is in a different location.
The virtual networks are peered with the supplied hub network resource ids, they are also peered with each other using the mesh peering option.
module "lz_vending" {
source = "Azure/avm-ptn-alz-sub-vending/azure"
version = "<version>" # change this to your desired version, https://www.terraform.io/language/expressions/version-constraints
# Set the default location for resources
location = "westeurope"
# subscription variables
subscription_alias_enabled = true
subscription_billing_scope = "/providers/Microsoft.Billing/billingAccounts/1234567/enrollmentAccounts/123456"
subscription_display_name = "my-subscription-display-name"
subscription_alias_name = "my-subscription-alias"
subscription_workload = "Production"
# management group association variables
subscription_management_group_association_enabled = true
subscription_management_group_id = "Corp"
# virtual network variables
virtual_network_enabled = true
virtual_networks = {
one = {
name = "my-vnet"
address_space = ["192.168.1.0/24"]
hub_peering_enabled = true
hub_network_resource_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-hub-network-rg/providers/Microsoft.Network/virtualNetworks/my-hub-network"
mesh_peering_enabled = true
}
two = {
name = "my-vnet2"
location = "northeurope"
address_space = ["192.168.2.0/24"]
hub_peering_enabled = true
hub_network_resource_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-hub-network-rg/providers/Microsoft.Network/virtualNetworks/my-hub-network2"
mesh_peering_enabled = true
}
}
umi_enabled = true
umi_name = "umi"
umi_resource_group_name = "rg-identity"
umi_role_assignments = {
myrg-contrib = {
definition = "Contributor"
relative_scope = "/resourceGroups/MyRg"
}
}
resource_group_creation_enabled = true
resource_groups = {
nwrg = {
name = "NetworkWatcherRG"
location = "westeurope"
}
myrg = {
name = "MyRg"
location = "westeurope"
}
}
# role assignments
role_assignment_enabled = true
role_assignments = {
# using role definition name, created at subscription scope
contrib_user_sub = {
principal_id = "00000000-0000-0000-0000-000000000000"
definition = "Contributor"
relative_scope = ""
},
# using a custom role definition
custdef_sub_scope = {
principal_id = "11111111-1111-1111-1111-111111111111"
definition = "/providers/Microsoft.Management/MyMg/providers/Microsoft.Authorization/roleDefinitions/ffffffff-ffff-ffff-ffff-ffffffffffff"
relative_scope = ""
},
# using relative scope (to the created or supplied subscription)
rg_owner = {
principal_id = "00000000-0000-0000-0000-000000000000"
definition = "Owner"
relative_scope = "/resourceGroups/MyRg"
},
}
}Instead of specifying static CIDR ranges, you can allocate address space dynamically from Azure Virtual Network Manager IPAM pools. This eliminates manual IP address planning and prevents overlapping address spaces across landing zones.
Use ipam_pools instead of address_space at the VNet level, and instead of address_prefixes at the subnet level.
These are mutually exclusive — you must use one or the other for each VNet and each subnet.
module "lz_vending" {
source = "Azure/avm-ptn-alz-sub-vending/azure"
version = "<version>"
location = "westeurope"
subscription_alias_enabled = true
subscription_billing_scope = "/providers/Microsoft.Billing/billingAccounts/1234567/enrollmentAccounts/123456"
subscription_display_name = "my-ipam-subscription"
subscription_alias_name = "my-ipam-subscription"
subscription_workload = "Production"
virtual_network_enabled = true
virtual_networks = {
spoke = {
name = "vnet-spoke"
resource_group_key = "rg1"
# Dynamic address space from IPAM pool
ipam_pools = [{
id = "/subscriptions/.../providers/Microsoft.Network/networkManagers/my-nm/ipamPools/my-pool"
prefix_length = 24
}]
subnets = {
workload = {
name = "subnet-workload"
ipam_pools = [{
pool_id = "/subscriptions/.../providers/Microsoft.Network/networkManagers/my-nm/ipamPools/my-pool"
prefix_length = 26
}]
}
}
}
}
}The following requirements are needed by this module:
The following resources are used by this module:
- modtm_telemetry.telemetry (resource)
- random_uuid.telemetry (resource)
- azapi_client_config.telemetry (data source)
- modtm_module_source.telemetry (data source)
The following input variables are required:
Description: The default location of resources created by this module.
Virtual networks will be created in this location unless overridden by the location attribute.
Type: string
The following input variables are optional (have default values):
Description: Whether to create budgets.
If enabled, supply the list of budgets in var.budgets.
Type: bool
Default: false
Description: Map of budgets to create for the subscription.
name- The name of the budget.amount- The total amount of cost to track with the budget.time_grain- The time grain for the budget. Must be one of Annually, BillingAnnual, BillingMonth, BillingQuarter, Monthly, or Quarterly.time_period_start- The start date for the budget.time_period_end- The end date for the budget.relative_scope- (optional) Scope relative to the created subscription. Omit, or leave blank for subscription scope. Use this if the resource group already exists. If the resource group is being created in this module, useresource_group_keyinstead.resource_group_key- (optional) The key of the resource group in which to create the budget. Use this if the resource group is being created in this module. If the resource group already exists, userelative_scopeinstead.notifications- (optional) The notifications to create for the budget.enabled- Whether the notification is enabled.operator- The operator for the notification. Must be one of GreaterThan or GreaterThanOrEqualTo.threshold- The threshold for the notification. Must be between 0 and 1000.threshold_type- The threshold type for the notification. Must be one of Actual or Forecasted.contact_emails- The contact emails for the notification.contact_roles- The contact roles for the notification.contact_groups- The contact groups for the notification.locale- The locale for the notification. Must be in the format xx-xx.
time_period_start and time_period_end must be UTC in RFC3339 format, e.g. 2018-05-13T07:44:12Z.
Example value:
subscription_budgets = {
budget1 = {
amount = 150
time_grain = "Monthly"
time_period_start = "2024-01-01T00:00:00Z"
time_period_end = "2027-12-31T23:59:59Z"
notifications = {
eightypercent = {
enabled = true
operator = "GreaterThan"
threshold = 80
threshold_type = "Actual"
contact_emails = ["john@contoso.com"]
}
budgetexceeded = {
enabled = true
operator = "GreaterThan"
threshold = 120
threshold_type = "Forecasted"
contact_roles = ["Owner"]
}
}
}
}Type:
map(object({
name = string
amount = number
time_grain = string
time_period_start = string
time_period_end = string
relative_scope = optional(string, "")
resource_group_key = optional(string)
notifications = optional(map(object({
enabled = bool
operator = string
threshold = number
threshold_type = optional(string, "Actual")
contact_emails = optional(list(string), [])
contact_roles = optional(list(string), [])
contact_groups = optional(list(string), [])
locale = optional(string, "en-us")
})), {})
}))Default: {}
Description: This variable controls whether or not telemetry is enabled for the module.
For more information see https://aka.ms/avm/telemetryinfo.
If it is set to false, then no telemetry will be collected.
Type: bool
Default: true
Description: Whether to create network security groups and security rules in the target subscription. Requires var.network_security_groups.
Type: bool
Default: false
Description: A map of the network security groups to create. The map key must be known at the plan stage, e.g. must not be calculated and known only after apply.
name: The name of the network security group. Changing this forces a new resource to be created. [required]resource_group_key: The resource group key from the resource groups map to create the user assigned identity in. [optional]resource_group_name_existing: The name of an existing resource group to create the user assigned identity in. [optional]
One of resource_group_key or resource_group_name_existing must be specified.
location: The supported Azure location where the resource exists. Changing this forces a new resource to be created.
tags: A map of tags to apply to the virtual network. [optional - default empty]
resource_types: An optional object to override the ARM resource types (and their API versions) used by the network security group submodule. [optional]this: The resource type for the network security group, e.g.Microsoft.Network/networkSecurityGroups@2024-05-01. [optional]security_rule: The resource type for the security rules, e.g.Microsoft.Network/networkSecurityGroups/securityRules@2024-05-01. [optional]
security_rules- (Optional) A map of security rules to create within the network network security group. The value is an object with the following fields:access- (Required) Specifies whether network traffic is allowed or denied. Possible values areAllowandDeny.description- (Optional) A description for this rule. Restricted to 140 characters.destination_address_prefix- (Optional) CIDR or destination IP range or*to match any IP. Tags such asVirtualNetwork,AzureLoadBalancerandInternetcan also be used. It also supports all available Service Tags likeSql.WestEurope,Storage.EastUS, etc. You can list the available service tags with the CLI:az network list-service-tags --location westcentralus.destination_address_prefixes- (Optional) List of destination address prefixes. Tags may not be used. This is required ifdestination_address_prefixis not specified.destination_application_security_group_ids- (Optional) A List of destination Application Security Group IDsdestination_port_range- (Optional) Destination Port or Range. Integer or range between0and65535or*to match any. This is required ifdestination_port_rangesis not specified.destination_port_ranges- (Optional) List of destination ports or port ranges. This is required ifdestination_port_rangeis not specified.direction- (Required) The direction specifies if rule will be evaluated on incoming or outgoing traffic. Possible values areInboundandOutbound.name- (Required) The name of the security rule. This needs to be unique across all Rules in the Network Security Group. Changing this forces a new resource to be created.priority- (Required) Specifies the priority of the rule. The value can be between 100 and 4096. The priority number must be unique for each rule in the collection. The lower the priority number, the higher the priority of the rule.protocol- (Required) Network protocol this rule applies to. Possible values includeTcp,Udp,Icmp,Esp,Ahor*(which matches all).source_address_prefix- (Optional) CIDR or source IP range or * to match any IP. Tags such asVirtualNetwork,AzureLoadBalancerandInternetcan also be used. This is required ifsource_address_prefixesis not specified.source_address_prefixes- (Optional) List of source address prefixes. Tags may not be used. This is required ifsource_address_prefixis not specified.source_application_security_group_ids- (Optional) A List of source Application Security Group IDssource_port_range- (Optional) Source Port or Range. Integer or range between0and65535or*to match any. This is required ifsource_port_rangesis not specified.source_port_ranges- (Optional) List of source ports or port ranges. This is required ifsource_port_rangeis not specified.
Type:
map(object({
name = string
location = optional(string)
resource_group_key = optional(string)
resource_group_name_existing = optional(string)
tags = optional(map(string))
resource_types = optional(object({
this = optional(string)
security_rule = optional(string)
}), {})
security_rules = optional(map(object({
access = string
description = optional(string)
destination_address_prefix = optional(string)
destination_address_prefixes = optional(set(string))
destination_application_security_group_ids = optional(set(string))
destination_port_range = optional(string)
destination_port_ranges = optional(set(string))
direction = string
name = string
priority = number
protocol = string
source_address_prefix = optional(string)
source_address_prefixes = optional(set(string))
source_application_security_group_ids = optional(set(string))
source_port_range = optional(string)
source_port_ranges = optional(set(string))
})))
}))Default: {}
Description: Whether to create additional resource groups in the target subscription. Requires var.resource_groups.
Type: bool
Default: false
Description: A map of the resource groups to create. The value is an object with the following attributes:
name- The name of the resource group.location- (Optional) The location of the resource group.tags- (Optional) A map of tags to assign to the resource group. Defaults to empty map.lock_enabled- (Optional) Whether to enable a resource lock on the resource group. Defaults tofalse.lock_name- (Optional) The name of the resource lock. Defaults to empty string.
We recommend that you include an entry to create the NetworkWatcherRG resource group so that this is managed by Terraform.
Type:
map(object({
name = string
location = optional(string)
tags = optional(map(string), {})
lock_enabled = optional(bool, false)
lock_name = optional(string, "")
}))Default: {}
Description: Whether to create role assignments.
If enabled, supply the list of role assignments in var.role_assignments.
Type: bool
Default: false
Description: Supply a map of objects containing the details of the role assignments to create.
Object fields:
principal_id: The directory/object id of the principal to assign the role to.definition: The role definition to assign. Either use the name or the role definition resource id. If supplying a definition ID, use a scopeless role definition ID (i.e. starting with/providers/Microsoft.Authorization/roleDefinitions/).relative_scope: (optional) Scope relative to the created subscription. Omit, or leave blank for subscription scope.resource_group_scope_key: (optional) The resource group key from the resource groups map to use as the scope for the role assignment. If supplied, this takes precedence overrelative_scope.condition: (optional) A condition to apply to the role assignment. See Conditions Custom Security Attributes for more details.condition_version: (optional) The version of the condition syntax. See Conditions Custom Security Attributes for more details.principal_type: (optional) The type of the principal. Can be"User","Group","Device","ForeignGroup", or"ServicePrincipal".definition_lookup_enabled: (optional) Whether to look up the role definition resource id from the the Azure API. Default isfalse, where we use a static module of role definitions.use_random_uuid: (optional) Whether to use a random UUID for the role assignment name. Default isfalse. If set totrue, the role assignment name will be a random UUID, otherwise it will be a deterministic UUID based on the scope, principal id, and role definition id.
E.g.
role_assignments = {
# Example using role definition name:
contributor_user = {
principal_id = "00000000-0000-0000-0000-000000000000",
definition = "Contributor",
relative_scope = "",
condition = "(!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})",
condition_version = "2.0",
},
# Example using role definition id and RG scope:
myrg_custom_role = {
principal_id = "11111111-1111-1111-1111-111111111111",
definition = "/providers/Microsoft.Management/managementGroups/mymg/providers/Microsoft.Authorization/roleDefinitions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
relative_scope = "/resourceGroups/MyRg",
}
}Type:
map(object({
principal_id = string,
definition = string,
relative_scope = optional(string, "")
resource_group_scope_key = optional(string)
condition = optional(string)
condition_version = optional(string)
principal_type = optional(string)
definition_lookup_enabled = optional(bool, false)
use_random_uuid = optional(bool, false)
}))Default: {}
Description: Whether to create route tables and routes in the target subscription. Requires var.route_tables.
Type: bool
Default: false
Description: A map defining route tables and their associated routes to be created:
name(required): The name of the route table.location(required): The location of the resource group.resource_group_key: The resource group key from the resource groups map to create the user assigned identity in. [optional]resource_group_name_existing: The name of an existing resource group to create the user assigned identity in. [optional]
One of resource_group_key or resource_group_name_existing must be specified.
bgp_route_propagation_enabled(optional): Boolean that controls whether routes learned by BGP are propagated to the route table. Default istrue.tags(optional): A map of key-value pairs for tags associated with the route table.resource_types(optional): An object to override the ARM resource types (and their API versions) used by the route table submodule.this(optional): The resource type for the route table, e.g.Microsoft.Network/routeTables@2024-05-01.route(optional): The resource type for the routes, e.g.Microsoft.Network/routeTables/routes@2024-05-01.
routes(optional): A map defining routes for the route table. Each route object has the following properties:name(required): The name of the route.address_prefix(required): The address prefix for the route.next_hop_type(required): The next hop type, must be one of: 'Internet', 'None', 'VirtualAppliance', 'VirtualNetworkGateway', 'VnetLocal'.next_hop_in_ip_address(optional): The next hop IP address for the route. Required if next hop type is 'VirtualAppliance'.
Note: Migration protection is built-in. The module uses
ignore_other_items_in_list = ["properties.routes"]to preserve existing inline routes.
Type:
map(object({
name = string
location = string
resource_group_key = optional(string)
resource_group_name_existing = optional(string)
bgp_route_propagation_enabled = optional(bool, true)
tags = optional(map(string))
resource_types = optional(object({
this = optional(string)
route = optional(string)
}), {})
routes = optional(map(object({
name = string
address_prefix = string
next_hop_type = string
next_hop_in_ip_address = optional(string)
})), {})
}))Default: {}
Description: Whether to create a new subscription using the subscription alias resource.
If enabled, the following must also be supplied:
subscription_alias_namesubscription_display_namesubscription_billing_scopesubscription_workload
Optionally, supply the following to enable the placement of the subscription into a management group:
subscription_management_group_idsubscription_management_group_association_enabled
If disabled, supply the subscription_id variable to use an existing subscription instead.
Note: When the subscription is destroyed, this module will try to remove the NetworkWatcherRG resource group using
az cli. This requires theaz clitool be installed and authenticated. If the command fails for any reason, the provider will attempt to cancel the subscription anyway.
Type: bool
Default: false
Description: The name of the subscription alias.
The string must be comprised of a-z, A-Z, 0-9, - and _.
The maximum length is 63 characters.
You may also supply an empty string if you do not want to create a new subscription alias.
In this scenario, subscription_enabled should be set to false and subscription_id must be supplied.
Type: string
Default: null
Description: The billing scope for the new subscription alias.
A valid billing scope starts with /providers/Microsoft.Billing/billingAccounts/ and is case sensitive.
E.g.
- For CustomerLed and FieldLed, e.g. MCA -
/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/billingProfiles/{billingProfileName}/invoiceSections/{invoiceSectionName} - For PartnerLed, e.g. MPA -
/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/customers/{customerName} - For Legacy EA -
/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/enrollmentAccounts/{enrollmentAccountName}
You may also supply an empty string if you do not want to create a new subscription alias.
In this scenario, subscription_enabled should be set to false and subscription_id must be supplied.
Type: string
Default: null
Description: The display name of the subscription alias.
The string must be comprised of a-z, A-Z, 0-9, -, _ and space.
The maximum length is 63 characters.
You may also supply an empty string if you do not want to create a new subscription alias.
In this scenario, subscription_enabled should be set to false and subscription_id must be supplied.
Type: string
Default: null
Description: An existing subscription id.
Use this when you do not want the module to create a new subscription.
But do want to manage the management group membership.
A GUID should be supplied in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
All letters must be lowercase.
When using this, subscription_management_group_association_enabled should be enabled,
and subscription_management_group_id should be supplied.
You may also supply an empty string if you want to create a new subscription alias.
In this scenario, subscription_alias_enabled should be set to true and the following other variables must be supplied:
subscription_alias_namesubscription_alias_display_namesubscription_alias_billing_scopesubscription_alias_workload
Type: string
Default: null
Description: Whether to create the management group association resource.
If enabled, the subscription_management_group_id must also be supplied.
Type: bool
Default: false
Description: The destination management group ID for the new subscription.
Note: Do not supply the display name.
The management group ID forms part of the Azure resource ID. E.g.,
/providers/Microsoft.Management/managementGroups/{managementGroupId}.
Type: string
Default: null
Description: The map of resource providers to register.
The map keys are the resource provider namespace, e.g. Microsoft.Compute.
The map values are a list of provider features to enable.
Leave the value empty to not register any resource provider features.
The default values are taken from Hashicorp's AzureRM provider.
Type: map(set(string))
Default:
{
"Microsoft.AVS": [],
"Microsoft.ApiManagement": [],
"Microsoft.AppPlatform": [],
"Microsoft.Authorization": [],
"Microsoft.Automation": [],
"Microsoft.Blueprint": [],
"Microsoft.BotService": [],
"Microsoft.Cache": [],
"Microsoft.Cdn": [],
"Microsoft.CognitiveServices": [],
"Microsoft.Compute": [],
"Microsoft.ContainerInstance": [],
"Microsoft.ContainerRegistry": [],
"Microsoft.ContainerService": [],
"Microsoft.CostManagement": [],
"Microsoft.CustomProviders": [],
"Microsoft.DBforMariaDB": [],
"Microsoft.DBforMySQL": [],
"Microsoft.DBforPostgreSQL": [],
"Microsoft.DataLakeAnalytics": [],
"Microsoft.DataLakeStore": [],
"Microsoft.DataMigration": [],
"Microsoft.DataProtection": [],
"Microsoft.Databricks": [],
"Microsoft.DesktopVirtualization": [],
"Microsoft.DevTestLab": [],
"Microsoft.Devices": [],
"Microsoft.DocumentDB": [],
"Microsoft.EventGrid": [],
"Microsoft.EventHub": [],
"Microsoft.GuestConfiguration": [],
"Microsoft.HDInsight": [],
"Microsoft.HealthcareApis": [],
"Microsoft.KeyVault": [],
"Microsoft.Kusto": [],
"Microsoft.Logic": [],
"Microsoft.MachineLearningServices": [],
"Microsoft.Maintenance": [],
"Microsoft.ManagedIdentity": [],
"Microsoft.ManagedServices": [],
"Microsoft.Management": [],
"Microsoft.Maps": [],
"Microsoft.MarketplaceOrdering": [],
"Microsoft.Network": [],
"Microsoft.NotificationHubs": [],
"Microsoft.OperationalInsights": [],
"Microsoft.OperationsManagement": [],
"Microsoft.PolicyInsights": [],
"Microsoft.PowerBIDedicated": [],
"Microsoft.RecoveryServices": [],
"Microsoft.Relay": [],
"Microsoft.Resources": [],
"Microsoft.Search": [],
"Microsoft.Security": [],
"Microsoft.SecurityInsights": [],
"Microsoft.ServiceBus": [],
"Microsoft.ServiceFabric": [],
"Microsoft.Sql": [],
"Microsoft.Storage": [],
"Microsoft.StreamAnalytics": [],
"Microsoft.Web": [],
"microsoft.insights": []
}Description: Whether to register resource providers for the subscription.
Use var.subscription_register_resource_providers_and_features to customize registration.
Type: bool
Default: false
Description: A map of tags to assign to the newly created subscription.
Only valid when subsciption_alias_enabled is set to true.
Example value:
subscription_tags = {
mytag = "myvalue"
mytag2 = "myvalue2"
}Type: map(string)
Default: {}
Description: Whether to update an existing subscription with the supplied tags and display name.
If enabled, the following must also be supplied:
subscription_id
Type: bool
Default: false
Description: The billing scope for the new subscription alias.
The workload type can be either Production or DevTest and is case sensitive.
You may also supply an empty string if you do not want to create a new subscription alias.
In this scenario, subscription_enabled should be set to false and subscription_id must be supplied.
Type: string
Default: null
Description: Whether to enable the creation of a user-assigned managed identity.
Requires umi.name and umi.resosurce_group_name to be non-empty.
Type: bool
Default: false
Description: A map of user-managed identities to create. The map key must be known at the plan stage, e.g. must not be calculated and known only after apply. The value is a map of attributes.
name: The name of the user-assigned managed identity. [required]resource_group_key: The resource group key from the resource groups map to create the user assigned identity in. [optional]resource_group_name_existing: The name of an existing resource group to create the user assigned identity in. [optional]
One of resource_group_key or resource_group_name_existing must be specified.
location: The location of the user-assigned managed identity. [optional]tags: The tags to apply to the user-assigned managed identity. [optional]
The following fields are used to configure role assignments for the user-assigned managed identity.
role_assignments: A map of role assignments to create for the user-assigned managed identity. [optional] - Seerole_assignmentsvariable for details.
The following fields are used to configure federated identity credentials, using OpenID Connect, for use in GitHub actions, Azure DevOps pipelines, and Terraform Cloud.
federated_credentials_github: A map of federated credentials to create for the user-assigned managed identity. [optional]name- the name of the federated credential resource, the last segment of the Azure resource id.organization- the name of the GitHub organization, e.g.Azureinhttps://github.com/Azure/terraform-azurerm-lz-vending.repository- the name of the GitHub respository, e.g.terraform-azurerm-lz-vendinginhttps://github.com/Azure/terraform-azurerm-lz-vending.entity- one of 'environment', 'pull_request', 'tag', or 'branch'enterprise_slug- the name of the GitHub Enterprise, e.g.my-enterprise. This is optional and only valid when using an enterprise.value- identifies theentitytype, e.g.mainwhen using entity isbranch. Should be blank whenentityispull_request.
federated_credentials_terraform_cloud: A map of federated credentials to create for the user-assigned managed identity. [optional]name- the name of the federated credential resource, the last segment of the Azure resource id.organization- the name of the Terraform Cloud organization.project- the name of the Terraform Cloud project.workspace- the name of the Terraform Cloud workspace.run_phase- one ofplan, orapply.
federated_credentials_advanced: A map of federated credentials to create for the user-assigned managed identity. [optional]name: The name of the federated credential resource, the last segment of the Azure resource id.subject_identifier: The subject of the token.issuer_url: The URL of the token issuer, should begin withhttps://audience: (optional) The token audience, defaults toapi://AzureADTokenExchange.
Type:
map(object({
name = string
resource_group_key = optional(string)
resource_group_name_existing = optional(string)
location = optional(string)
tags = optional(map(string), {})
role_assignments = optional(map(object({
definition = string
relative_scope = optional(string, "")
resource_group_scope_key = optional(string)
condition = optional(string)
condition_version = optional(string)
principal_type = optional(string)
definition_lookup_enabled = optional(bool, false)
use_random_uuid = optional(bool, false)
})), {})
federated_credentials_github = optional(map(object({
name = optional(string)
organization = string
repository = string
entity = string
enterprise_slug = optional(string)
value = optional(string)
})), {})
federated_credentials_terraform_cloud = optional(map(object({
name = optional(string)
organization = string
project = string
workspace = string
run_phase = string
})), {})
federated_credentials_advanced = optional(map(object({
name = string
subject_identifier = string
issuer_url = string
audiences = optional(set(string), ["api://AzureADTokenExchange"])
})), {})
}))Default: {}
Description: Enables and disables the virtual network submodule.
Type: bool
Default: false
Description: A map of the virtual networks to create. The map key must be known at the plan stage, e.g. must not be calculated and known only after apply.
name: The name of the virtual network. [required]address_space: The address space of the virtual network as a list of strings in CIDR format, e.g.["192.168.0.0/24", "10.0.0.0/24"]. Mutually exclusive withipam_pools. [optional - required ifipam_poolsis not set]ipam_pools: A list of IPAM pool objects for dynamic address space allocation from Azure Virtual Network Manager IPAM. Mutually exclusive withaddress_space. [optional - required ifaddress_spaceis not set]id: The resource ID of the IPAM pool. [required]prefix_length: The prefix length to allocate from the pool (2-29 for IPv4, 48-64 for IPv6). [required]
resource_group_key: The resource group key from the resource groups map to create the virtual network in. [optional]resource_group_name_existing: The name of an existing resource group to use for the virtual network. [optional]
One of resource_group_key or resource_group_name_existing must be specified.
dns_servers: A list of DNS servers to use for the virtual network, e.g.["192.168.0.1", "10.0.0.1"]. If empty will use the Azure default DNS. [optional - default empty list]
ddos_protection_enabled: Whether to enable ddos protection. [optional]ddos_protection_plan_id: The resource ID of the protection plan to attach the vnet. [optional - but required if ddos_protection_enabled istrue]
location: The location of the virtual network (and resource group if creation is enabled). [optional, will usevar.locationif not specified or empty string]
Note at least one of
locationorvar.locationmust be specified. If both are empty then the module will fail.
subnets- (Optional) A map of subnets to create in the virtual network. The value is an object with the following fields:name- The name of the subnet.address_prefixes- The IPv4 address prefixes to use for the subnet in CIDR format. Mutually exclusive withipam_pools. [optional - required ifipam_poolsis not set]ipam_pools- (Optional) A list of IPAM pool objects for dynamic subnet address allocation. Mutually exclusive withaddress_prefixes.pool_id- The resource ID of the IPAM pool.prefix_length- (Optional) The prefix length to allocate from the pool.
nat_gateway- (Optional) An object with the following fields:id- The ID of the NAT Gateway which should be associated with the Subnet. Changing this forces a new resource to be created.
network_security_group- (Optional) An object with the following fields:id- The ID of the Network Security Group which should be associated with the Subnet. Changing this forces a new association to be created.key_reference- The name of the var.network_security_group map key that should be associated with the subnet once it has been provisioned. If you are passing in anidvalue, this will not be used.
private_endpoint_network_policies_enabled- (Optional) Enable or Disable network policies for the private endpoint on the subnet. Setting this to true will Enable the policy and setting this to false will Disable the policy. Defaults to true.private_link_service_network_policies_enabled- (Optional) Enable or Disable network policies for the private link service on the subnet. Setting this to true will Enable the policy and setting this to false will Disable the policy. Defaults to true.route_table- (Optional) An object with the following fields which are mutually exclusive, choose either an external route table or the generated route table:id- The ID of the Route Table which should be associated with the Subnet. Changing this forces a new association to be created.key_reference- The name of the var.route_tables map key that should be associated with the subnet once it has been provisioned. If you are passing in anidvalue, this will not be used.
default_outbound_access_enabled- (Optional) Whether to allow internet access from the subnet. Defaults tofalse.service_endpoints- (Optional) The list of Service endpoints to associate with the subnet.service_endpoint_policies- (Optional) The list of Service Endpoint Policy objects with the resource id to associate with the subnet.id- The ID of the endpoint policy that should be associated with the subnet.
delegations- (Optional) A list of delegation objects with the following fields:name- The name of the delegation.service_delegation- An object with the following fields:name- The name of the service delegation.
The following values configure bi-directional hub & spoke peering for the given virtual network:
hub_peering_enabled: Whether to enable hub peering. [optional]hub_peering_direction: The direction of the peering. [optional - allowed values are:tohub,fromhuborboth- defaultboth]hub_network_resource_id: The resource ID of the hub network to peer with. [optional - but required if hub_peering_enabled istrue]hub_peering_name_tohub: The name of the peering to the hub network. [optional - leave empty to use calculated name]hub_peering_name_fromhub: The name of the peering from the hub network. [optional - leave empty to use calculated name]
The following values configure the options for the hub network peering. These are configurable in each direction:
allow_forwarded_traffic: Whether to allow forwarded traffic for the peering. [optional - defaulttrue]allow_gateway_transit: Whether to allow gateway transit for the peering. [optional - defaultfalse(outbound) ortrue(inbound)]allow_virtual_network_access: Whether to allow virtual network access for the peering. [optional - defaulttrue]do_not_verify_remote_gateways: Whether to not verify remote gateways for the peering. [optional - defaultfalse]enable_only_ipv6_peering: Whether to enable only IPv6 peering. [optional - defaultfalse]local_peered_address_spaces: A list of local address spaces to peer with. [optional - default empty and only used ifpeer_complete_vnetsisfalse]local_peered_subnets: A list of local subnets to peer with. [optional - default empty and only used ifpeer_complete_vnetsisfalse]peer_complete_vnets: Whether to peer complete virtual networks. [optional - defaulttrue]remote_peered_address_spaces: A list of remote address spaces to peer with. [optional - default empty and only used ifpeer_complete_vnetsisfalse]remote_peered_subnets: A list of remote subnets to peer with. [optional - default empty and only used ifpeer_complete_vnetsisfalse]use_remote_gateways: Whether to use remote gateways for the peering. [optional - defaulttrue(outbound) orfalse(inbound)]
Mesh peering is the capability to create a bi-directional peerings between all supplied virtual networks in var.virtual_networks.
Peerings will only be created between virtual networks with the mesh_peering_enabled value set to true.
mesh_peering_enabled: Whether to enable mesh peering for this virtual network. Must be enabled on more than one virtual network for any peerings to be created. [optional]mesh_peering_allow_forwarded_traffic: Whether to allow forwarded traffic for the mesh peering. [optional - default false]
vwan_associated_routetable_resource_id: The resource ID of the route table to associate with the virtual network. [optional - leave empty to usedefaultRouteTableon hub]vwan_connection_enabled: Whether to create a connection to a Virtual WAN. [optional - default false]vwan_connection_name: The name of the connection to the Virtual WAN. [optional - leave empty to use calculated name]vwan_hub_resource_id: The resource ID of the hub to connect to. [optional - but required if vwan_connection_enabled istrue]vwan_propagated_routetables_labels: A list of labels of route tables to propagate to the virtual network. [optional - leave empty to use["default"]]vwan_propagated_routetables_resource_ids: A list of resource IDs of route tables to propagate to the virtual network. [optional - leave empty to usedefaultRouteTableon hub]vwan_security_configuration: A map of security configuration values for VWAN hub connection - see below. [optional - default empty]secure_internet_traffic: Whether to forward internet-bound traffic to the destination specified in the routing policy. [optional - defaultfalse]secure_private_traffic: Whether to all internal traffic to the destination specified in the routing policy. Not compatible withrouting_intent_enabled. [optional - defaultfalse]routing_intent_enabled: Enable to use with a Virtual WAN hub with routing intent enabled. Routing intent on hub is configured outside this module. [optional - defaultfalse]
tags: A map of tags to apply to the virtual network. [optional - default empty]
Type:
map(object({
name = string
address_space = optional(list(string))
resource_group_key = optional(string)
resource_group_name_existing = optional(string)
ipam_pools = optional(list(object({
id = string
prefix_length = number
})))
location = optional(string)
dns_servers = optional(list(string), [])
flow_timeout_in_minutes = optional(number)
ddos_protection_enabled = optional(bool, false)
ddos_protection_plan_id = optional(string)
subnets = optional(map(object(
{
name = string
address_prefixes = optional(list(string))
ipam_pools = optional(list(object({
pool_id = string
prefix_length = optional(number)
})))
nat_gateway = optional(object({
id = string
}))
network_security_group = optional(object({
id = optional(string)
key_reference = optional(string)
}))
private_endpoint_network_policies = optional(string, "Enabled")
private_link_service_network_policies_enabled = optional(bool, true)
route_table = optional(object({
id = optional(string)
key_reference = optional(string)
}))
default_outbound_access_enabled = optional(bool, false)
service_endpoints = optional(set(string))
service_endpoint_policies = optional(map(object({
id = string
})))
delegations = optional(list(
object(
{
name = string
service_delegation = object({
name = string
})
}
)
))
}
)), {})
hub_network_resource_id = optional(string)
hub_peering_enabled = optional(bool, false)
hub_peering_direction = optional(string, "both")
hub_peering_name_tohub = optional(string)
hub_peering_options_tohub = optional(object({
allow_forwarded_traffic = optional(bool, true)
allow_gateway_transit = optional(bool, false)
allow_virtual_network_access = optional(bool, true)
do_not_verify_remote_gateways = optional(bool, false)
enable_only_ipv6_peering = optional(bool, false)
local_peered_address_spaces = optional(list(string), [])
local_peered_subnets = optional(list(string), [])
peer_complete_vnets = optional(bool, true)
remote_peered_address_spaces = optional(list(string), [])
remote_peered_subnets = optional(list(string), [])
use_remote_gateways = optional(bool, true)
}), {})
hub_peering_name_fromhub = optional(string)
hub_peering_options_fromhub = optional(object({
allow_forwarded_traffic = optional(bool, true)
allow_gateway_transit = optional(bool, true)
allow_virtual_network_access = optional(bool, true)
do_not_verify_remote_gateways = optional(bool, false)
enable_only_ipv6_peering = optional(bool, false)
local_peered_address_spaces = optional(list(string), [])
local_peered_subnets = optional(list(string), [])
peer_complete_vnets = optional(bool, true)
remote_peered_address_spaces = optional(list(string), [])
remote_peered_subnets = optional(list(string), [])
use_remote_gateways = optional(bool, false)
}), {})
mesh_peering_enabled = optional(bool, false)
mesh_peering_allow_forwarded_traffic = optional(bool, false)
vwan_associated_routetable_resource_id = optional(string)
vwan_connection_enabled = optional(bool, false)
vwan_connection_name = optional(string)
vwan_hub_resource_id = optional(string)
vwan_propagated_routetables_labels = optional(list(string), [])
vwan_propagated_routetables_resource_ids = optional(list(string), [])
vwan_security_configuration = optional(object({
secure_internet_traffic = optional(bool, false)
secure_private_traffic = optional(bool, false)
routing_intent_enabled = optional(bool, false)
}), {})
tags = optional(map(string), {})
}))Default: {}
Description: The duration to wait after vending a subscription before performing subscription operations.
Type:
object({
create = optional(string, "30s")
destroy = optional(string, "0s")
})Default: {}
The following outputs are exported:
Description: The created budget resource IDs, expressed as a map.
Description: The management_group_subscription_association_id output is the ID of the management group subscription association.
Value will be null if var.subscription_management_group_association_enabled is false.
Description: The created resource group IDs, expressed as a map.
Description: The resource_id is the Azure resource id of the subscription that resources have been deployed into.
Description: The created route table resource IDs, expressed as a map.
Description: The subscription_id is the Azure subscription id that resources have been deployed into.
Description: The subscription_resource_id is the Azure subscription resource id that resources have been deployed into
Description: The client id of the user managed identity.
Value will be null if var.umi_enabled is false.
Description: The principal id of the user managed identity, sometimes known as the object id.
Value will be null if var.umi_enabled is false.
Description: The Azure resource id of the user managed identity.
Value will be null if var.umi_enabled is false.
Description: The tenant id of the user managed identity.
Value will be null if var.umi_enabled is false.
Description: A map of virtual network resource ids, keyed by the var.virtual_networks input map. Only populated if the virtualnetwork submodule is enabled.
The following Modules are called:
Source: ./modules/budget
Version:
Source: ./modules/network-security-group
Version:
Source: ./modules/resource-group
Version:
Source: ./modules/resource-provider
Version:
Source: ./modules/role-assignment
Version:
Source: ./modules/role-assignment
Version:
Source: ./modules/route-table
Version:
Source: ./modules/subscription
Version:
Source: ./modules/user-assigned-managed-identity
Version:
Source: ./modules/virtual-network
Version:
The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.