Azure Automation Best Practices Guide

By Greg Charman

Azure Automation Best Practices

Kelverion have put together this Azure Automation Best Practices Guide to support the creation of automation process in Azure Automation. Our consultants work with Azure Automation every day and have substantial experience with Azure Automation and IT automation built using other tools. It’s important to recognize that these are recommendations rather than hard and fast rules.

Each recommendation should be considered for use within a user’s own automations, and while readers may find that some of the recommendations don’t fit for development or proof of concept runbooks, the Kelverion team have found that they have been of great benefit in production solutions.

Name Runbooks with a Structure

Always use a structure for Runbooks names to simulate a folder structure within Azure. As readers may be aware, there is no folder structure for runbooks within Azure, however, by using a 3-part identifier for your runbooks, this can be simulated. The recommended approach is:

e.g. Alerting_Monitor_SCOM

Why? This helps keep things simple. It groups all the related runbooks together and makes it easier to manage them.


Poor Naming                                         Good Naming



Using Numbers Within the “Descriptive Function” Part of the Runbook Name

As in the pictures above, adding a numeric identifier to the third segment of the runbook name helps define the expected order of execution and provide an association between the Type segment.

i.e. all the 3xx runbooks above are related.

Meaningful Names for Runbooks and Activities

Give all runbooks and the activities within meaningful names rather than using defaults; this will save time when documenting and supporting your solution. Don’t forget that both runbooks and the activities they contain have description fields.

Using the Runbook Studio, users can colour code activities and links to make the flow of execution, error handling and other vital features much easier to understand. Combine colour with link labels and descriptive names, and the runbooks will almost document themselves.

Hybrid Worker Deployment

Hybrid-worker groups should contain at least two machines for resilience. If the hybrid-workers are not available, then runbooks that should be executed will go into a suspended state.

Ideally, the deployment and configuration of your hybrid workers should be automated. Cloud Hybrid workers can easily be deployed as a Hybrid Runbook Worker role through the Azure virtual machine (VM) extension framework. The Azure VM agent is responsible for management of the extension on Azure VMs on Windows and Linux VMs.

This can also be done for on-premise Hybrid Workers, ensure these are Azure Arc enabled servers using the Connected Machine agent.

Solution Segregation via Automation Accounts

Individual Automation Accounts are an excellent way to isolate unrelated solutions, this could include placing the Automation Accounts into separate Resource Groups for improved security separation.

This needs to be considered carefully at the planning stage, as it can introduce additional overheads for managing the solutions. Many of those limitations can be overcome using ARM templates for Automation Account deployment.

However, where hybrid-workers are currently used, they can only be assigned to a single Automation Account. This means that the number of hybrid workers will grow rapidly as the number of automation accounts increases.

Keep Connection Asset Names Generic

The properties of the connection asset hold all the specific information (User Name, Password, Server Name). If the user includes the server name or the name of the environment in the Asset name, then a user will need to modify it (and the runbooks that utilize that information) when deployed to a different environment or change servers.

For example: use the connection name ‘ServiceNow’ or ‘SCOM’ rather than ‘SN-Istanbul-dev’ or ‘SRV-SCOM-MS-01’.

Don’t Use Files for Data Repositories

Using files to hold temporary data or logging information is not recommended because once the runbook completes, the sandbox in which it was executed will be disposed of and the files removed from the system. This makes it challenging to troubleshoot.

Using a database to hold the temporary data or logging information makes it possible to centralize information independently of where the runbook is executed or which runbook is performing the task.

Use Variable Assets Sparingly

Variables are useful for pieces of information to be shared across multiple runbooks. However, they don’t serve the same purpose as true variables within the runbooks. Although variables can be updated using ‘Set-AzureRmAutomationVariable’, it can be challenging to manage multiple runbooks reading and writing the same set of variables.

Instead, think of variables as a ‘global constant’ to be shared across an automation

If data must be shared across multiple runbooks (or runbook executions), see 2.11.

Create Common Task Runbooks

