Microsoft have announced that on October 1st, 2023 Azure Automation Run-as accounts will be retired and no longer work. This means that all Azure automation scripts using Run-as accounts for authentication will stop working on this date. During recent testing I’ve recently noticed that all new Azure Automation accounts created after April 1st, 2023 can no longer even use run-as accounts:
Fortunately, this gives us Azure admins a bit of time to update existing Azure Automation accounts and scripts to use the much more secure Managed Identities.
In my projects I commonly use Azure Automation for scheduling start-ups and shutdowns and VMs so I wanted to show how I’ve changed an automation account running scripts for this purpose from a run-as account to a managed identity.
In my Azure automation account I have a run-as account as below:-
You will see the Run-as account is a service principal which has automatically been granted Contributor access to the subscription:
You can see this is an example of why this functionality is being deprecated – this account is only going to start-up/shutdown VMs so why does it need contributor access to the entire subscription?
We can lock this down by manually removing the Contributor role assignment at the subscription level and granting Virtual Machine Contributor access to the relevant resources or resource groups, but by default run-as accounts will automatically be granted Contributor access to the subscription they are deployed in.
Furthermore, the service principal created will have a certificate and/or password (secret) which if compromised will allow login and read/write access to the entire subscription.
Managed Identities improve this functionality by introducing an account that can only authenticate on behalf of a single Azure Automation account (or multiple in the case of a user-assigned managed identity). There are no passwords or certificates being used and permission assignment must be done manually.
Back to my example, I have a Powershell runbook in my Azure Automation account which starts up VMs depending on the existence of a tag value:
#### Tag Based Start ####
# Connection Block
$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Connect-AzAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint
# VM Action Block
$VMs = Get-AzVM | where {$_.Tags.Values -like ‘Start_7am’}
$VMs | Start-AzVM
Write-Output $VMs.Name
This script will connect using the Service Principal associated with this Automation account, search for all VMs and start the VMs with a Tag Value of ‘Start_7am’. This script runs every day at 7am.
To change this script to use a managed identity I first need to create a managed identity. This is done in the Identity section of the Azure Automation account resource by toggling the status to on.
NOTE: Managed Identities are similar to the concept of Managed Service Accounts (MSAs) in Windows Active Directory. Before these were released, Windows services were often run as normal AD accounts with a username and password. MSAs (released with Windows Server 2008 R2) allowed accounts to be assigned to a computer object and then used to run Windows services on that computer.
These were then superseded by Group Managed Service Accounts (gMSAs) which allowed this AD account to be assigned to multiple computer objects.
Similarly, Azure Managed Identities come in two varieties, system-assigned and user-assigned. The former is a managed identity that is assigned to a single Azure Automation account whereas the latter can be used to be assigned to multiple Azure Automation accounts. When you create a user-assigned managed identity, it appears as a resource in a resource group.
You can then assign it to multiple azure automation accounts on the User-assigned tab in the Identity section of the Azure Automation account.
Anyway, back to my example of using Azure Automation to start-up VMs to a schedule. Once the Managed Identity is enabled you will need to grant it access to the resource groups that the VMs it is going to control reside in. To do this, copy the Object (principal) ID of the newly created Managed Identity as per one of the screenshots above.
Grant the managed identity Virtual Machine Contributor role on the relevant resource group:
Once this is complete, we need to modify our start-up script to use the managed identity rather the service principal.
#### Tag Based Start ####
# Connection Block
Connect-AzAccount -Identity
# VM Action Block
$VMs = Get-AzVM | where {$_.Tags.Values -like ‘Start_7am’}
$VMs | Start-AzVM
Write-Output $VMs.Name
As you can see the connection block in the new script, it is much simpler, and we can run our script in 4 lines of PowerShell.
You can then tag machines with a tag value of ‘Start 7am’ (tag name is up to you) and link your PowerShell runbook to a schedule that runs daily at 7am.
We can also add a second runbook to shutdown VMs, but equally this can be controlled by the ‘Scheduled shutdown’ option available on all Azure VMs.
#### Tag Based Stop ####
# Connection Block
Connect-AzAccount -Identity
# VM Action Block
$VMs = Get-AzVM | where {$_.Tags.Values -like ‘Stop_9pm’}
$VMs | Stop-AzVM -Force
Write-Output $VMs.Name