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
- Azure CLI / PowerShell
- 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
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