Frequently, users reuse existing patterns within automation, such as logging in to an Azure Account, checking if a type of resource exists, or something more exotic.

If users create common “task” runbooks to carry out those activities, then Azure Automation makes it simple to call those tasks and execute them consistently.

Using the Kelverion Runbook Studio, users can drag and drop a task runbook into the main flow. When calling a child runbook, the child executes in the same process as the parent and executes synchronously, similar to calling a function within a script.

Alternatively, users can invoke a child runbook asynchronously using the ‘Start-AzureAzAutomation’ activity in the parent runbook. This is like executing a PowerShell Script block with ‘start-job’.

Implement Automation with a Runtime Database

Many automation challenges can be made more manageable through careful supervision of the runbooks and data used to drive them.

Using a database to support the automation gives users an easy to use centralized store for data that can be shared across runbooks and processes simultaneously as being accessed concurrently by those runbooks.

This database is called the Persistent Data Store (PDS), and it enables many of our Azure Automation best practices.

Always Deploy the Integration Module for SQL Server

As noted above, the Persistent Data Store (PDS) is a crucial enabler for many Kelverion best practices. To enable the easy deployment of a PDS as part of your automation solution, Kelverion include the Integration Module for SQL Server free with our authoring tool the Runbook Studio.

By deploying the Integration Module for SQL Server, users can exploit the power of smart discovery within the Runbook Studio to accelerate the development of runbooks. This allows the database interactions to happen without the need to write a single line of SQL code.

Create a Robust Error Reporting Routine

Create a standard Event handling process; within each of the runbooks. Write the error to the PDS and allow the error handling runbook to forward the errors to Azure Monitor, System Center Operations Manager, your organisation’s Service Desk or any other alert notification system you wish to use.

Azure Automation best practices error_log

Within a runbook, the hash table $ActivityError contains the details for activities that have raised errors. Within a users own code, either use ‘Write-Error’ to generate non-terminating errors, or you can “Throw” an exception.

Note that users can turn fatal errors into non-fatal errors to be handled in a controlled fashion within the runbook when you configure an activity.

Azrue Automation best practices activity

Debug to the PDS

The job logs for runbooks are quite verbose and can be hard to understand, even for relatively simple runbooks where all the actions are executed in-line. As the complexity of the runbooks increases, or as soon as a child runbook is executed out-of-band, users will benefit from writing debug information to an external store.

The PDS is the perfect location for that debug information. Consider setting a variable within the initialization section of the runbook to turn the logging on and off and then using a link condition before an ‘Insert-SQLRows’ Activity to log key pieces
of debug information.

Forward Job Logs to Azure Monitor

Forward your Azure Automation Job logs to Azure Monitor. The following article shows exactly how to do that, and once this is done, users can configure alerts to warn if issues are affecting the execution of their runbooks.

Forward Azure Automation diagnostic logs to Azure Monitor

Add a Branch for “nothing to process”

When troubleshooting runbooks via the logging in Azure, it can sometimes be challenging if there is no output from an activity when using pipeline mode because the runbook appears to stop executing (this is because there is no work to do).

Using Sequence links and a junction activity, it’s possible to add a generic handler to the runbook if there is nothing to do.

Azure Automation best practices sequence log

The code activity “Handle No Output” contains the following:

azure automation best practices handle no output

Add Initialization Phase to Each of your Runbooks

Create a linear section at the start of each runbook to initialize essential data to be used within the rest of the runbook. This initialization phase should use sequence links to hook its activities up (to ensure that each one runs once (and only once.))

Use consistent colour coding through all runbooks for the initialization phase so that other users looking at the runbook realize that it’s not part of the “main” flow of the runbook.

Don’t Use PowerShell Workflow

Initially, Azure Automation only supported PowerShell workflow. Users may find some documentation on the internet or examples of runbooks that use workflow. PowerShell workflow has some interesting features and capabilities; however, it also introduces some new challenges. If the user is already aware of the features and wants them, they are probably ready to deal with the challenges. If not, Kelverion recommends that users just focus on the power of ordinary PowerShell.

