Revista Tecnología

Cómo programar snapshots de Instancias EC2 con Lambda en AWS

Publicado el 30 noviembre 2015 por Dbigcloud @dbigcloud

Sigo mi andadura con AWS, pensando en el sistema de backups para las instancias EC2, he echado en falta en la consola de AWS, un sistema programado de snapshots, en el que establecer ventanas y realizar diferentes políticas, algo que a día de hoy no entiendo que no esté disponible. Existen diferentes compañías que a través del Marketplace de AWS venden software de backups, con soluciones bastante potentes, en mi caso he decidido darle una "vuelta de tuerca" y usar componentes del mismo AWS para programar mis backups, so voy a explicar cómo.

esquema Snapshot Lambda Por DBigCloud

Todo el que este familiarizado con AWS, sabe que dispone un potente SDK que a través de CLI o con diferentes lenguajes de programación podemos crear tareas programadas con las que interactuar con los propios componentes de AWS. Hasta hace no mucho era usual que Administradores de sistemas, en instancias, programasen a través de crontab, scripts hechos en CLI para la realización de backups de los volúmenes de instancias EC2.

Hace ya más de un año que AWS presentó Lambda, un sistema capaz de ejecutar tareas (que hayamos programado) en respuesta a eventos, ya sean operaciones realizadas sobre componentes de AWS o bien programaciones periódicas. Si tenemos un componente que es capaz de ejecutar código de forma programada, ¿Por qué no usarlo para programar nuestros snapshots? Quizás no todo el mundo sea consciente de lo potente de este componente de AWS, por lo que os voy a explicar cómo poder realizar dicha tarea con él. Con lambda podemos programar en Python, Node.js y Java, por lo que si tenéis algún script de backup para AWS, quizás podáis reutilizarlo, yo el script que he realizado está hecho con Python.

A partir de aquí para poder comprender está entrada debemos conocer lo siguiente sobre AWS.

  • Cómo crear una IAM Policy
  • Cómo crear un Rol usando una IAM Policy
  • Cómo establecer tags a las instancias EC2.
  • Crear una Lambda.

Crear la IAM Policy

Cómo todo componente de AWS es necesario establecer unos permisos para poder interactuar entre los demás componentes, en este ejemplo necesitamos tener permisos para que Lambda interactue con EC2, por ello que es necesario crear una policy, la cual he llamado CreateSnapshot, de la siguiente forma: 

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["logs:*"],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": "ec2:Describe*",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateSnapshot",
        "ec2:ModifySnapshotAttribute",
        "ec2:ResetSnapshotAttribute"
      ],
      "Resource": ["*"]
    }
  ]
}

En la siguiente imagen podéis ver la creación de la policy.

create policy por DBigCloud

Ahora lo siguiente va a ser crear el Rol al que le vamos a asignar esta policy, de esta forma Lambda tendra los permisos para interactuar con EC2, también con CloudWatch por si queremos ver a través de los log las operaciones realizadas.  Cuando creéis el Rol aseguraros que seleccionáis como tipo de rol Lambda.

create Rol AWS porDBigCloud

De esta forma ya tenemos un rol creado que vamos a usar con Lambda. Para usar el script que va a realizar las snapshots de los volúmenes de las instancias EC2, debemos tener en cuenta lo siguiene: usa la librería boto3, con la cual podemos hacer casi cualquier cosa a través de Python en AWS, el script se encarga de buscar instancias EC2 con una etiqueta especifica, en este caso yo la he llamado Backup, da igual el valor que contenga dicha etiqueta.

Instance Tag AWS por AWS

Así cualquier instancia EC2 que tenga dicha etiqueta será usada por el script, para la realización de los snapshots he añadido información adicional a la descripción indicando la fecha en la que se realiza el snapshot, el nombre y el ID de la instancia al que pertenece el volumen. El Script es el siguiente:

import boto3
from datetime import date

#Return dateBackup
BackupDate = date.today()
ec = boto3.client('ec2')

#Return TagName Value
def TagName(i):
    for tag in i:
        if tag[u'Key']=='Name':
            return tag[u'Value']

def lambda_handler(event,context):
    reservations = ec.describe_instances(
            Filters=[
                {'Name': 'tag-key', 'Values': ['backup', 'Backup']},
            ]
        )['Reservations']
    
    instances = sum(
        [
            [i for i in r['Instances']]
            for r in reservations
        ], [])

    for instance in instances:
        InstanceName=TagName(instance['Tags'])
        for dev in instance['BlockDeviceMappings']:
            if dev.get('Ebs', None) is None:
                # skip non-EBS volumes
                continue
            vol_id = dev['Ebs']['VolumeId']
            print "Found EBS volume %s on instance %s" % (
                vol_id, instance['InstanceId'])
            #Create Snapshot
            ec.create_snapshot(
                VolumeId=vol_id,
                Description='Backup done '+ str(BackupDate) +' Instance ' + InstanceName + ' : ' + instance['InstanceId']
            )

El script lo podéis descargar desde el repositorio de GitHub de DBigCloud. Ahora ya podemos crear la Lambda en el que añadiremos el código del Script.

lambda aws por DbigCloud

Acordaros que tenéis que seleccionar el Role que hemos creado anteriormente, una vez creada la Lambda debemos añadir un Event Source en el cual debemos especificar el tipo Scheduled Event y añadir la expresión de cuando queremos que se ejecute, en mi caso he añadido que se ejecute de Lunes a Viernes a las 23 horas, una cosa importante es que tenemos que tener en cuenta el sistema de horario de AWS, por lo que posiblemente no coincidan nuesto horario local con el de AWS.

ProgramacionSnapShots

Una vez creado el Evento Source, ya solo queda esperar a la ventana que hemos indicado para comprobara que los snapshots se realizan de forma periódica.

snapshot creado en AWS por DBigCloud

Una cosa que tenemos que tener en cuenta de estos snapshots de los volumenes, es que son ejecutados en caliente por lo que no serían validos por ejemplo para instancias de base de datos o de cualquier otro tipo que estén constantemente haciendo uso de operaciones de escritura, ya que podrían ser inconsistentes.

También debemos saber las Lambdas son facturadas por blosques de milisegundos, así que hay que tener cuidado con el código que ejecutamos, aunque entra dentro de la capa gratuita por lo que podéis probar Lambda sin problemas.

Mencionar que la versión inicial del script ha sido obtenida desde el blog serverlesscode.com y yo la he adaptado a mis necesidades, en dicha web también tenéis un script para expirar snapshots. Espero que os sea de utilidad.



Volver a la Portada de Logo Paperblog