Skip to content

Commit

Permalink
fix: for #3443 lz/sub-vending (#3491)
Browse files Browse the repository at this point in the history
## Description

This pull request introduces a new parameter
`managementGroupAssociationDelayCount` to the `sub-vending` module,
which adds a delay to the subscription being moved to the target
management group. This delay is intended to allow for background
platform RBAC inheritance to occur. The changes span multiple files,
including updates to `README.md`, `main.bicep`, `main.json`, and
`subResourceWrapper.bicep`.

Fixes #3443 

## Pipeline Reference

<!-- Insert your Pipeline Status Badge below -->

| Pipeline |
| -------- |
|
[![avm.ptn.lz.sub-vending](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.ptn.lz.sub-vending.yml/badge.svg?branch=main)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.ptn.lz.sub-vending.yml)|

## Type of Change

<!-- Use the checkboxes [x] on the options that are relevant. -->

- [ ] Update to CI Environment or utilities (Non-module affecting
changes)
- [x] Azure Verified Module updates:
- [x] Bugfix containing backwards-compatible bug fixes, and I have NOT
bumped the MAJOR or MINOR version in `version.json`:
- [x] Someone has opened a bug report issue, and I have included "Closes
#{bug_report_issue_number}" in the PR description.
- [ ] The bug was found by the module author, and no one has opened an
issue to report it yet.
- [ ] Feature update backwards compatible feature updates, and I have
bumped the MINOR version in `version.json`.
- [ ] Breaking changes and I have bumped the MAJOR version in
`version.json`.
  - [ ] Update to documentation

## Checklist

- [x] I'm sure there are no other open Pull Requests for the same
update/change
- [x] I have run `Set-AVMModule` locally to generate the supporting
module files.
- [x] My corresponding pipelines / checks run clean and green without
any errors or warnings

<!-- Please keep up to date with the contribution guide at
https://aka.ms/avm/contribute/bicep -->
  • Loading branch information
