AWS Instance Scheduler permite gestionar el arranque y parada automáticos de instancias EC2 y bases de datos del servicio AWS RDS de forma programada. Esta es una de las formas más sencillas de ahorrar en el uso de estos servicios de AWS: apagándolos cuando no se necesitan (por ejemplo en entornos de desarrollo o de test).

Amazon proporciona una plantilla de AWS CloudFormation que permite desplegar todos los recursos necesarios de forma automática.

Cómo funciona AWS Instance Scheduler

AWS Instance Scheduler Architecture

AWS Instance Scheduler Architecture

La plantilla de CloudFormation configura eventos en Amazon CloudWatch de manera que se ejecute una acción -la ejecución de una función Lambda- con la frecuencia que especifiquemos.

La función NombreDelStack-InstanceSchedulerMain lee la configuración de una tabla de DynamoDB con los periodos en los que las instancias tienen que estar en ejecución.

Cuando se ejecuta la lambda, se comprueban las etiquetas aplicadas a las instancias y se encienden o apagan según corresponda.

Definir schedules y periods

En mi opinión este es uno de los puntos mejorables de la documentación de AWS Instance Scheduler.

En la documentación no se indica -en mi opinión- con suficiente detalle cómo crear estos periodos o programaciones. Se indica, eso sí, que se pueden crear desde la consola de DynamoDB, desde un custom resource o desde el AWS Instance Scheduler CLI (un script en Python), pero no cómo hacerlo.

Curiosamente, si revisas los elementos que contiene la tabla <NombreDelStack>-ConfigTable-..., verás que sí que contiene algunas entradas (tanto para definir periodos como schedules):

Estos valores no aparcen en el fichero de CloudFormation, por lo que no tengo claro desde dónde se introducen en la base de datos.

Definiciones

Tienes la información de qué es un schedule y un period en la documentación.

Un period especifica el tiempo en el que la máquina debe arrancar y apagarse. Un schedule puede contener más de un period. Por ejemplo, podríamos crear un schedule que contenga dos periodos, uno de mañana y otro de tarde (de manera que las máquinas estarían apagadas durante el mediodía).

También puedes reutilizar un period en diferentes schedules, ya que la zona horaria se define en el schedule.

El periodo de “horas de oficina” podría ser el mismo en dos ubicaciones, por ejemplo, de 09h a 17h. Sin embargo, la hora “global” de arranque de las máquinas no sucede a la vez si la zona horaria es Europe/London que si es America/Barbados, por ejemplo. En este caso, tendríamos que crear dos schedules diferentes, uno llamado london-office-hours y barbados-office-hours, por ejemplo.

Paso a paso

A la práctica, la forma más rápida para poder crear tus propios periodos de actividad para las instancias es a través de la consola de DynamoDB.

Selecciona la tabla ...-ConfigTable-... y la pestaña Items para ver las entradas de esta tabla (los de la imagen superior).

Selecciona un period y en el desplegable Actions, selecciona Duplicate. A partir de ahí edita el nuevo ítem para ajustarlo al periodo que quieres definir.

Por ejemplo, el siguiente periodo define como hora de inicio (arranque de las máquinas) las 06h, apagándolas a las 18h de lunes a viernes.

{
  "begintime": {
    "S": "06:00"
  },
  "description": {
    "S": "06-18"
  },
  "endtime": {
    "S": "18:00"
  },
  "name": {
    "S": "06-18"
  },
  "type": {
    "S": "period"
  },
  "weekdays": {
    "SS": [
      "mon-fri"
    ]
  }
}

A continuación, repito el proceso para duplicar un schedule y lo “asocio” al periodo definido mediante el uso de la propiedad name:

{
  "description": {
    "S": "Schedule for 06h-18h"
  },
  "name": {
    "S": "schedule-06-18"
  },
  "periods": {
    "SS": [
      "06-18"
    ]
  },
  "timezone": {
    "S": "Europe/Madrid"
  },
  "type": {
    "S": "schedule"
  }
}

Aplicando la etiqueta a las instancias (o RDS)

Para que AWS Instance Scheduler identifique qué recursos debe gestionar, en la configuración del CloudFormation indicamos la etiqueta que la función Lambda buscará al inspeccionar las instancias EC2 o bases de datos RDS.

Esta etiqueta, por defecto, es Schedule. El valor de la etiqueta debe ser uno de los schedule definidos en la base de datos DynamoDB.

Un detalle importante que debes considerar es que las etiquetas distinguen entre mayúsculas y minúsculas (ver Tag Restrictions), por lo que Schedule y schedule no son iguales.

Etiquetado automático de las instancias arrancadas/paradas por AWS Instance Scheduler

Un detalle muy interesante de AWS Instance Scheduler es que permite etiquetar automáticamente las instancias iniciadas/detenidas. En la documentación se indica, por ejemplo:

Example Parameter Input Instance Scheduler Tag
ScheduleMessage=Started on {year}/{month}/{day} at {hour}:{minute} {timezone} ScheduleMessage=Started on 2017/07/06 at 09:00 UTC

Esto puede ayudar en aquipos en los que la administración de las instancias (o el control de costes) está separado de los usuarios finales de las instancias, de manera que sepan porqué motivo la instancia se encuentra parada, por ejemplo.

Otros parámetros interesantes de los schedules

Revisa los parámetros de los schedules porque hay algunos que permiten implementar medidas interesantes, como el enforced, el override_status o el use_maintenance_window para RDS.

Por ejemplo, estableciendo el enforced a true, AWS Instance Scheduler detendrá una instancia incluso si se arranca manualmente fuera del periodo definido. Debes recordarlo si algún día ves quieres arrancar una máquina fuera del schedule configurado y ésta se apaga una y otra vez ;)

Otra medida interesante puede ser establecer un periodo que sólo tenga endtime -desde el punto de vista de recortar gastos-, de manera que las instancias se apaguen siempre a una determinada hora, pero que no arranquen automáticamente. Esto puede ser útil en entornos de desarrollo o de test en los que las instancias se usen sólo de forma esporádica, arrancándose de forma manual o como respuesta a algún evento, para evitar que se queden arrancadas indefinidamente.

Soporte multicuenta

Hacia el final de la página sobre AWS Instance Scheduler se menciona lo que es, para mí, una de las mejores características de esta solución: ¡soporte multicuenta!

Gracias a esta característica puedes definir una serie de schedules en una cuenta y aplicarlos sobre el resto de cuentas en las que tienes instancias/RDS.

Si tienes una cuenta por equipo de desarrollo, por ejemplo, imagina el tiempo que tendrías que dedicar a configurar una y otra vez los mismos schedules

Después de haber tenido que lidiar con los problemas de dar permisos de ejecución sobre Lambdas entre diferentes cuentas, el hecho de poder contar con un CloudFormation que simplifique el proceso para AWS Instance Scheduler me parece espectacular.

Tengo todavía pendiente probarlo para ver cómo de sencillo es en la práctica, pero al revisar el fichero de CloudFormation, parece que en la cuenta secundaria sólo es necesario proporcionar el ARN del Role definido por el CloudFormation en la cuenta “principal”.

Si has elegido que el CloudFormation genere el role automáticamente, el ARN, éste tendrá la siguiente forma: arn:aws:iam::<Account>:role/<NombreStack>-SchedulerRole-<RandomAlphaNumeric>.

Resumen

AWS Instance Scheduler es una solución que permite reducir los costes -e incluso la seguridad de tu entorno- asegurando que las máquinas sólo se usan dentro de los horarios definidos.

Si buscas en YouTube, esta era una función que antes de la existencia de esta solución la gente estaba implementando de forma más o menos “casera”, por lo que disponer de un producto tan práctico y bien ejecutado es un gustazo.

¡Pruébalo y dime qué te parece!