Task 03: Create Resource Groups
DOCUMENT CATEGORY: Runbook
SCOPE: Full CAF/WAF resource group structure
PURPOSE: Create multi-subscription resource group organization
MASTER REFERENCE: Microsoft Learn — Resource Groups
Status: Active
Overview
Create resource groups within each subscription following the full CAF/WAF deployment model. Each subscription gets resource groups organized by function, providing granular access control, cost tracking, and lifecycle management.
What This Accomplishes
- Resource organization — logical grouping of related Azure resources per subscription
- Access control — resource group-level RBAC boundaries within each subscription
- Cost tracking — granular cost allocation using subscription + resource group + tags
- Lifecycle management — coordinated resource deployment and cleanup per function
Prerequisites
| Prerequisite | Detail |
|---|---|
| Subscriptions | All subscriptions created and associated with management groups (Task 02) |
| Permissions | Contributor or Owner role on each target subscription |
| Authenticated Azure session | See Authentication |
variables.yml | Configured with resource group names per subscription |
Resource Group Plan
Platform Identity Subscription
Subscription: iic-platform-identity-001 (config: azure.subscriptions.platform_identity.name)
| Resource Group | Purpose | Config Path |
|---|---|---|
rg-identity-entraconnect-eus-01 | Entra ID Connect servers | azure_resources.platform_identity.rg_entraconnect |
rg-identity-pim-eus-01 | Privileged Identity Management | azure_resources.platform_identity.rg_pim |
Platform Management Subscription
Subscription: iic-platform-management-001 (config: azure.subscriptions.platform_management.name)
| Resource Group | Purpose | Config Path |
|---|---|---|
rg-mgmt-monitoring-eus-01 | Azure Monitor, Log Analytics | azure_resources.platform_management.rg_monitoring |
rg-mgmt-automation-eus-01 | Automation accounts, runbooks | azure_resources.platform_management.rg_automation |
rg-mgmt-backup-eus-01 | Recovery Services vaults | azure_resources.platform_management.rg_backup |
Platform Connectivity Subscription
Subscription: iic-platform-connectivity-001 (config: azure.subscriptions.platform_connectivity.name)
| Resource Group | Purpose | Config Path |
|---|---|---|
rg-connectivity-hub-eus-01 | Hub VNet, Azure Firewall | azure_resources.platform_connectivity.rg_hub |
rg-connectivity-dns-eus-01 | Private DNS zones | azure_resources.platform_connectivity.rg_dns |
rg-connectivity-bastion-eus-01 | Azure Bastion hosts | azure_resources.platform_connectivity.rg_bastion |
Landing Zone Subscriptions
Each landing zone subscription (e.g., iic-lz-azurelocal-corp-001) gets a single resource group per cluster — the same pattern as simplified deployment:
| Resource Group | Purpose | Config Path |
|---|---|---|
rg-c01-azl-eus-01 | Azure Local cluster + Arc resources | azure_resources.resource_group_name |
For multiple clusters in the same subscription, increment the cluster identifier: rg-c01-azl-eus-01, rg-c02-azl-eus-01, etc.
Variables from variables.yml
| Variable | Config Path | Example (IIC) |
|---|---|---|
| Identity — Entra Connect RG | azure_resources.platform_identity.rg_entraconnect | rg-identity-entraconnect-eus-01 |
| Identity — PIM RG | azure_resources.platform_identity.rg_pim | rg-identity-pim-eus-01 |
| Management — Monitoring RG | azure_resources.platform_management.rg_monitoring | rg-mgmt-monitoring-eus-01 |
| Management — Automation RG | azure_resources.platform_management.rg_automation | rg-mgmt-automation-eus-01 |
| Management — Backup RG | azure_resources.platform_management.rg_backup | rg-mgmt-backup-eus-01 |
| Connectivity — Hub RG | azure_resources.platform_connectivity.rg_hub | rg-connectivity-hub-eus-01 |
| Connectivity — DNS RG | azure_resources.platform_connectivity.rg_dns | rg-connectivity-dns-eus-01 |
| Connectivity — Bastion RG | azure_resources.platform_connectivity.rg_bastion | rg-connectivity-bastion-eus-01 |
| Cluster RG | azure_resources.resource_group_name | rg-c01-azl-eus-01 |
Execution Options
- Azure Portal
- Orchestrated Script
- Standalone Script
Azure Portal
When to use: Single deployment, prefer visual interface
Procedure
- Navigate to Resource Groups:
- In Azure Portal, search for Resource groups
- Click + Create
- Create Platform Identity RGs:
- Subscription: Select
iic-platform-identity-001 - Resource group: Enter name from the table above
- Region: Per config (
azure.regionorcluster.location) - Click Review + create → Create
- Repeat for each RG in the Platform Identity table
- Create Platform Management RGs:
- Subscription: Select
iic-platform-management-001 - Create each RG from the Platform Management table
- Create Platform Connectivity RGs:
- Subscription: Select
iic-platform-connectivity-001 - Create each RG from the Platform Connectivity table
- Create Landing Zone RGs:
- Subscription: Select each landing zone subscription (e.g.,
iic-lz-azurelocal-corp-001) - Create the cluster RG:
rg-c01-azl-eus-01 - Repeat for each landing zone subscription
Validation
- All resource groups created in the correct subscriptions
- Resource group names match
variables.yml - Resource groups are in the correct region
Links
Azure CLI / PowerShell
When to use: Scripted deployment reading values from
variables.yml
Script
Primary: scripts/deploy/02-azure-foundation/phase-01-landing-zones/full-deployment/task-03-create-resource-groups/powershell/Deploy-ResourceGroups.ps1
Alternatives:
| Variant | Path |
|---|---|
| PowerShell + Azure CLI | scripts/deploy/02-azure-foundation/phase-01-landing-zones/full-deployment/task-03-create-resource-groups/azure-cli/Deploy-ResourceGroups.azcli.ps1 |
| Bash + Azure CLI | scripts/deploy/02-azure-foundation/phase-01-landing-zones/full-deployment/task-03-create-resource-groups/bash/az-deploy-resource-groups.sh |
Code
# ============================================================================
# Script: Deploy-ResourceGroups.ps1
# Prerequisites: Az.Resources module, authenticated with Contributor on all subs
# ============================================================================
#Requires -Modules Az.Resources
# Load configuration
$config = Get-Content "./config/variables.yml" | ConvertFrom-Yaml
$location = $config.azure.region
# Build resource group list: each entry = subscription name + RG name
$ResourceGroups = @()
# Platform Identity
$subIdentity = $config.azure.subscriptions.platform_identity.name
foreach ($rg in $config.azure_resources.platform_identity.PSObject.Properties) {
$ResourceGroups += @{ Subscription = $subIdentity; Name = $rg.Value }
}
# Platform Management
$subManagement = $config.azure.subscriptions.platform_management.name
foreach ($rg in $config.azure_resources.platform_management.PSObject.Properties) {
$ResourceGroups += @{ Subscription = $subManagement; Name = $rg.Value }
}
# Platform Connectivity
$subConnectivity = $config.azure.subscriptions.platform_connectivity.name
foreach ($rg in $config.azure_resources.platform_connectivity.PSObject.Properties) {
$ResourceGroups += @{ Subscription = $subConnectivity; Name = $rg.Value }
}
# Landing Zone(s) — cluster RG per subscription
foreach ($lzKey in @('lz_corp', 'lz_online')) {
$subName = $config.azure.subscriptions.$lzKey.name
$rgName = $config.azure_resources.resource_group_name
$ResourceGroups += @{ Subscription = $subName; Name = $rgName }
}
Write-Host "Creating $($ResourceGroups.Count) resource groups ..." -ForegroundColor Cyan
foreach ($rg in $ResourceGroups) {
Set-AzContext -Subscription $rg.Subscription | Out-Null
New-AzResourceGroup -Name $rg.Name -Location $location -Force | Out-Null
Write-Host " Created: $($rg.Name) in $($rg.Subscription)" -ForegroundColor Gray
}
Write-Host "Resource groups created successfully" -ForegroundColor Green
Validation
foreach ($rg in $ResourceGroups) {
Set-AzContext -Subscription $rg.Subscription | Out-Null
$result = Get-AzResourceGroup -Name $rg.Name -ErrorAction SilentlyContinue
if ($result) {
Write-Host " OK: $($rg.Name) in $($rg.Subscription)" -ForegroundColor Green
} else {
Write-Host " MISSING: $($rg.Name) in $($rg.Subscription)" -ForegroundColor Red
}
}
Validation Script: scripts/validation/landing-zones/powershell/Test-ResourceGroups.ps1
Standalone Script
When to use: Copy-paste ready script — no config file, no helpers, no dependencies.
Code
# ============================================================================
# Script: New-ResourceGroups-Standalone.ps1
# Execution: Run anywhere — fully self-contained, no external dependencies
# Prerequisites: Az.Resources module, authenticated with Contributor on all subs
# ============================================================================
#Requires -Modules Az.Resources
#region CONFIGURATION
# ── Edit these values to match your environment ──────────────────────────────
$Location = "eastus"
# Each entry: subscription name → array of resource group names
$Plan = @(
@{
Subscription = "iic-platform-identity-001"
ResourceGroups = @(
"rg-identity-entraconnect-eus-01",
"rg-identity-pim-eus-01"
)
},
@{
Subscription = "iic-platform-management-001"
ResourceGroups = @(
"rg-mgmt-monitoring-eus-01",
"rg-mgmt-automation-eus-01",
"rg-mgmt-backup-eus-01"
)
},
@{
Subscription = "iic-platform-connectivity-001"
ResourceGroups = @(
"rg-connectivity-hub-eus-01",
"rg-connectivity-dns-eus-01",
"rg-connectivity-bastion-eus-01"
)
},
@{
Subscription = "iic-lz-azurelocal-corp-001"
ResourceGroups = @(
"rg-c01-azl-eus-01"
)
},
@{
Subscription = "iic-lz-azurelocal-online-001"
ResourceGroups = @(
"rg-c01-azl-eus-01"
)
}
)
#endregion CONFIGURATION
Write-Host "Creating resource groups ..." -ForegroundColor Cyan
foreach ($entry in $Plan) {
Set-AzContext -Subscription $entry.Subscription | Out-Null
foreach ($rgName in $entry.ResourceGroups) {
New-AzResourceGroup -Name $rgName -Location $Location -Force | Out-Null
Write-Host " Created: $rgName in $($entry.Subscription)" -ForegroundColor Gray
}
}
Write-Host "Resource groups created successfully" -ForegroundColor Green
# Verify
foreach ($entry in $Plan) {
Set-AzContext -Subscription $entry.Subscription | Out-Null
foreach ($rgName in $entry.ResourceGroups) {
$result = Get-AzResourceGroup -Name $rgName -ErrorAction SilentlyContinue
if ($result) {
Write-Host " OK: $rgName in $($entry.Subscription)" -ForegroundColor Green
} else {
Write-Host " MISSING: $rgName in $($entry.Subscription)" -ForegroundColor Red
}
}
}
This script is completely self-contained. All values are defined in the #region CONFIGURATION block above. Edit those values and run — no variables.yml, no config-loader, no helpers required.
Troubleshooting
| Symptom | Error | Resolution |
|---|---|---|
| Permission denied | AuthorizationFailed | Verify Contributor or Owner role on the target subscription |
| Duplicate name | ResourceGroupAlreadyExists | RG already exists — verify it's in the correct subscription and region, then move on |
| Invalid location | LocationNotAllowed | Check Azure Policy allowed-locations constraints on the subscription or management group |
| Wrong subscription context | RG created in wrong sub | Always run Set-AzContext -Subscription before New-AzResourceGroup |
Next Steps
After resource groups are deployed:
- Proceed to the next phase of the Azure Foundation deployment
- Apply tagging policies at the management group or subscription level
- Configure RBAC assignments on each resource group as needed
References
- Azure Local Toolkit — Governance Module
- Microsoft Learn — Manage Resource Groups
- Microsoft Learn — Resource Naming Conventions
- Microsoft Learn — Resource Tagging
Alternatives
The procedures in this task use the scripted methods shown in the tabs above. Additional deployment methods including Azure CLI and Bash scripts are available in the azurelocal-toolkit repository under scripts/deploy/.
| Method | Description |
|---|---|
| Azure CLI | PowerShell-based Azure CLI scripts for Azure resource operations |
| Bash | Linux/macOS compatible shell scripts for pipeline environments |
Navigation
| Previous | Up | Next |
|---|---|---|
| Task 02 — Create Subscriptions | Full Deployment Overview | Phase 02 — Resource Providers |
Version Control
- Created: 2026-01-15 by Hybrid Cloud Solutions
- Last Updated: 2026-03-19 by Hybrid Cloud Solutions
- Version: 3.0.0
Version Control
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0.0 | 2025-03-25 | Azure Local Cloud | Initial release |