PSPrivateMetadata and “Finding yourself”

For every runbook executing, the PowerShell host creates an object holding some valuable information ‘$PSPrivateMetadata’.

Within the properties of this object, the JobID can be found for the currently executing runbook ‘$PSPrivateMetadata.JobId.Guid’

When recording any information to the PDS about a running runbook, it’s valuable to record the JobID as this allows users to retrieve job logs for the runbook.

Within a runbook, users can even use the JobID to find information about the current runbook, e.g. Automation Account Name, Runbook Name.

The following PowerShell Code does precisely that. Please remember that there is no direct method to get the runbook name, so the code below iterates through all the automation accounts for the current subscription. While this is not a particularly resource-intensive operation, this shouldn’t be done more than once for a runbook execution (as the data will not have changed).

This is a perfect example to become a “common task runbook”, and its execution probably should be added at the start of the runbook during the “initialization phase” see 2.17.

Note: if creating a task runbook containing this code, users will only receive information about the “parent” runbook if the child is executed “in-line” if the child is executed “out-of-band” with (Start-AzureRmAutomationRunbook), then the information returned will be for the child runbook alone.


Scheduling Runbook Execution

There are several options available for the scheduled execution of runbooks. There are pros and cons to each option.

1) Runbook Schedules – Runbook schedules can easily be configured in each Automation Account and assigned to one or more runbooks. This is a straightforward appoach to scheduling runbook execution.


  • No additional cost
  • Simple


  • Limited granularity (1 hour)
  • Lack of flexibility

2) Webhooks and Logic Apps – Runbooks can easily have webhooks configured to start the runbook when an HTTP Post is received. Azure has a comprehensive scheduling capability called Logic Apps that can trigger these webhooks. 


  • Simple
  • Flexibility
  • Down to 1 second scheduling
  • Easily manage multiple Automation Accounts
  • There are additional triggers in Logic Apps like database, so can be used with the PDS to only trigger Azure Automation when there is rows in the database to process.


  • Only time based
  • There is a cost associated with Logic Apps use

3) Dispatcher runbook and external configuration store – A custom dispatcher runbook is driven by data within the PDS and can give a considerable level of control over the scheduled execution of runbooks within one or many Automation Accounts. The time element and decision elements can be as simple or complex as required.


  • Powerful
  • Flexible


  • Complex (but can use graphical runbooks)
  • Requires automation minutes for execution
  • It depends on one of the other solutions to trigger the Dispatcher

4) Webhooks and Event Grid – Although this is not truly a scheduling approach, it is possible to configure the Azure Event Grid to trigger a runbook via a webhook based on a publish and subscribe model. For example, when a virtual machine is deployed to a subscription, an event is posted to the event grid. An appropriate subscription can then trigger a runbook to perform some actions against that virtual machine.


  • No additional cost
  • Simple
  • No “polling” for work to do


  • Not a scheduling solution as such
  • Recurring actions are still dependant on publishing a “trigger event”

Heartbeat Runbooks

If utilizing the power of Azure Monitor, then consider using the alerting to build a “heartbeat” mechanism that will provide out-of-band alerting for any or all the following: 

  • Hybrid Worker Groups
  • Scheduling facilities

Create a runbook that sends an event to Azure Monitor periodically (e.g. every 15 minutes) and then configure an alert if there are less than three alerts in any one hour period.

About Kelverion

Kelverion specializes in Service Request Automation and offers organizations automation solutions, integrations and supporting services.

Kelverion’s solutions wrap around your existing ITSM tool and enable organizations to harness the power of automation in the service management space, delivering a 400% return on investment over the first 12 months.

Kelverion has been involved with Microsoft’s Azure Automation since its inception and has a deep understanding of what is required to build efficient and effective automation solutions using Azure Automation. These best practices incorporate Kelverion’s own experiences building Azure Solutions and feedback from customers around their challenges.

For more information or a demonstration, please chat with a member of our team via or visit: