Azure Garbage Collection (auto-delete Your Unused Resources)
As I described in a previous post on ephemeral workloads, I separate experiments into their own resource groups and like to automate all provisioning to make sure they’re repeatable and delete-able.
I saw this tweet from Jeff Hollan the other day and it gave me the foundation to create a garbage collector for my experiments using Powershell Azure Functions. This makes a good example of Azure management automation using Functions.
When I create a quick demo or repro I preface my resource groups with "deleteme" - but sometimes forget to clean them up. Just wrote a quick PowerShell @AzureFunctions that does it automatically for me every night! Took about 10 minutes and 10 lines 🎉 pic.twitter.com/WtJDwgQjcm
— Jeff Hollan (@jeffhollan) May 26, 2019
The concept is great! Since I’m already using a purpose
tag to identify transient workload I want to piggy-back on that. I also want to be able to keep resource groups longer than just one day. My garbage collector needs to:
- Automatically assign a
purpose
1 if it’s missing. - For resource groups with a tag
purpose
set toexperiment
, add an expiry date automatically, two weeks from now - Delete groups with an
expiry
tag once it’s in the past - Send me notification to make sure things aren’t marked for deletion erroneously.
To do so I’m using a combination of Powershell Azure Functions to tag and remove the resources, and LogicApp to send notifications. The solution (including a provisioning script that can be ran to deploy everything to your own subscription) is on GitHub.
FunctionApp
The function app contains three functions:
AddPurpose
runs every hour and adds apurpose
tag if none is set.AddExpiryDate
runs every hour and adds anexpiry
tag in 2 weeks if none is set.CleanupExpired
runs once a day at UTC+8 (PT), and deletes all resource groups whereexpiry
is in the past.
All functions send a message to a queue when they do something.
Those functions are relatively simple. Let’s look at CleanupExpired
for example:
Select the subscription and query expired resource groups:
param($Timer)
$date=Get-Date
Write-Host "Garbage collection triggered at $date"
Select-AzSubscription -Subscription $env:SUBSCRIPTION
$expiredResources = Get-AzResourceGroup | Where-Object { $_.Tags.expiry -and [DateTime] $_.Tags.expiry -lt $date }
Iterate through resource groups and delete them:
Foreach ($resourceGroup in $expiredResources) {
Write-Host "Collecting $($resourceGroup.ResourceGroupName)"
Remove-AzResourceGroup -Name $resourceGroup.ResourceGroupName -Force
Send a message to the queue (using a queue binding):
$evt = [ordered]@{
type="groupCollected"
group=$resourceGroup.ResourceGroupName
date=$date
}
$jsonEvent = $evt | ConvertTo-Json -Depth 10
Push-OutputBinding -Name "eventsQueue" -Value $jsonEvent
}
Write-Host "Done collecting"
LogicApp
The logic app uses the queue connector to retrieve messages to be sent:
Based on the type, a different message is assembled, then it uses the O365 connector to send an email.
Code
All the code is here.
Notes
-
Purpose being: experiment, production, development, etc. ↩