-
Notifications
You must be signed in to change notification settings - Fork 437
[Utilities] Added ManagementGroup-Deployment removal script #1622
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
3e07b3c
Added function for later use
AlexanderSehr 9c7d8de
Minor refactoring
AlexanderSehr 6fe594e
Updated conditions
AlexanderSehr e8071ab
Update to latest
AlexanderSehr 309ba04
Update utilities/tools/Clear-ManagementGroupDeployment.ps1
AlexanderSehr e70497e
Added docs
AlexanderSehr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
docs/wiki/The CI environment - Management Group Deployment removal utility.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| Use this script to remove Management-Group-Level Azure deployments on scale. This may be necessary in cases where you run many (test) deployments in this scope as Azure currently only auto-removes deployments from an [Resource-Group & Subscription](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-history-deletions?tabs=azure-powershell) scope. The resulting error message may look similar to `Creating the deployment '<deploymentName>' would exceed the quota of '800'. The current deployment count is '804'. Please delete some deployments before creating a new one, or see https://aka.ms/800LimitFix for information on managing deployment limits.` | ||
|
|
||
| --- | ||
|
|
||
| ### _Navigation_ | ||
|
|
||
| - [Location](#location) | ||
| - [How it works](#how-it-works) | ||
| - [How to use it](#how-to-use-it) | ||
|
|
||
| --- | ||
| # Location | ||
|
|
||
| You can find the script under [`/utilities/tools/Clear-ManagementGroupDeployment`](https://github.com/Azure/ResourceModules/blob/main/utilities/tools/Clear-ManagementGroupDeployment.ps1) | ||
|
|
||
| # How it works | ||
|
|
||
| 1. The script fetches all current deployments from Azure. | ||
| 1. By default it then filters them down to non-running & non-failing deployments (can be modified). | ||
| 1. Lastly, it removes all matching deployments in chunks of 100 deployments each. | ||
|
|
||
| # How to use it | ||
|
|
||
| For details on how to use the function, please refer to the script's local documentation. | ||
|
|
||
| > **Note:** The script must be loaded ('*dot-sourced*') before the function can be invoked. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| | ||
| <# | ||
| .SYNOPSIS | ||
| Bulk delete all deployments on the given management group scope | ||
|
|
||
| .DESCRIPTION | ||
| Bulk delete all deployments on the given management group scope | ||
|
|
||
| .PARAMETER ManagementGroupId | ||
| Mandatory. The Resource ID of the Management Group to remove the deployments for. | ||
|
|
||
| .PARAMETER DeploymentStatusToExclude | ||
| Optional. The status to exlude from removals. Can be multiple. By default, we exclude any deployment that is in state 'running' or 'failed'. | ||
|
|
||
| .EXAMPLE | ||
eriqua marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Clear-ManagementGroupDeployment -ManagementGroupId 'MyManagementGroupId' | ||
|
|
||
| Bulk remove all 'non-running' & 'non-failed' deployments from the Management Group with ID 'MyManagementGroupId' | ||
|
|
||
| .EXAMPLE | ||
| Clear-ManagementGroupDeployment -ManagementGroupId 'MyManagementGroupId' -DeploymentStatusToExclude @('running') | ||
|
|
||
| Bulk remove all 'non-running' deployments from the Management Group with ID 'MyManagementGroupId' | ||
| #> | ||
| function Clear-ManagementGroupDeployment { | ||
|
|
||
|
|
||
| [CmdletBinding(SupportsShouldProcess)] | ||
| param ( | ||
| [Parameter(Mandatory = $true)] | ||
| [string] $ManagementGroupId, | ||
|
|
||
| [Parameter(Mandatory = $false)] | ||
| [string[]] $DeploymentStatusToExclude = @('running', 'failed') | ||
| ) | ||
eriqua marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Load used functions | ||
| . (Join-Path $PSScriptRoot 'helper' 'Split-Array.ps1') | ||
|
|
||
| $getInputObject = @{ | ||
| Method = 'GET' | ||
| Uri = "https://management.azure.com/providers/Microsoft.Management/managementGroups/$ManagementGroupId/providers/Microsoft.Resources/deployments/?api-version=2021-04-01" | ||
| Headers = @{ | ||
| Authorization = 'Bearer {0}' -f (Get-AzAccessToken).Token | ||
| } | ||
| } | ||
| $response = Invoke-RestMethod @getInputObject | ||
eriqua marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (($response | Get-Member -MemberType 'NoteProperty').Name -notcontains 'value') { | ||
| throw ('Fetching deployments failed with error [{0}]' -f ($reponse | Out-String)) | ||
| } | ||
|
|
||
| $relevantDeployments = $response.value | Where-Object { $_.properties.provisioningState -notin $DeploymentStatusToExclude } | ||
|
|
||
| if (-not $relevantDeployments) { | ||
| Write-Verbose 'No deployments found' -Verbose | ||
| return | ||
| } | ||
|
|
||
| $relevantDeploymentChunks = , (Split-Array -InputArray $relevantDeployments -SplitSize 100) | ||
|
|
||
| Write-Verbose ('Triggering the removal of [{0}] deployments of management group [{1}]' -f $relevantDeployments.Count, $ManagementGroupId) | ||
|
|
||
| $failedRemovals = 0 | ||
| $successfulRemovals = 0 | ||
| foreach ($deployments in $relevantDeploymentChunks) { | ||
|
|
||
| $requests = $deployments | ForEach-Object { | ||
| @{ httpMethod = 'DELETE' | ||
| name = (New-Guid).Guid | ||
| requestHeaderDetails = @{ | ||
| commandName = 'HubsExtension.Microsoft.Resources/deployments.BulkDelete.execute' | ||
| } | ||
| url = '/providers/Microsoft.Management/managementGroups/{0}/providers/Microsoft.Resources/deployments/{1}?api-version=2019-08-01' -f $ManagementGroupId, $_.name | ||
| } | ||
| } | ||
|
|
||
| $removeInputObject = @{ | ||
| Method = 'POST' | ||
| Uri = 'https://management.azure.com/batch?api-version=2020-06-01' | ||
| Headers = @{ | ||
| Authorization = 'Bearer {0}' -f (Get-AzAccessToken).Token | ||
| 'Content-Type' = 'application/json' | ||
| } | ||
| Body = @{ | ||
| requests = $requests | ||
| } | ConvertTo-Json -Depth 4 | ||
| } | ||
| if ($PSCmdlet.ShouldProcess(('Removal of [{0}] deployments' -f $requests.Count), 'Request')) { | ||
| $response = Invoke-RestMethod @removeInputObject | ||
|
|
||
| $failedRemovals += ($response.responses | Where-Object { $_.httpStatusCode -notlike '20*' } ).Count | ||
| $successfulRemovals += ($response.responses | Where-Object { $_.httpStatusCode -like '20*' } ).Count | ||
| } | ||
| } | ||
|
|
||
| Write-Verbose 'Outcome' -Verbose | ||
eriqua marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Write-Verbose '=======' -Verbose | ||
| Write-Verbose "Successful removals:`t`t$successfulRemovals" -Verbose | ||
| Write-Verbose "Un-successful removals:`t$failedRemovals" -Verbose | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| <# | ||
| .SYNOPSIS | ||
| Split a given array evenly into chunks of n-items | ||
|
|
||
| .DESCRIPTION | ||
| Split a given array evenly into chunks of n-item | ||
|
|
||
| .PARAMETER InputArray | ||
| Mandatory. The array to split | ||
|
|
||
| .PARAMETER SplitSize | ||
| Mandatory. The chunk size to split into. | ||
|
|
||
| .EXAMPLE | ||
| Split-Array -InputArray @('1','2,'3','4','5') -SplitSize 3 | ||
|
|
||
| Split the given array @('1','2,'3','4','5') into chunks of size '3'. Will return the multi-demensional array @(@('1','2,'3'),@('4','5')) | ||
| #> | ||
| function Split-Array { | ||
|
|
||
| [CmdletBinding()] | ||
| param( | ||
| [Parameter(Mandatory = $true)] | ||
| [object[]] $InputArray, | ||
|
|
||
| [Parameter(Mandatory = $true)] | ||
| [int] $SplitSize | ||
| ) | ||
| begin { | ||
| Write-Debug ('{0} entered' -f $MyInvocation.MyCommand) | ||
| } | ||
| process { | ||
|
|
||
| if ($splitSize -ge $InputArray.Count) { | ||
| return $InputArray | ||
| } else { | ||
| $res = @() | ||
| for ($Index = 0; $Index -lt $InputArray.Count; $Index += $SplitSize) { | ||
| $res += , ( $InputArray[$index..($index + $splitSize - 1)] ) | ||
| } | ||
| return $res | ||
| } | ||
| } | ||
| end { | ||
| Write-Debug ('{0} existed' -f $MyInvocation.MyCommand) | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.