Wednesday, January 26, 2022

Create Azure Automation Account (using managed identity) and Runbooks using Azure PowerShell and deploy via Azure DevOps Pipeline.

Azure Automation is one of the most popular automation tools, designed specifically for resolving day to day operational challenges around process automation, configuration management and update management.

Some of the useful scenarios of Azure Automation are:

  • If you ever want to automate the process of creating virtual machines on Azure.
  • Or updating/ patching the VMs
  • De-allocating the VMs at the end of the day 
  • Scaling down and scaling up various Azure services to different SKUs to help you reduce operational costs and save time.
And the list is much more..

In this post, I will be discussing mainly about process automation, which is a way of automating the azure management or orchestrate processes using PowerShell or python scripts. Runbooks are created which are PowerShell or python scripts to write the logic. There are several types of runbooks described in the Microsoft documentation here Azure Automation runbook types | Microsoft Docs

I will focus on how to create Automation account using managed identity and how to create and run Azure Automation PowerShell Runbooks programmatically. 

PowerShell runbooks are based on Windows PowerShell. You directly edit the code of the runbook using the text editor in the Azure portal. You can also use any offline text editor and import the runbook into Azure Automation.

Azure Automation account using Run-As account vs Managed Identity

Whenever run as account is created, a new application is registered under App Registration in Azure Ad and self signed certificate will be generated which will be valid for one year. 

So there is an overhead of renewing the certificate every year before it expires to prevent the Automation account to stop working.

Some of the permissions needed for Run-as accounts are, 

  1. User Access Administrator at subscription level (needed for created Run-As account and renewing certificates) 
  2. At Azure AD, Application Administrator (for creating Service Principal) 
  3. Contributor access to Automation account

Now Microsoft has the ability to have Automation accounts to be configured to use Managed Identity which is default option when account is created. With is feature, Automation account can authenticate to Azure as itself without the need to exchange any credentials. And this removes the overhead of renewing the certificate or managing the service principal. 

Managed identity can be system assigned or user assigned. By default, now, whenever a new Automation account is created, system assigned managed identity is enabled.

Programmatically creating Automation Account and Importing Runbooks

This section create the following using Azure PowerShell scripts:

  1. Creating Automation Account using system assigned managed identity
  2. Create Role Assignment to give permissions to Automation account
  3. Creating Automation Schedule (Once/ Recurring)
  4. Create and Import Runbooks
  5. Scheduling Runbooks

GitHub Repository

You can access all the code and script from my GitHub repo:

Creating Automation Account using system assigned managed identity

This can be done simply in one line of code:

New-AzAutomationAccount -Name $AutomationAccountName -Location $Location -ResourceGroupName $ResourceGroupName -AssignSystemIdentity

The complete script is located at my GitHub repository:

Script Name: createAutomationAccount.ps1

The above script will create Automation account with system assigned managed identity enabled:

Create Role Assignment to give permissions to Automation account

Before you can use your system-assigned managed identity for authentication, you need to assign the appropriate role to that identity on the target Azure resource. For e.g. to start or stop an Azure VM, managed identity should be assigned the appropriate permission for starting or stopping VM. 

In the previous screen shot, if you click on "Azure role assignments", you will see there are no role assignments found as in the screen below:

To create a role assignment, I used the command below:

New-AzRoleAssignment -ObjectId $automationObject -RoleDefinitionName $RoleDefinition -Scope $Scope

where objectId can be obtained using the command below:

$automationObject = (Get-AzAutomationAccount -Name $AutomationAccountName -ResourceGroupName $ResourceGroupName).Identity.PrincipalId

For e.g. for giving contributor access on a resource group, you can use:

New-AzRoleAssignment -ObjectId $automationObject -RoleDefinitionName "Contributor" -Scope /subscriptions/<subscriptionId>/resourceGroups/<your resourcegroup name>

Note: In real world scenario, follow the principal of least privilege and carefully assign permissions only required to execute your runbook. 

The complete script is located at my GitHub repository:

Script Name: createRoleAssignment.ps1

Once the role is assigned, you will see the role in the Azure Portal as:

    Create and Import Runbooks

    Now, for creating runbooks, 3 commands are used in the PowerShell script:

    New-AzAutomationRunbook - This will create an empty runbook.

    Import-AzAutomationRunbook - This will import the runbook that has PowerShell script commands to do the stuff

    Publish-AzAutomationRunbook - This will publish the runbook

    The code snippet below is used to import all the runbooks from a specific location:

    The name of the runbook will be the same as filename of the PowerShell script.

    The complete script is located at my GitHub repository: 

    Script Name: createAndImportRunbooks.ps1 

    In my GitHub repository example, I have created 2 PowerShell script files in the location runbooks/rgs in my GitHub repository. CreateAndImportRunbooks.ps1 will import those PowerShell scripts (GetAllResourceGroups.ps1 and GetAResourceGroup.ps1) as Runbooks from the location runbooks/rgs. The runbooks name will be - GetAllResourceGroups and GetAResourceGroup

    On executing the script, the runbooks can be viewed in the portal as below:

    Creating Automation Schedule (Once/ Recurring)

    Now the Automation account is created with appropriate permission to managed identity. Also runbooks are created imported and published.

    Next, lets create a Automation schedule, that will be used by runbooks that were created in the previous step.

    Schedule can be "recurring" or "once".

    Below code snippet, creates the "recurring" schedule:

    This will create schedule that will run every evening on Monday to Friday.

    For non-recurring schedule, only hour interval is provided in the command:

    New-AzAutomationSchedule -AutomationAccountName $AutomationAccountName -Name $ScheduleName -StartTime $startTime -HourInterval 1 -ResourceGroupName $ResourceGroupName -TimeZone $TimeZone

    The complete script is located at my GitHub repository:

    Script Name: createSchedule.ps1

    Once script is executed successfully, recurring schedule will be created as below:

    Adding Runbook(s) to a schedule

    The last step is to add a runbook to the schedule. The code snippet of the script below calls Register-AzAutomationScheduledRunbook command to add a runbook to the schedule.

    To add multiple runbooks to a schedule call the script with -RunbooksName parameter with names separated by commas as below:
    -RunbooksName "GetAllResourcegroups,GetAResourceGroup"

    The complete script is located at my GitHub repository: 

    Script Name: registerRunbooksToASchedule.ps1

    The successful execution of the above script will add the runbooks to a schedule and can be viewed in the portal as below:

    Using Azure DevOps pipeline to run the scripts

    While these scripts can be executed from your local machine, I prefer to automate to run the scripts via pipeline.

    For this section, I would have to assume, you are familiar and experienced with Azure DevOps pipelines. 

    To create pipeline:

    1. Create repository in the Azure DevOps (Or you can use your own Git-Hub repository)
    2. Create Service Connection in Azure DevOps
    3. Create YAML pipeline using the repository
    I have added a YAML pipeline file that is used to call these scripts in the GitHub repository:

    File Name: CreateRunBooks.yml

    The pipeline can be improved to make it more generic for reusability, I have kept it simple for this demo. Just update your service connection and parameters in the file variables.yml

    Please feel free to leave your suggestions and comments on my post :)


    Post a Comment