Azure for Architects
上QQ阅读APP看书,第一时间看更新

Runbook authoring and execution

Azure Automation allows the creation of automation scripts known as runbooks. Multiple runbooks can be created using the Azure portal or PowerShell ISE. They can also be imported from Runbook Gallery. The gallery can be searched for specific functionality, and the entire code is displayed within the runbook.

A runbook can accept parameter values just like a normal PowerShell script. The next example takes a single parameter named connectionName of type string. It is mandatory to supply a value for this parameter when executing this runbook:

param(

    [parameter(mandatory=$true)]

    [string] $connectionName

)

$connection = Get-AutomationConnection  -name $connectionName  

$subscriptionid = $connection.subscriptionid

$tenantid = $connection.tenantid

$applicationid = $connection.applicationid

$cretThumbprint = $connection.CertificateThumbprint

Login-AzureRMAccount -CertificateThumbprint $cretThumbprint -ApplicationId $applicationid -ServicePrincipal -Tenant $tenantid  

Get-AzureRMVM

The runbook uses the Get-AutomationConnection cmdlet to reference the shared connection asset. The name of the asset is contained within the parameter value. Once the reference to the connection asset has been made, the values from the connection reference are populated into the $connection variable, and subsequently, they are assigned to multiple other variables.

The Login-AzureRMAccount cmdlet authenticates with Azure, and it supplies the values obtained from the connection object. It uses the service principal created earlier in this chapter for authentication.

Finally, the runbook invokes the Get-AzureRMVm cmdlet to list all the VMs in the subscription.

By default, Azure Automation still provides AzureRM modules for working with Azure. It does not install Az modules by default. Later we will install an Az module manually in the Azure Automation account and use cmdlets in runbooks.

Parent and child runbooks

Runbooks have a life cycle, from being authored to being executed. These life cycles can be divided into authoring status and execution status.

The authoring life cycle is shown in Figure 4.11.

When a new runbook is created, it has the New status and as it is edited and saved multiple times, it takes the In edit status, and finally, when it is published, the status changes to Published. It is also possible to edit a published runbook, and in that case, it goes back to the In edit status.

A flow diagram showing the authoring life cycle with three stages—New, In edit, and Published.
Figure 4.11: Authoring life cycle

The execution life cycle is described next.

The life cycle starts with the beginning of a runbook execution request. A runbook can be executed in multiple ways:

Manually from the Azure portal

By using a parent runbook as a child runbook

By means of a webhook

It does not matter how a runbook is initiated; the life cycle remains the same. A request to execute the runbook is received by the Automation engine. The Automation engine creates a job and assigns it to a runbook worker. Currently, the runbook has a status of Queued.

There are multiple runbook workers, and the chosen one picks up the job request and changes the status to Starting. At this stage, if there are any scripting and parsing issues in the script, the status changes to Failed and the execution is halted.

Once the runbook execution is started by the worker, the status is changed to Running. The runbook can have multiple different statuses once it is running.

The runbook will change its status to Completed if the execution happens without any unhandled and terminating exceptions.

The running runbook can be manually stopped by the user, and it will have the Stopped status.

A block diagram displaying the execution life cycle for runbooks.
Figure 4.12: The execution life cycle for runbooks

The user can also suspend and resume the execution of the runbook.

Creating a runbook

A runbook can be created from the Azure portal by going to the Runbook menu item in the left navigation pane. A runbook has a name and type. The type determines the scripting language used for creating the runbook. We have already discussed the possible languages, and in this chapter, PowerShell will be used primarily for all examples.

Creating a PowerShell runbook is exactly the same as creating a PowerShell script. It can declare and accept multiple parameters—the parameters can have attributes such as data types, which are mandatory (just like any PowerShell parameter attributes). It can invoke PowerShell cmdlets whose modules are available and already loaded and declared, and it can invoke functions and return output.

A runbook can also invoke another runbook. It can invoke a child runbook inline within the original process and context or in a separate process and context.

Invoking a runbook inline is similar to invoking a PowerShell script. The next example invokes a child runbook using the inline approach:

.\ConnectAzure.ps1 -connectionName "azureforarchitectsconnection"

Get-AzSqlServer

In the preceding code, we saw how the ConnectAzure runbook accepts a parameter named connectionName and an appropriate value is supplied to it. This runbook creates a connection to Azure after authenticating with it using a service principal. Check out the syntax for invoking the child runbook. It is very similar to invoking a general PowerShell script along with parameters.

The next line of code, Get-AzVm, fetches the relevant information from Azure and lists the VM details. You will notice that although the authentication happens within a child runbook, the Get-AzVm cmdlet succeeds and lists all the VMs in the subscription because the child runbook executes in the same job as that of the parent runbook, and they share the context.

Alternatively, a child runbook can be invoked using the Start-AzurermAutomationRunbook cmdlet provided by Azure Automation. This cmdlet accepts the name of the Automation account, the resource group name, and the name of the runbook along with parameters, as mentioned here:

$params = @{"connectionName"="azureforarchitectsconnection"}

$job = Start-AzurermAutomationRunbook '

    –AutomationAccountName 'bookaccount' '

    –Name 'ConnectAzure' '

    -ResourceGroupName 'automationrg' -parameters $params

if($job -ne $null) {

    Start-Sleep -s 100

    $job = Get-AzureAutomationJob -Id $job.Id -AutomationAccountName 'bookaccount'

    if ($job.Status -match "Completed") {

        $jobout = Get-AzureAutomationJobOutput '

                                    -Id $job.Id '

                                    -AutomationAccountName 'bookaccount' '

                                    -Stream Output

                    if ($jobout) {Write-Output $jobout.Text}

    }

}

Using this approach creates a new job that's different from the parent job, and they run in different contexts.