Image of a Playmobil garbage man by jacqueline macou - https://pixabay.com/users/jackmac34-483877/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=771313

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.

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:

  1. Automatically assign a purpose1 if it’s missing.
  2. For resource groups with a tag purpose set to experiment, add an expiry date automatically, two weeks from now
  3. Delete groups with an expiry tag once it’s in the past
  4. 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

Functions in the Azure Portal

The function app contains three functions:

  1. AddPurpose runs every hour and adds a purpose tag if none is set.
  2. AddExpiryDate runs every hour and adds an expiry tag in 2 weeks if none is set.
  3. CleanupExpired runs once a day at UTC+8 (PT), and deletes all resource groups where expiry 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:

View of the notification logicapp

Based on the type, a different message is assembled, then it uses the O365 connector to send an email.

I'm sending myself emails

Code

All the code is here.

Notes

  1. Purpose being: experiment, production, development, etc.