Azure Automation: creando runbooks

Hace unos días estaba pensando en la mejor forma de poder apagar y encender todas las máquinas que tenía en mi suscripción de pruebas, con el fin de ahorrar gastos innecesarios. Este puede ser además un escenario muy común en el mundo cloud para entornos de desarrollo, preproducción, QA, etcétera: Si conozco el horario en el que se están haciendo uso de ciertas máquinas ¿Por qué no apagarlas cuando no son necesarias y así ahorrar costes?
El servicio pensando para este tipo de tareas automáticas dentro de la plataforma Microsoft Azure se conoce como Automation (todavía en preview). Básicamente lo que nos permite es crear scripts en PowerShell llamados runbooks que nos ayuden a realizar múltiples tareas. En este post me gustaría mostrar cómo apagaríamos y encenderíamos nuestras máquinas virtuales de una forma programada.

Crear y subir un certificado de administración al portal

Lo primero que debemos hacer es subir un certificado para poder dar acceso a los runbooks del servicio. Para esta demo basta con crear un certificado firmado por nosotros mismos, haciendo uso de la herramienta makecert.exe:

makecert.exe -n "CN=AutomationCert" -pe -ss My -sr CurrentUser -r -a sha1 -sy 24 -sky exchange -len 2048

Azure Automation makecert

Exportamos el mismo con y sin la contraseña privada (seleccionando el certificado dentro de Personal > Certificates y con el botón derecho All Tasks > Export):

Automation certs

Dentro del apartado Settings > MANAGEMENT CERTIFICATES subimos el archivo .cer:

Settings Management Certificates Azure Automation

Crear un servicio de Azure Automation

La forma de crear un servicio de Azure Automation es muy sencillo. Lo primero es necesario comprobar que tenemos acceso a la preview del servicio a través de la página de Preview features:

Azure Automation Preview Feature

Dentro del portal buscamos la sección AUTOMATION y hacemos clic sobre CREATE AN AUTOMATION ACCOUNT:

Create an automation account

Es necesario elegir un nombre para la cuenta y la ubicación de la misma. Durante la preview sólo es posible crear el servicio en East US:

Add a New Automation Account

Esta operación tardará tan sólo unos segundos. Si accedemos a la nueva cuenta veremos que tenemos diferentes apartados:

  • DASHBOARD: nos muestra el estado de la cuenta, el número de jobs lanzados en los últimos 30 días, su estado, número de runbooks, conexiones, variables, etcétera.
  • RUNBOOKS: se utiliza para gestionar los runbooks o listado de procedimientos.
  • ASSETS: nos permite agregar diferentes tipos de elementos, como certificados, conexiones, variables, etc.

Asociar el certificado de administración con Automation

Si recordamos el primero de los pasos, tuvimos que crear un certificado y exportar el mismo con y sin la clave privada. El archivo .cer lo subimos directamente al portal y ahora necesitamos enlazar el certificado con clave privada con nuestra nueva cuenta de Azure Automation. Para ello, seleccionamos la pestaña ASSETS y hacemos clic en la opción ADD SETTING del menú inferior. En el nuevo cuadro de diálogo seleccionamos ADD CREDENTIAL para la asociación del certificado:

Azure Automation Add Setting Credential

Cuando creamos una credencial existen a día de hoy dos posibilidades: Windows Powershell Credential y Certificate. La primera de ella nos permite utilizar Azure Active Directory para la conexión con Azure Automation. En este ejemplo utilizaremos la segunda opción basada en certificados.

Automation ADD CREDENTIAL Define Credential

Crear una conexión

Una vez que tenemos dado de alta el certificado que queremos utilizar necesitamos un nuevo elemento llamado conexión. Lo que nos va a permitir es enlazar el certificado, que a su vez se corresponde con el certificado que subimos en el apartado settings, y la suscripción a la que pertenece. Para ello, volvemos a utilizar ADD SETTING, pero esta vez elegimos la opción ADD CONNECTION:

Azure Automation Add Setting Add Connection

En el primer paso del asistente es muy importante utilizar como nombre el nombre de la suscripción a la que va asociada, ya que de lo contrario no funcionará:

Automation Add Connection Configure connection

Por último, debemos escribir el nombre del certificado que dimos de alta dentro de la cuenta de Azure Automation y el Id de la suscripción:

Automation Add Connection Configure connection properties

Runbooks

Una vez que tenemos creada y configurada la nueva cuenta ya estamos preparados para la creación o importación de runbooks. Un runbook básicamente es un script en Powershell a través del cual podemos lanzar una o más acciones. Lo ideal es que cada módulo sea lo más simple y concreto posible, con el fin de que varios de ellos puedan ser reutilizados dentro de otros runbooks. En este ejemplo vamos a crear 3 scripts: uno que conecte con la suscripción, otro que pare las máquinas virtuales de la misma y un último que sea capaz de arrancarlas.

