Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ parameters:
- name: removeDeployment
displayName: Remove deployed module
type: boolean
default: false # Deployment does not support tags
default: true
- name: versioningOption
displayName: The mode to handle the version increments [major|minor|patch]
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ jobs:
DeploymentName = '$(deploymentName)'
TemplateFilePath = $templateFilePath
ResourceGroupName = '${{ parameters.resourceGroupName }}'
ManagementGroupId = '${{ parameters.managementGroupId }}'
Verbose = $true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ runs:
DeploymentName = '${{ steps.deploy_step.outputs.deploymentName }}'
TemplateFilePath = Join-Path $env:GITHUB_WORKSPACE '${{ inputs.templateFilePath }}'
ResourceGroupName = '${{ inputs.resourceGroupName }}'
ManagementGroupId = '${{ inputs.managementGroupId }}'
Verbose = $true
}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ms.management.managementgroups.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
type: boolean
description: 'Remove deployed module'
required: false
default: 'false' # Deployment does not support tags
default: 'true'
versioningOption:
type: choice
description: 'The mode to handle the version increments [major|minor|patch]'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Mandatory. The path to the template used for the deployment. Used to determine t
.PARAMETER ResourceGroupName
Optional. The name of the resource group the deployment was happening in. Relevant for resource-group level deployments.

.PARAMETER ManagementGroupId
Optional. The ID of the management group to fetch deployments from. Relevant for management-group level deployments.

.EXAMPLE
Initialize-DeploymentRemoval -DeploymentName 'virtualWans-20211204T1812029146Z' -TemplateFilePath "$home/ResourceModules/arm/Microsoft.Network/virtualWans/deploy.bicep" -resourceGroupName 'test-virtualWan-parameters.json-rg'

Expand All @@ -31,7 +34,10 @@ function Initialize-DeploymentRemoval {
[string] $TemplateFilePath,

[Parameter(Mandatory = $false)]
[string] $ResourceGroupName = 'validation-rg'
[string] $ResourceGroupName,

[Parameter(Mandatory = $false)]
[string] $ManagementGroupId
)

