VSTS - удаление предыдущих развертываний во время выпуска

Я работаю над проектом Azure, где развертывания могут быть выполнены только с использованием шаблонов ARM из Visual Studio CI, и у нас есть только доступ для чтения к порталу Azure.

В настоящее время я получаю сообщение об ошибке ниже и не могу сделать никаких релизов. Я также не могу удалить развертывания из портала, так как у меня есть только разрешение на настройку фаз сборки и выпуска, мне было интересно, есть ли какая-либо фаза, которую я могу создать, где удаляются предыдущие развертывания.

До сих пор я пробовал несколько вещей, таких как использование встроенной команды PowerShell Remove-AzureRmResourceGroupDeployment, удаление группы ресурсов типа Microsoft.Resouces/deployments до фазы развертывания ресурса, но ни одна из них не работала.

[ошибка] Создание развертывания "azuredeploy-2017721-715" превысит квоту "800". Текущее число развертываний равно 800. Пожалуйста, удалите некоторые развертывания перед созданием нового. Пожалуйста, смотрите https://aka.ms/arm-deploy для деталей использования.

1 ответ

Решение

Используйте задачу Azure PowerShell. Он заботится об аутентификации для вас - не нужно звонить Login-AzureRmAccount,

Вот сценарий, позволяющий удалять такие развертывания параллельно. Вы также можете использовать это для задачи Azure PowerShell в Azure DevOps. Если у вас есть проблемы с аутентификацией, посмотрите здесь: учетные данные Azure не настроены или срок их действия истек, запустите Connect-AzAccount

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..."