Runbook #1: Conexión con la suscripción

Antes de comenzar a crear nuestros propios scripts es importante saber que existe un sitio llamado Script Center, donde el propio equipo del producto, y otros desarrolladores, comparten sus propios runbooks. Para este ejemplo he utilizado el llamado Connect to an Azure Subscription using Certificates. Cuando creamos o descargamos un runbook la única acción que debemos llevar a cabo es la importación del archivo dentro de la cuenta. Para ello, accedemos al apartado de RUNBOOKS y utilizamos la opción IMPORT del menú inferior:

Automation IMPORT runbook

Si hacemos clic en la opción EDIT RUNBOOK o bien seleccionamos el nuevo elemento dentro del listado podemos acceder al script e incluso realizar pruebas antes de publicarlo. En este caso, pulsamos sobre la opción PUBLISH del menú inferior:

Automation Connect-Azure Runbook

Runbook #2: Apagando máquinas

En el caso del runbook que se encarga del apagado de las máquinas virtuales lo vamos a crear desde cero. Para ello, dentro del apartado RUNBOOKS pulsamos sobre el botón NEW > APP SERVICES > AUTOMATION PREVIEW > RUNBOOK > QUICK CREATE y utilizamos como nombre Stop-VMs:

New Automation Runbook

Una vez que el nuevo elemento se haya creado aparecerá en la lista junto con Connect-Azure. Hacemos clic sobre él y seleccionamos la pestaña AUTHOR. Al tratarse de un nuevo script, encontraremos la siguiente estructura:

workflow Stop-VMs
{
}

Todos los runbooks deben estar encapsulados dentro de un workflow con el nombre que hayamos elegido. En este script además vamos a hacer uso del módulo anterior, Connect-Azure, para poder acceder a los elementos de la suscripción sobre la cual queremos operar. Una vez que tengamos acceso, recuperaremos todas las máquinas virtuales existentes y utilizaremos el comando Stop-AzureVM por cada una de ellas. El código del script sería similar al siguiente:

workflow Stop-VMs
{
    #Connect-Azure -AzureConnectionName
    $subscriptionName = "Internal Consumption"
    Connect-Azure -AzureConnectionName $subscriptionName
    Select-AzureSubscription $subscriptionName
    # Get VMs
    $VMs = Get-AzureVM
    $VerbosePreference = "Continue"
    if( $VMs.Count -gt 0 ){
        Foreach($vm in $VMs){
            $vmName = $vm.Name
            Write-Verbose "Stopping $vmName"
            Stop-AzureVM -ServiceName $vm.ServiceName -Name $vm.Name -Force
        }
        "All machines are now stopped!"
    }
    else{
        "You don't have machines in this subscription"
    }
}

Antes de publicar el código anterior, podemos realizar pruebas y ver el resultado a través de la sección Output, utilizando el botón TEST del menú inferior:

Automation Runbook Output pane

Runbook #3: Arrancando máquinas

El último script que debemos crear es exactamente igual que el anterior a excepción del comando a utilizar, ya que en este caso será Start-AzureVM:

workflow Start-VMs
{
    #Connect-Azure -AzureConnectionName
    $subscriptionName = "Internal Consumption"
    Connect-Azure -AzureConnectionName $subscriptionName
    Select-AzureSubscription $subscriptionName
    # Get VMs
    $VMs = Get-AzureVM
    if( $VMs.Count -gt 0 ){
        Foreach($vm in $VMs){
            $vmName = $vm.Name
            Write-Verbose "Starting $vmName"
            Start-AzureVM -ServiceName $vm.ServiceName -Name $vm.Name
        }
        "All machines are now started!"
    }
    else{
        "You don't have machines in this subscription"
    }
}

Una vez que hayamos realizado las pruebas pertinentes publicamos los runbooks Stop-VMs y Start-VMs.

Programando runbooks

En el caso de la parada de las máquinas, accedo al runbook Stop-VMs y en la pestaña Schedule seleccionamos la opción Link to a new schedule:

Automation Stop-VMs Link to a new Schedule

Lo único que necesitamos es elegir un nombre y de manera opcional una descripción:

Automation Configure Schedule

Por último debemos elegir cuándo y con qué frecuencia queremos que se lance:

Automation Configure Schedule Daily

En el caso del arranque de las máquinas sería exactamente igual pero, en mi caso, cambiando la hora de ejecución a las 8:00.

Espero que haya sido de utilidad.

¡Saludos!