jtracey93 authored Oct 9, 2024
1 parent 41479d6 commit f1f12dc
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 76 deletions.
9 changes: 9 additions & 0 deletions avm/ptn/lz/sub-vending/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ param virtualNetworkResourceGroupName = '<virtualNetworkResourceGroupName>'
| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. |
| [`existingSubscriptionId`](#parameter-existingsubscriptionid) | string | 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 subscription ID should be provided in the example format `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`. |
| [`hubNetworkResourceId`](#parameter-hubnetworkresourceid) | string | The resource ID of the Virtual Network or Virtual WAN Hub in the hub to which the created Virtual Network, by this module, will be peered/connected to via Virtual Network Peering or a Virtual WAN Virtual Hub Connection.<p> |
| [`managementGroupAssociationDelayCount`](#parameter-managementgroupassociationdelaycount) | int | The number of blank ARM deployments to create sequentially to introduce a delay to the Subscription being moved to the target Management Group being, if set, to allow for background platform RBAC inheritance to occur. |
| [`resourceProviders`](#parameter-resourceproviders) | object | An object of resource providers and resource providers features to register. If left blank/empty, no resource providers will be registered.<p> |
| [`roleAssignmentEnabled`](#parameter-roleassignmentenabled) | bool | Whether to create role assignments or not. If true, supply the array of role assignment objects in the parameter called `roleAssignments`.<p> |
| [`roleAssignments`](#parameter-roleassignments) | array | Supply an array of objects containing the details of the role assignments to create.<p><p>Each object must contain the following `keys`:<li>`principalId` = The Object ID of the User, Group, SPN, Managed Identity to assign the RBAC role too.<li>`definition` = The Name of one of the pre-defined built-In RBAC Roles or a Resource ID of a Built-in or custom RBAC Role Definition as follows:<p> - You can only provide the RBAC role name of the pre-defined roles (Contributor, Owner, Reader, Role Based Access Control Administrator (Preview), and User Access Administrator). We only provide those roles as they are the most common ones to assign to a new subscription, also to reduce the template size and complexity in case we define each and every Built-in RBAC role.<p> - You can provide the Resource ID of a Built-in or custom RBAC Role Definition<p> - e.g. `/providers/Microsoft.Authorization/roleDefinitions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`<li>`relativeScope` = 2 options can be provided for input value:<p> 1. `''` *(empty string)* = Make RBAC Role Assignment to Subscription scope<p> 2. `'/resourceGroups/<RESOURCE GROUP NAME>'` = Make RBAC Role Assignment to specified Resource Group.<p> |
Expand Down Expand Up @@ -735,6 +736,14 @@ The resource ID of the Virtual Network or Virtual WAN Hub in the hub to which th
- Type: string
- Default: `''`

### Parameter: `managementGroupAssociationDelayCount`

The number of blank ARM deployments to create sequentially to introduce a delay to the Subscription being moved to the target Management Group being, if set, to allow for background platform RBAC inheritance to occur.

- Required: No
- Type: int
- Default: `15`

### Parameter: `resourceProviders`

An object of resource providers and resource providers features to register. If left blank/empty, no resource providers will be registered.<p>
Expand Down
4 changes: 4 additions & 0 deletions avm/ptn/lz/sub-vending/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ param resourceProviders object = {
'Microsoft.Web': []
}

@sys.description('Optional. The number of blank ARM deployments to create sequentially to introduce a delay to the Subscription being moved to the target Management Group being, if set, to allow for background platform RBAC inheritance to occur.')
param managementGroupAssociationDelayCount int = 15

// VARIABLES

var existingSubscriptionIDEmptyCheck = empty(existingSubscriptionId)
Expand Down Expand Up @@ -355,6 +358,7 @@ module createSubscriptionResources './modules/subResourceWrapper.bicep' = if (su
subscriptionId: (subscriptionAliasEnabled && empty(existingSubscriptionId))
? createSubscription.outputs.subscriptionId
: existingSubscriptionId
managementGroupAssociationDelayCount: managementGroupAssociationDelayCount
subscriptionManagementGroupAssociationEnabled: subscriptionManagementGroupAssociationEnabled
subscriptionManagementGroupId: subscriptionManagementGroupId
subscriptionTags: subscriptionTags
Expand Down
50 changes: 46 additions & 4 deletions avm/ptn/lz/sub-vending/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"_generator": {
"name": "bicep",
"version": "0.30.23.60470",
"templateHash": "2343164809013150587"
"templateHash": "2644636658214532574"
},
"name": "Sub-vending",
"description": "This module deploys a subscription to accelerate deployment of landing zones. For more information on how to use it, please visit this [Wiki](https://github.com/Azure/bicep-lz-vending/wiki).",
Expand Down Expand Up @@ -377,6 +377,13 @@
"metadata": {
"description": "Optional. An object of resource providers and resource providers features to register. If left blank/empty, no resource providers will be registered.\n"
}
},
"managementGroupAssociationDelayCount": {
"type": "int",
"defaultValue": 15,
"metadata": {
"description": "Optional. The number of blank ARM deployments to create sequentially to introduce a delay to the Subscription being moved to the target Management Group being, if set, to allow for background platform RBAC inheritance to occur."
}
}
},
"variables": {
Expand Down Expand Up @@ -546,6 +553,9 @@
"mode": "Incremental",
"parameters": {
"subscriptionId": "[if(and(parameters('subscriptionAliasEnabled'), empty(parameters('existingSubscriptionId'))), createObject('value', reference(extensionResourceId(managementGroup().id, 'Microsoft.Resources/deployments', variables('deploymentNames').createSubscription), '2022-09-01').outputs.subscriptionId.value), createObject('value', parameters('existingSubscriptionId')))]",
"managementGroupAssociationDelayCount": {
"value": "[parameters('managementGroupAssociationDelayCount')]"
},
"subscriptionManagementGroupAssociationEnabled": {
"value": "[parameters('subscriptionManagementGroupAssociationEnabled')]"
},
Expand Down Expand Up @@ -653,7 +663,7 @@
"_generator": {
"name": "bicep",
"version": "0.30.23.60470",
"templateHash": "12288692280280036332"
"templateHash": "2549730186599602050"
},
"name": "`/subResourcesWrapper/deploy.bicep` Parameters",
"description": "This module is used by the [`bicep-lz-vending`](https://aka.ms/sub-vending/bicep) module to help orchestrate the deployment",
Expand Down Expand Up @@ -960,11 +970,19 @@
"metadata": {
"description": "The name of the storage account for the deployment script."
}
},
"managementGroupAssociationDelayCount": {
"type": "int",
"defaultValue": 15,
"metadata": {
"description": "Optional. The number of blank ARM deployments to create sequentially to introduce a delay to the Subscription being moved to the target Management Group being, if set, to allow for background platform RBAC inheritance to occur."
}
}
},
"variables": {
"$fxv#0": "Param(\n[string]$subscriptionId,\n[string]$resourceProviders\n)\n\n$ErrorActionPreference = 'SilentlyContinue'\n# Selecting the right subscription\nSelect-AzSubscription -SubscriptionId $subscriptionId\n\n# Defining variables\n$providers = $resourceProviders | ConvertFrom-Json -AsHashtable\n$failedProviders = ''\n$failedFeatures = ''\n$DeploymentScriptOutputs = @{}\n\n##############################################\n## Registering resource providers and features\n##############################################\n\nif ($providers.Count -gt 0) {\n foreach ($provider in $providers.keys) {\n try {\n # Registering resource providers\n $providerStatus = (Get-AzResourceProvider -ListAvailable | Where-Object ProviderNamespace -EQ $provider).registrationState\n # Check if the providered is registered\n if ($providerStatus -eq 'NotRegistered') {\n Write-Output \"`n Registering the '$provider' provider\"\n if (Register-AzResourceProvider -ProviderNamespace $provider) {\n Write-Output \"`n The registration for provider'$provider' has started successfully\"\n } else {\n Write-Output \"`n The '$provider' provider has not been registered successfully\"\n $failedProviders += \",$provider\"\n }\n } elseif ($providerStatus -eq 'Registering') {\n Write-Output \"`n The '$provider' provider is in registering state\"\n $failedProviders += \",$provider\"\n } elseif ( $null -eq $providerStatus) {\n Write-Output \"`n There was a problem registering the '$provider' provider. Please make sure this provider namespace is valid\"\n $failedProviders += \",$provider\"\n }\n\n if ($failedProviders.length -gt 0) {\n $output = $failedProviders.substring(1)\n } else {\n $output = 'No failures'\n }\n $DeploymentScriptOutputs['failedProvidersRegistrations'] = $output\n } catch {\n Write-Output \"`n There was a problem registering the '$provider' provider. Please make sure this provider namespace is valid\"\n $failedProviders += \",$provider\"\n if ($failedProviders.length -gt 0) {\n $output = $failedProviders.substring(1)\n }\n $DeploymentScriptOutputs['failedProvidersRegistrations'] = $output\n }\n # Registering resource providers features\n $features = $providers[$provider]\n if ($features.length -gt 0) {\n foreach ($feature in $features) {\n try {\n # Define variables\n $featureStatus = (Get-AzProviderFeature -ListAvailable | Where-Object FeatureName -EQ $feature).RegistrationState\n # Check if the feature is registered\n if ($featureStatus -eq 'NotRegistered' -or $featureStatus -eq 'Unregistered') {\n Write-Output \"`n Registering the '$feature' feature\"\n if (Register-AzProviderFeature -FeatureName $feature -ProviderNamespace $provider) {\n Write-Output \"`n The The registration for feature '$feature' has started successfully\"\n } else {\n Write-Output \"`n The '$feature' feature has not been registered successfully\"\n $failedFeatures += \",$feature\"\n }\n } elseif ($null -eq $featureStatus) {\n Write-Output \"`n The '$feature' feature doesn't exist.\"\n $failedFeatures += \",$feature\"\n }\n if ($failedFeatures.length -gt 0) {\n $output = $failedFeatures.substring(1)\n } else {\n $output = 'No failures'\n }\n $DeploymentScriptOutputs['failedFeaturesRegistrations'] = $output\n } catch {\n Write-Output \"`n There was a problem registering the '$feature' feature. Please make sure this feature name is valid\"\n $failedFeatures += \",$feature\"\n if ($failedFeatures.length -gt 0) {\n $output = $failedFeatures.substring(1)\n }\n $DeploymentScriptOutputs['failedFeaturesRegistrations'] = $output\n }\n }\n } else {\n $output = 'No failures'\n $DeploymentScriptOutputs['failedFeaturesRegistrations'] = $output\n }\n }\n} else {\n Write-Output \"`n No providers or features to register\"\n}\n",
"$fxv#0": "Param(\n [string]$subscriptionId,\n [string]$resourceProviders\n)\n\n$ErrorActionPreference = 'SilentlyContinue'\n# Selecting the right subscription\nSelect-AzSubscription -SubscriptionId $subscriptionId\n\n# Defining variables\n$providers = $resourceProviders | ConvertFrom-Json -AsHashtable\n$failedProviders = ''\n$failedFeatures = ''\n$DeploymentScriptOutputs = @{}\n\n##############################################\n## Registering resource providers and features\n##############################################\n\nif ($providers.Count -gt 0) {\n foreach ($provider in $providers.keys) {\n try {\n # Registering resource providers\n $providerStatus = (Get-AzResourceProvider -ListAvailable | Where-Object ProviderNamespace -EQ $provider).registrationState\n # Check if the providered is registered\n if ($providerStatus -eq 'NotRegistered') {\n Write-Output \"`n Registering the '$provider' provider\"\n if (Register-AzResourceProvider -ProviderNamespace $provider) {\n Write-Output \"`n The registration for provider'$provider' has started successfully\"\n } else {\n Write-Output \"`n The '$provider' provider has not been registered successfully\"\n $failedProviders += \",$provider\"\n }\n } elseif ($providerStatus -eq 'Registering') {\n Write-Output \"`n The '$provider' provider is in registering state\"\n $failedProviders += \",$provider\"\n } elseif ( $null -eq $providerStatus) {\n Write-Output \"`n There was a problem registering the '$provider' provider. Please make sure this provider namespace is valid\"\n $failedProviders += \",$provider\"\n }\n\n if ($failedProviders.length -gt 0) {\n $output = $failedProviders.substring(1)\n } else {\n $output = 'No failures'\n }\n $DeploymentScriptOutputs['failedProvidersRegistrations'] = $output\n } catch {\n Write-Output \"`n There was a problem registering the '$provider' provider. Please make sure this provider namespace is valid\"\n $failedProviders += \",$provider\"\n if ($failedProviders.length -gt 0) {\n $output = $failedProviders.substring(1)\n }\n $DeploymentScriptOutputs['failedProvidersRegistrations'] = $output\n }\n # Registering resource providers features\n $features = $providers[$provider]\n if ($features.length -gt 0) {\n foreach ($feature in $features) {\n try {\n # Define variables\n $featureStatus = (Get-AzProviderFeature -ListAvailable | Where-Object FeatureName -EQ $feature).RegistrationState\n # Check if the feature is registered\n if ($featureStatus -eq 'NotRegistered' -or $featureStatus -eq 'Unregistered') {\n Write-Output \"`n Registering the '$feature' feature\"\n if (Register-AzProviderFeature -FeatureName $feature -ProviderNamespace $provider) {\n Write-Output \"`n The The registration for feature '$feature' has started successfully\"\n } else {\n Write-Output \"`n The '$feature' feature has not been registered successfully\"\n $failedFeatures += \",$feature\"\n }\n } elseif ($null -eq $featureStatus) {\n Write-Output \"`n The '$feature' feature doesn't exist.\"\n $failedFeatures += \",$feature\"\n }\n if ($failedFeatures.length -gt 0) {\n $output = $failedFeatures.substring(1)\n } else {\n $output = 'No failures'\n }\n $DeploymentScriptOutputs['failedFeaturesRegistrations'] = $output\n } catch {\n Write-Output \"`n There was a problem registering the '$feature' feature. Please make sure this feature name is valid\"\n $failedFeatures += \",$feature\"\n if ($failedFeatures.length -gt 0) {\n $output = $failedFeatures.substring(1)\n }\n $DeploymentScriptOutputs['failedFeaturesRegistrations'] = $output\n }\n }\n } else {\n $output = 'No failures'\n $DeploymentScriptOutputs['failedFeaturesRegistrations'] = $output\n }\n }\n} else {\n Write-Output \"`n No providers or features to register\"\n}\n",
"deploymentNames": {
"moveSubscriptionToManagementGroupDelay": "[take(format('lz-vend-move-sub-delay-{0}', uniqueString(parameters('subscriptionId'), parameters('subscriptionManagementGroupId'), deployment().name)), 64)]",
"moveSubscriptionToManagementGroup": "[take(format('lz-vend-move-sub-{0}', uniqueString(parameters('subscriptionId'), parameters('subscriptionManagementGroupId'), deployment().name)), 64)]",
"tagSubscription": "[take(format('lz-vend-tag-sub-{0}', uniqueString(parameters('subscriptionId'), deployment().name)), 64)]",
"createResourceGroupForLzNetworking": "[take(format('lz-vend-rsg-create-{0}', uniqueString(parameters('subscriptionId'), parameters('virtualNetworkResourceGroupName'), parameters('virtualNetworkLocation'), deployment().name)), 64)]",
Expand Down Expand Up @@ -1002,6 +1020,27 @@
"resourceProvidersFormatted": "[replace(string(parameters('resourceProviders')), '\"', '\\\"')]"
},
"resources": [
{
"copy": {
"name": "moveSubscriptionToManagementGroupDelay",
"count": "[length(range(0, parameters('managementGroupAssociationDelayCount')))]",
"mode": "serial",
"batchSize": 1
},
"condition": "[and(parameters('subscriptionManagementGroupAssociationEnabled'), not(empty(parameters('subscriptionManagementGroupId'))))]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2024-03-01",
"name": "[format('{0}-{1}', variables('deploymentNames').moveSubscriptionToManagementGroupDelay, copyIndex())]",
"location": "[parameters('virtualNetworkLocation')]",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": []
}
}
},
{
"condition": "[and(parameters('subscriptionManagementGroupAssociationEnabled'), not(empty(parameters('subscriptionManagementGroupId'))))]",
"type": "Microsoft.Resources/deployments",
Expand Down Expand Up @@ -1055,7 +1094,10 @@
}
]
}
}
},
"dependsOn": [
"moveSubscriptionToManagementGroupDelay"
]
},
{
"condition": "[not(empty(parameters('subscriptionTags')))]",
Expand Down
Loading

0 comments on commit f1f12dc

Please sign in to comment.