As Azure environments grow, manual subscription creation becomes a scalability and governance challenge. Subscription vending solves this problem by enabling automated, standardized, and governed subscription creation using Infrastructure as Code (IaC). This article provides a complete, production‑ready guide to implementing Azure subscription vending using Azure Verified Modules (AVM) with Terraform, including identity and billing permissions, Subscription Creator role assignment, and best practices aligned with Azure Landing Zones.
Why Subscription Vending Is Critical at Scale
Azure subscriptions define the security, governance, and billing boundary for workloads. In large organizations, manual subscription creation often leads to:
- Inconsistent management group placement
- Delayed or missing policy enforcement
- Incorrect RBAC assignments
- Lack of cost controls
- Platform teams becoming a bottleneck
Subscription vending standardizes this process by allowing application teams to request subscriptions while platform teams enforce governance through automation. Microsoft formally recommends this approach as part of Azure Landing Zones.
Azure Verified Modules (AVM) – The Foundation
Azure Verified Modules (AVM) are Microsoft‑owned and Microsoft‑supported Infrastructure as Code modules that codify Azure Well‑Architected Framework guidance.
AVM provides:
- Resource modules – deploy individual Azure resources
- Pattern modules – deploy opinionated architectural patterns
Subscription vending is delivered as an AVM pattern module, making it the preferred and supported approach for enterprise landing zones.
Key benefits:
- Microsoft supported
- Terraform and Bicep support
- Built‑in governance
- Used by Azure Landing Zone accelerators
AVM Subscription Vending Pattern Overview
The Terraform module used for subscription vending is:
Azure/avm-ptn-alz-sub-vending
This module enables:
- Azure subscription creation
- Management group association
- Resource provider registration
- RBAC assignments
- Budget enforcement
- Optional networking scaffolding
The module uses the AzAPI provider, allowing subscription creation and governance configuration in a single Terraform apply.
Reference Architecture
High‑level flow:
- Subscription request captured (YAML/JSON or pipeline input)
- CI/CD pipeline triggers Terraform
- AVM module creates the subscription
- Subscription is placed in the correct management group
- Governance (RBAC, policies, budgets) is applied automatically
This model aligns with Microsoft’s Landing Zone architecture.
Prerequisites
1. Azure Billing and Tenant
- Enterprise Agreement (EA) or Microsoft Customer Agreement (MCA)
- Billing Scope ID, for example:
/providers/Microsoft.Billing/billingAccounts/<id>/enrollmentAccounts/<id>
2. Management Group Hierarchy
A predefined management group hierarchy must exist:
Tenant Root
├── Platform
├── LandingZones
│ ├── Corp
│ └── Online
└── Sandbox
3. Tooling
az version
terraform version
Identity & Permissions Model (Critical Section)
Automated subscription vending requires a non‑interactive identity (Service Principal or Managed Identity).
The key permission is the Subscription Creator role, which is a billing‑scope role, not a standard Azure RBAC role.
⚠️ Important
The Subscription Creator role cannot be assigned using the Azure Portal.
Assigning the Subscription Creator Role (Enterprise Agreement)
Role Scope Summary
| Agreement | Role Scope |
|---|---|
| EA | Enrollment Account |
| MCA | Billing Profile / Invoice Section |
This guide covers Enterprise Agreement (EA), which is most common in large landing zones.
Step 1: Create a Service Principal
az ad sp create-for-rbac \
--name avm-subscription-vending-sp \
--skip-assignment
Store securely:
- appId
- tenant
- password (or certificate)
Step 2: Get Service Principal Object ID
az ad sp show \
--id <appId> \
--query id \
--output tsv
⚠️ Use the Object ID, not the Application ID.
Step 3: Identify the Enrollment Account
az rest \
--method get \
--url "https://management.azure.com/providers/Microsoft.Billing/enrollmentAccounts?api-version=2019-10-01-preview"
Capture:
- Enrollment Account ID
- Full resource ID
Step 4: Assign Subscription Creator Role (REST API)
az rest \
--method put \
--url "https://management.azure.com/providers/Microsoft.Billing/enrollmentAccounts/<ENROLLMENT_ACCOUNT_ID>/providers/Microsoft.Authorization/roleAssignments/<GUID>?api-version=2019-10-01-preview" \
--body '{
"properties": {
"principalId": "<SERVICE_PRINCIPAL_OBJECT_ID>",
"roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/4f8fab4f-1852-4a58-9a5b-5f5f75a2f8a8"
}
}'
Notes:
- <GUID> → any new GUID
- Role definition ID corresponds to Subscription Creator
Step 5: Verify Assignment
az rest \
--method get \
--url "https://management.azure.com/providers/Microsoft.Billing/enrollmentAccounts/<ENROLLMENT_ACCOUNT_ID>/providers/Microsoft.Authorization/roleAssignments?api-version=2019-10-01-preview"
Important Constraints
- Service Principal must be in the same tenant as the EA billing account
- Cross‑tenant assignment is not supported
- Subscription Creator will not appear in Azure Portal IAM
Terraform Implementation Using AVM
Provider Configuration
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
azapi = {
source = "Azure/azapi"
}
}
}
provider "azurerm" {
features {}
}
AVM Subscription Vending Module
module "subscription_vending" {
source = "Azure/avm-ptn-alz-sub-vending/azure"
version = "0.1.1"
location = "southeastasia"
subscription_alias_enabled = true
subscription_display_name = "corp-finance-prod"
subscription_alias_name = "corp-finance-prod"
subscription_workload = "Production"
subscription_billing_scope = var.billing_scope
subscription_management_group_association_enabled = true
subscription_management_group_id = "Corp"
}
Optional Governance
Budgets
budget_enabled = true
budget_amount = 5000
RBAC
role_assignments = {
ops = {
principal_id = var.ops_group_id
role_definition_name = "Contributor"
}
}
Deploy
terraform init
terraform plan
terraform apply
Validate
az account list --all --query "[?name=='corp-finance-prod']"
az managementgroup subscription list --name Corp
Operational Best Practices
- Use GitOps‑based subscription requests
- Store parameters in version‑controlled YAML/JSON
- Enforce PR approvals for new subscriptions
- Treat subscriptions as immutable infrastructure
- Regularly update AVM module versions
- Avoid tenant‑wide Owner permissions
Conclusion
Subscription vending using Azure Verified Modules enables secure, scalable, and repeatable Azure subscription management.
By combining AVM, Terraform, and correctly scoped billing permissions, platform teams can fully automate subscription creation while enforcing governance from day one.
For any organization adopting Azure Landing Zones, AVM‑based subscription vending should be considered a foundational capability, not an optional enhancement.
References
- Azure Verified Modules
https://azure.github.io/Azure-Verified-Modules/ - AVM Subscription Vending Module
https://registry.terraform.io/modules/Azure/avm-ptn-alz-sub-vending/azure/latest - Subscription Vending – Azure Architecture Center
https://learn.microsoft.com/azure/architecture/landing-zones/subscription-vending - Assign EA roles to service principals
https://learn.microsoft.com/azure/cost-management-billing/manage/assign-roles-azure-service-principals