VSTS - 在发布期间删除以前的部署

VSTS - Deleting previous deployments during a release

我正在为一个 Azure 项目工作,在该项目中只能使用来自 Visual Studio CI 的 ARM 模板进行部署,并且我们只有对 Azure 门户的读取权限。

目前我遇到以下错误,无法发布。我也无法从 Portal 中删除部署,因为我只有配置构建和发布阶段的权限,我想知道是否可以创建任何阶段来删除以前的部署。

到目前为止,我尝试了一些方法,例如使用内联 PowerShell 命令 Remove-AzureRmResourceGroupDeployment,删除类型为 Microsoft.Resouces/deployments[= 的资源组19=] 在资源部署阶段之前,但没有一个有效。

[error]Creating the deployment 'azuredeploy-2017721-715' would exceed the quota of '800'. The current deployment count is '800', please delete some deployments before creating a new one. Please see https://aka.ms/arm-deploy for usage details.

使用 Azure PowerShell 任务。它负责为您进行身份验证——无需调用 Login-AzureRmAccount

这是一个允许您以并行方式删除此类部署的脚本。您还可以将其用于 Azure DevOps 中的 Azure PowerShell 任务。如果您对身份验证有疑问,请查看此处:

Param(
    [string] 
    [Parameter(Mandatory = $true)]
    $subscriptionId,

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

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

    [int] 
    [Parameter(Mandatory = $true)]
    $numberOfDeploymentsToKeep,

    [int] 
    [Parameter(Mandatory = $true)]
    $batchSize
)

try {
    $c = Get-AzContext
}
catch {
    $c = $null
}

if (!$c -or !$c.Account) {
    Connect-AzAccount -Subscription $subscriptionId -Tenant $tenantId
} else {
    Select-AzSubscription -Subscription $subscriptionId -Tenant $tenantId
}

# ----------------------------------
# Get Deployments
# ----------------------------------

#$dateBeforeDeleteDeployments = Get-Date -Year 2018 -Month 06 -Day 30
#$deploymentsToDelete = Get-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName | Where-Object { $_.Timestamp -le $dateBeforeDeleteDeployments }

$currentDeployments = Get-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName

$currentNumberOfDeployments = ($currentDeployments | Measure-Object).Count
$numberOfDeploymentsToRemove = $currentNumberOfDeployments - $numberOfDeploymentsToKeep

if ($numberOfDeploymentsToRemove -lt 0) {
    throw "Number of deployments to remove is < 0..."
} 
if ($numberOfDeploymentsToRemove -eq 0) {
    Write-Host "Number of deployments to remove is 0..."
    return
}

Write-Host "Number of Deployments to remove: '$numberOfDeploymentsToRemove'..."

$deploymentsToDelete = $currentDeployments | Sort-Object -Property Timestamp | Select-Object -First $numberOfDeploymentsToRemove

$deploymentsToDelete | ForEach-Object {$i=0; $j=0; $deploymentsToDeleteBatched=@{}} {
    if($i -ne $batchSize -and $deploymentsToDeleteBatched["Batch $j"]) { 
        $deploymentsToDeleteBatched["Batch $j"]+=$_
        $i+=1 
    }
    else {
        $i=1
        $j+=1
        $deploymentsToDeleteBatched["Batch $j"]=@($_)
    }
}

Write-Host "Created $($deploymentsToDeleteBatched.Count) batches..."

# ----------------------------------
# Execute deletion in parallel
# ----------------------------------
$jobNames = @()
foreach ($batchkey in $deploymentsToDeleteBatched.Keys) {
    $deploymentsToDeleteBatch = $deploymentsToDeleteBatched.$batchkey

    $logic = {
        Param(
            [object] 
            [Parameter(Mandatory = $true)]
            $ctx,

            [object] 
            [Parameter(Mandatory = $true)]
            $deploymentsToDeleteBatch,

            [string] 
            [Parameter(Mandatory = $true)]
            $resourceGroupName
        )

        foreach ($deploymentToDelete in $deploymentsToDeleteBatch) {
            $deploymentName = $deploymentToDelete.DeploymentName
            Remove-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -DefaultProfile $ctx -ErrorAction Stop
            Write-Host "Deleted Deployment '$deploymentName' from '$($deploymentToDelete.Timestamp)'..."
        }  
    }

    $jobName = ([System.Guid]::NewGuid()).Guid
    $jobNames += $jobName
    $jobObject = Start-Job $logic -Name $jobName -ArgumentList (Get-AzContext), $deploymentsToDeleteBatch, $resourceGroupName
}

while (Get-Job -State "Running") {
    Write-Host "---------------------------------------------------------------"
    Write-Host "Jobs still running..."
    Get-Job | Format-Table
    Write-Host "---------------------------------------------------------------"
    Start-Sleep -Seconds 10
}

Write-Host "Jobs completed, getting output..."
Write-Host "---------------------------------------------------------------"

foreach ($jobName in $jobNames) {
    Write-Host "Output of Job '$jobName'..."
    Receive-Job -Name $jobName
    Write-Host "---------------------------------------------------------------"
}

Write-Host "Done..."