Azure DevOps - Workload Identity Federation
In a previous blog post, I discussed Workload Identity Federation in AKS, the successor to the Azure Pod Identity solutions and a more elegant
Shutting down a virtual machine is a very easy job. You just go to the portal and press the stop button or you can just as simply run a Stop-AzVM command but what happens when you're working in a global company with people from multiple time zones?
You could say that the solution would be to set the VM DevTest Lab resource:
But that would require a lot of clicking and manual work so you just might as well write a script for it to apply it programmatically and then you're going to meet your first issue. Which time zone is the correct time zone for each user?
The problem with keeping time zones is that they exist and you're better off delegating that problem to somebody else.
This video explains the time zone problem much better than can I explain it and I recommend watching it so you don't fall in a pit like I almost did once :)
Now that we watched the video, we can understand the hassle we have with time zones. So we're better off querying Azure AAD for the users location (if they have one set, if not then you have a different problem) and getting the time zone from a provider that keeps time.
As an Azure guy, my first approach was to go query the Google API but I shortly found out that I'd rather skin a tree than jump through the hoops that Google set up. I also tried find other providers but again no luck or hitting paywalls.
After almost giving up I remembered that Bing exists and it has a maps system which is also used in Microsoft Flight Simulator. Not perfect, but it works.
Lo and behold https://www.bingmapsportal.com/, get a key and start querying.
No really, it's that easy, check this out:
$cityname = 'Cluj-Napoca'
$apiKey = 'frombingdevcenter'
$uri = "https://dev.virtualearth.net/REST/v1/timezone/?query=$cityName&output=json&key=$apiKey"
$response = Invoke-WebRequest -Uri $uri
$result = $response.content | ConvertFrom-Json
$result.resourceSets.resources.timeZoneAtLocation.timezone
I kid you not, this was the simplest query ever. It gives the output in Windows enum type which needs to be used in the Auto-Shutdown blade and that's it.
Now that we have the time zone data at our finger tips, we can start automating VM shutdowns based on a users time zone. At this point if you don't know the owner of that VM, then you need to setup a general governance practice with tagging resource groups / resources with an owner / creator tag.
#timezone from the script from above
$timezone = $result.resourceSets.resources.timeZoneAtLocation.timezone.windowsTimeZoneId
$VM = Get-AzVM #name and rg
$resourceGroupName = $VM.ResourceGroupName
$virtualMachineName = $VM.Name
$subscriptionId = $VM.Id.Split("/", 10)[2]
$scheduledShutdownResourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/microsoft.devtestlab/schedules/shutdown-computevm-$virtualMachineName"
$scheduleSplat = @{
status = "Enabled"
taskType = "ComputeVmShutdownTask"
dailyRecurrence = @{
time = "12:00"
}
timeZoneId = "$timezone"
targetResourceId = $virtualMachine.Id
}
New-AzResource -Location $virtualMachine.Location -ResourceId $ScheduledShutdownResourceId -Properties $scheduleSplat -Force
With the script from above, you will have created the devtestlab schedule for the VM that will shut it down during the correct time zone e.g. User is sleeping ish :)
That being said, when in doubt, give a Bing system a try, it might surprise you. It surprised me so why not you.
Have a good one!