'Get-AzKeyVault -InRemovedState call from Azure Function returns null even after long wait

Here's the sequence of actions performed inside Azure powershell function -

if (Get-AzKeyVault -VaultName $name) {
    #This should Delete the KeyVault and put it into "Removed" state
    Remove-AzKeyVault -VaultName $name -Force
}

$timeout = New-TimeSpan -Minutes 16
$stopWatch = [System.Diagnostics.Stopwatch]::StartNew()

do{
   Write-Host "Waiting for 2 minutes before checking InRemoved status of KeyVault '$name'"
   Start-Sleep -s 120
   $vault = Get-AzKeyVault -InRemovedState | Where-Object { $_.VaultName -eq $name }
} while ($stopWatch.ElapsedMilliseconds -lt $timeout.TotalMilliseconds -and $vault -eq $null)
            
if ($vault) {
  Write-Host "Removing '$name' Key Vault which is in Removed State"
  Remove-AzKeyVault -VaultName $name -Force -InRemovedState -Location $vault.Location
}

It seems, the "Get-AzKeyVault -InRemovedState | Where-Object { $_.VaultName -eq $name }" never returns the vault object and finally the function times out after the given timeout (16 minutes here). I tried from just putting a normal sleep of 20 seconds to this timeout based do-while and the Get-AzKeyVault -InRemovedState never gives already Removed Vault's object.

The same logic works perfectly fine locally with no wait time required at all.

Am I doing anything wrong here from Azure powershell function? Suggestions / help would be appreciated.



Solution 1:[1]

I have to do the same thing for a teardown script and I also encountered the issue you're describing. I ultimately ended up with this. It doesn't feel as safe, but Azure doesn't provide much feedback on the delete/purge on Key Vaults. This has been working for me for several months.

# Key vaults that are soft-delete enabled must be deleted and then purged
# Delete them first because the resource group can't be targeted after they are in the deleted state
$keyVaults = Get-AzKeyVault -ResourceGroupName $resourceGroupName

foreach($kv in $keyVaults)
{
    Remove-AzKeyVault -VaultName $kv.VaultName -ResourceGroupName $kv.ResourceGroupName -Force
    Remove-AzKeyVault -VaultName $kv.VaultName -Location $kv.Location -InRemovedState -Force -ErrorAction SilentlyContinue
}

Solution 2:[2]

The Purge access on Access Policy only grants the Purge - Keys, Secrets and Certificates permissions, whereas to actually purge (permanently delete) a soft-deleted KeyVault itself, the Managed Identity of the Function App needs to have a Subscription Level Role assigned to it (in Azure RBAC) which grants it permission to execute the action - "Microsoft.KeyVault/locations/deletedVaults/purge/action".

Once this role was granted to the MI of Function App, and the Purge Access Policy was also available, the script could easily soft-delete and permanently delete both the Secrets as well as the KeyVault itself.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 joelforsyth
Solution 2 omkar.ghaisas