Automation, Azure, DevOps, Powershell, Professional, Terraform

Deploying Azure Automation Account and Runbooks via Terraform

Azure Automation Accounts leverage Azure Runbooks to automate processes within organizations’ Azure tenants. This process can be very powerful and help organizations effectively manage, scan, and update their environments. This post is not about Azure Automation Accounts or Azure Runbooks but rather the process by which to deploy these Accounts and their associated scripts via Terraform.

If unfamiliar, Terraform is an open-source Infrastructure as code provider. One of it’s biggest selling points is that it can be used for deploying to a plethora of providers. Since we are dealing with Azure we will be using the Azure provider. We will also assume that you are already familiar with how to deploy Terraform to Azure. If you are not here is the Terraform walkthrough for Azure.

The first step in the deployment will be creating the Azure Automation Runbook. This is done via the azurerm_automation_account resource like below:

resource "azurerm_automation_account" "aa_demo" {
  name                = 'aademo'
  location            = azurerm_resource_group.rg_automation_account.location
  resource_group_name = azurerm_resource_group.rg_automation_account.name

  sku_name = "Basic"

}

This automation account is referencing a resource group that will also be created as part of the Terraform file. Automation Accounts like any other Azure resource requires a Resource Group. The Resource Group is setup like:

resource "azurerm_resource_group" "rg_automation_account" {
  name     = 'rg-aatest-dev-eus
  location = "east us"

}

Unfortunately, the ability to create the Automation Account as a “RunAsAccount” cannot be configured at this this via Terraform. RunAsAccount is similar to a Managed Identity in Azure, aka the script will run as the resource…..thus RunAsAccount. That being said there is a github issue that outlines the steps that one could work around this. However; for initial setup it might be easier to create the Automation Account and toggle the Run. This located after the Automation Account has been created by going to “Run as Accounts”-> Create

So at this point the Terraform file will create the Resource Group and the Azure Automation Account. However, we still need to create the Runbook and upload the code that will be ran under it.

I have found the easiest way to do this is to store the script to be ran in the same project as the Terraform file. In this case we have the script in runbooks\poweshell\demo.ps1

This script will need to be imported into the Terraform file as a data reference of type local file. A block like this should do the trick:

data "local_file" "demo_ps1" {
  filename = "../runbooks/powershell/demo.ps1"
}

Once we do this Terraform is aware of the existence of the demo.ps1 file. This is important as we will pass this reference to the Runbook.

To create the Runbook we will leverage the azure_automation_runbook resource.

resource "azurerm_automation_runbook" "demo_rb" {
  name                    = "Demo-Runbook"
  location                = azurerm_resource_group.rg_automation_account.location
  resource_group_name     = azurerm_resource_group.rg_automation_account.name
  automation_account_name = azurerm_automation_account.aa_demo.name
  log_verbose             = "true"
  log_progress            = "true"
  description             = "This Run Book is a demo"
  runbook_type            = "PowerShell"
  content                 = data.local_file.demo_ps1.content
}

The content argument is key as that will pass the script that was referenced earlier and upload it’s contents as part of the deployment.

So now that the Automation Account has been created and the Runbook the demo.ps1 file can be executed in Azure. However; the need may still arise to schedule the execution of the demo.ps1 script. To do this we can leverage the azurerm_automation_job_schedule resource with first a schedule defined via azurerm_automation_schedule.

First the schedule:

resource "azurerm_automation_schedule" "sunday" {
  name                    = "EverySundayEST"
  resource_group_name     = azurerm_resource_group.rg_automation_account.name
  automation_account_name = azurerm_automation_account.aa_demo.name
  frequency               = "Week"
  interval                = 1
  timezone                = "America/New_York"
  description             = "Run every Sunday"
  week_days               = ["Sunday"]
}

This schedule is agnostic of the current Runbook and can be reused multiple times.

Next is the Terraform that links the Runbook and the schedule together:

resource "azurerm_automation_job_schedule" "demo_sched" {
  resource_group_name     = azurerm_resource_group.rg_automation_account.name
  automation_account_name = azurerm_automation_account.aa_demo.name
  schedule_name           = azurerm_automation_schedule.sunday.name
  runbook_name            = azurerm_automation_runbook.demo_rb.name
  depends_on = [azurerm_automation_schedule.sunday]
}

Now normally with Terraform the depends_on does not need to be declared as it should recognize that the sunday schedule is being reference and thus infer the demo_sched won’t run until the sunday schedule is created. However, at the time of this blog post there is an open bug on this issue. Thus, the workout is the explicitly call out the dependency.

After this everything is all done! Congratulations you should now be able to deploy an Azure Automation Account, Azure Runbooks, Schedules, and associated scripts via Terraform!