begin {
Expand Down Expand Up @@ -84,10 +90,15 @@ function Initialize-DeploymentRemoval {

# Invoke removal
$inputObject = @{
DeploymentName = $deploymentName
ResourceGroupName = $resourceGroupName
TemplateFilePath = $templateFilePath
RemovalSequence = $removalSequence
DeploymentName = $deploymentName
TemplateFilePath = $templateFilePath
RemovalSequence = $removalSequence
}
if (-not [String]::IsNullOrEmpty($resourceGroupName)) {
$inputObject['resourceGroupName'] = $resourceGroupName
}
if (-not [String]::IsNullOrEmpty($ManagementGroupId)) {
$inputObject['ManagementGroupId'] = $ManagementGroupId
}
Remove-Deployment @inputObject -Verbose
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ Mandatory. The deployment name to search for
.PARAMETER ResourceGroupName
Optional. The name of the resource group for scope 'resourcegroup'

.PARAMETER ManagementGroupId
Optional. The ID of the management group to fetch deployments from. Relevant for management-group level deployments.

.PARAMETER Scope
Mandatory. The scope to search in

Expand All @@ -20,6 +23,11 @@ Get-DeploymentTargetResourceListInner -Name 'keyvault-12356' -Scope 'resourcegro

Get all deployments that match name 'keyvault-12356' in scope 'resourcegroup'

.EXAMPLE
Get-ResourceIdsOfDeploymentInner -Name 'mgmtGroup-12356' -Scope 'managementGroup' -ManagementGroupId 'af760cf5-3c9e-4804-a59a-a51741daa350'

Get all deployments that match name 'mgmtGroup-12356' in scope 'managementGroup'

.NOTES
Works after the principal:
- Find all deployments for the given deployment name
Expand All @@ -36,6 +44,9 @@ function Get-DeploymentTargetResourceListInner {
[Parameter(Mandatory = $false)]
[string] $ResourceGroupName,

[Parameter(Mandatory = $false)]
[string] $ManagementGroupId,

[Parameter(Mandatory)]
[ValidateSet(
'resourcegroup',
Expand Down Expand Up @@ -65,6 +76,7 @@ function Get-DeploymentTargetResourceListInner {
# In case we already have any such resources in the list, we should remove them
[array]$resultSet = $resultSet | Where-Object { $_ -notmatch "/resourceGroups/$resourceGroupName/" }
}
break
}
'subscription' {
[array]$deploymentTargets = (Get-AzDeploymentOperation -DeploymentName $name).TargetResource | Where-Object { $_ -ne $null }
Expand All @@ -84,23 +96,25 @@ function Get-DeploymentTargetResourceListInner {
[array]$resultSet += Get-DeploymentTargetResourceListInner -name (Split-Path $deployment -Leaf) -Scope 'subscription'
}
}
break
}
'managementgroup' {
[array]$deploymentTargets = (Get-AzManagementGroupDeploymentOperation -DeploymentName $name).TargetResource | Where-Object { $_ -ne $null }
[array]$deploymentTargets = (Get-AzManagementGroupDeploymentOperation -DeploymentName $name -ManagementGroupId $ManagementGroupId).TargetResource | Where-Object { $_ -ne $null }
foreach ($deployment in ($deploymentTargets | Where-Object { $_ -notmatch '/deployments/' } )) {
Write-Verbose ('Found deployed resource [{0}]' -f $deployment) -Verbose
[array]$resultSet += $deployment
}
foreach ($deployment in ($deploymentTargets | Where-Object { $_ -match '/deployments/' } )) {
[array]$resultSet = $resultSet | Where-Object { $_ -ne $deployment }
if ($deployment -match '/managementGroup/') {
if ($deployment -match '/subscriptions/') {
# Subscription Level Child Deployments
[array]$resultSet += Get-DeploymentTargetResourceListInner -Name (Split-Path $deployment -Leaf) -Scope 'subscription'
} else {
# Management Group Level Deployments
[array]$resultSet += Get-DeploymentTargetResourceListInner -name (Split-Path $deployment -Leaf) -scope 'managementgroup'
[array]$resultSet += Get-DeploymentTargetResourceListInner -name (Split-Path $deployment -Leaf) -scope 'managementgroup' -ManagementGroupId $ManagementGroupId
}
}
break
}
'tenant' {
[array]$deploymentTargets = (Get-AzTenantDeploymentOperation -DeploymentName $name).TargetResource | Where-Object { $_ -ne $null }
Expand All @@ -110,14 +124,15 @@ function Get-DeploymentTargetResourceListInner {
}
foreach ($deployment in ($deploymentTargets | Where-Object { $_ -match '/deployments/' } )) {
[array]$resultSet = $resultSet | Where-Object { $_ -ne $deployment }
if ($deployment -match '/tenant/') {
if ($deployment -match '/managementgroups/') {
# Management Group Level Child Deployments
[array]$resultSet += Get-DeploymentTargetResourceListInner -Name (Split-Path $deployment -Leaf) -scope 'managementgroup'
[array]$resultSet += Get-DeploymentTargetResourceListInner -Name (Split-Path $deployment -Leaf) -scope 'managementgroup' -ManagementGroupId $ManagementGroupId
} else {
# Tenant Level Deployments
[array]$resultSet += Get-DeploymentTargetResourceListInner -name (Split-Path $deployment -Leaf)
}
}
break
}
}
return $resultSet
Expand All @@ -132,7 +147,10 @@ Get all deployments that match a given deployment name in a given scope using a
Get all deployments that match a given deployment name in a given scope using a retry mechanic.

.PARAMETER ResourceGroupName
Mandatory. The resource group of the resource to remove
Optional. The name of the resource group for scope 'resourcegroup'

.PARAMETER ManagementGroupId
Optional. The ID of the management group to fetch deployments from. Relevant for management-group level deployments.

.PARAMETER Name
Optional. The deployment name to use for the removal
Expand All @@ -150,6 +168,12 @@ Optional. The time to wait in between the search for resources via their remove
Get-DeploymentTargetResourceList -name 'KeyVault' -ResourceGroupName 'validation-rg' -scope 'resourcegroup'

Get all deployments that match name 'KeyVault' in scope 'resourcegroup' of resource group 'validation-rg'

.EXAMPLE
Get-ResourceIdsOfDeployment -Name 'mgmtGroup-12356' -Scope 'managementGroup' -ManagementGroupId 'af760cf5-3c9e-4804-a59a-a51741daa350'

Get all deployments that match name 'mgmtGroup-12356' in scope 'managementGroup'

#>
function Get-DeploymentTargetResourceList {

Expand All @@ -158,6 +182,9 @@ function Get-DeploymentTargetResourceList {
[Parameter(Mandatory = $false)]
[string] $ResourceGroupName,

[Parameter(Mandatory = $false)]
[string] $ManagementGroupId,

[Parameter(Mandatory = $true)]
[string] $Name,

Expand All @@ -179,7 +206,18 @@ function Get-DeploymentTargetResourceList {

$searchRetryCount = 1
do {
[array]$targetResources = Get-DeploymentTargetResourceListInner -Name $name -Scope $scope -ResourceGroupName $resourceGroupName -ErrorAction 'SilentlyContinue'
$innerInputObject = @{
Name = $name
Scope = $scope
ErrorAction = 'SilentlyContinue'
}
if (-not [String]::IsNullOrEmpty($resourceGroupName)) {
$innerInputObject['resourceGroupName'] = $resourceGroupName
}
if (-not [String]::IsNullOrEmpty($ManagementGroupId)) {
$innerInputObject['ManagementGroupId'] = $ManagementGroupId
}
[array]$targetResources = Get-DeploymentTargetResourceListInner @innerInputObject
if ($targetResources) {
break
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,18 @@ function Get-ResourceIdsAsFormattedObjectList {

switch ($idElements.Count) {
{ $PSItem -eq 5 } {
# subscription level resource group
$formattedResources += @{
resourceId = $resourceId
type = 'Microsoft.Resources/resourceGroups'
if ($idElements[3] -eq 'managementGroups') {
# management-group level management group (e.g. '/providers/Microsoft.Management/managementGroups/testMG')
$formattedResources += @{
resourceId = $resourceId
type = $idElements[2, 3] -join '/'
}
} else {
# subscription level resource group (e.g. '/subscriptions/<subId>/resourceGroups/myRG')
$formattedResources += @{
resourceId = $resourceId
type = 'Microsoft.Resources/resourceGroups'
}
}
break
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ Requires the resource in question to be tagged with 'removeModule = <moduleName>
Mandatory. The name of the module to remove

.PARAMETER ResourceGroupName
Mandatory. The resource group of the resource to remove
Optional. The resource group of the resource to remove

.PARAMETER ManagementGroupId
Optional. The ID of the management group to fetch deployments from. Relevant for management-group level deployments.

.PARAMETER SearchRetryLimit
Optional. The maximum times to retry the search for resources via their removal tag
Expand Down Expand Up @@ -39,6 +42,9 @@ function Remove-Deployment {
[Parameter(Mandatory = $false)]
[string] $ResourceGroupName,

[Parameter(Mandatory = $false)]
[string] $ManagementGroupId,

[Parameter(Mandatory = $true)]
[string] $DeploymentName,

Expand Down Expand Up @@ -81,9 +87,14 @@ function Remove-Deployment {
# Fetch deployments
# =================
$deploymentsInputObject = @{
Name = $deploymentName
Scope = $deploymentScope
ResourceGroupName = $resourceGroupName
Name = $deploymentName
Scope = $deploymentScope
}
if (-not [String]::IsNullOrEmpty($resourceGroupName)) {
$deploymentsInputObject['resourceGroupName'] = $resourceGroupName
}
if (-not [String]::IsNullOrEmpty($ManagementGroupId)) {
$deploymentsInputObject['ManagementGroupId'] = $ManagementGroupId
}
[array] $deployedTargetResources = Get-DeploymentTargetResourceList @deploymentsInputObject -Verbose
Write-Verbose ('Total number of deployment target resources after fetching deployments [{0}]' -f $deployedTargetResources.Count) -Verbose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ function Test-TemplateWithParameterFile {
}
}
if ($ValidationErrors) {
Write-Warning ($res.Details | ConvertTo-Json -Depth 10 | Out-String)
if ($res.Details) { Write-Warning ($res.Details | ConvertTo-Json -Depth 10 | Out-String) }
if ($res.Message) { Write-Warning $res.Message }
Write-Error 'Template is not valid.'
} else {
Write-Verbose 'Template is valid' -Verbose
Expand Down