Skip to main content

Command Palette

Search for a command to run...

Automatizando Backups EC2 con Lambda

Integrando automatización de infraestructura con Boto3, Lambda y EventBridge

Updated
6 min read
Automatizando Backups EC2 con Lambda
R

Ingeniero en Telecomunicaciones con enfoque en redes, conectividad y automatización. Actualmente estudiando AWS, DevOps y CI/CD. Comparto mi camino con proyectos prácticos y artículos técnicos desde Chile 🇨🇱.

https://robertoespana.hashnode.dev/portafolio

Continuando con mi aprendizaje con Boto3 SDK voy a crear y desplegar un script en Lambda que de manera automática se ejecute diariamente y genere una snapshot de una instancia EC2.

Para comprender de mejor manera, realicé un diagrama. Tenemos en este caso un Lambda “LambdaEC2DailySnapshot”; a esta se le asocia un rol, el cual debe tener los permisos necesarios para que la función Lambda pueda generar una snapshot de mi instancia. En tercer lugar está el encargado de ejecutar el script diariamente: EventBridge, configurado como scheduler. Este scheduler se activará cada día a una hora específica, enviando el trigger a mi Lambda, ejecutándose y realizando el snapshot de mi instancia EC2.

Para realizar esto son necesarios conocimientos previos como la manipulación de los servicios de AWS utilizando el modo resource y client, además del uso de try y except para manejo de errores, y el uso de la librería logging para integrar visibilidad al código.

El primer paso es crear la función Lambda desde la consola de AWS. Al momento de crearla, seleccionamos el runtime Python 3.12 y creamos la función. Al momento de ser creada, tendrá código sencillo que descartaremos.

Desde nuestro Visual Studio Code debemos tener instalada la extensión AWS Toolkit, además debemos configurar nuestras credenciales de acceso de nuestra cuenta. Posterior a tenerlo configurado, podremos observar todas las regiones; en mi caso trabajo con us-virginia. Desde esta región tenemos todos los servicios de nuestra cuenta. Nos dirigimos a Lambda, listamos, y podremos ver nuestra función creada desde la consola de AWS. Damos clic derecho en download, y con esto podremos trabajar con nuestro IDE de manera más sencilla y sincronizada con la nube.


Creación de Script lambda

Ahora solo debemos escribir nuestro código. En este caso importamos las librerías con las que trabajé: utilicé logging para agregar visibilidad. Primero obtenemos el logger de Python que permitirá al script escribir mensajes en CloudWatch Logs; este es un objeto responsable de manejar los logs de la aplicación.

En segundo lugar definimos el nivel al que trabajaremos, en este caso INFO, que corresponde también a: INFO, WARNING, ERROR y CRITICAL.

Entonces, cuando se ejecute alguna de estas dos líneas:
logger.info("Snapshot creada correctamente") o
logger.error("Ocurrió un error"),
Python automáticamente guardará la información dependiendo de cuál se haya ejecutado, y Lambda enviará esa información a CloudWatch Logs. Estos logs sirven para ver errores, respuestas de AWS, debugging y tiempos de ejecución.

Continuando con la explicación, el código es super sencillo. Primero utilizamos la función principal lambda_handler, dentro de esta trabajaremos. Cargamos el modo cliente de EC2 dentro de la variable ec2, además de definir una variable que contendrá la fecha gracias a la librería datetime.

Para el manejo de errores utilizamos try y except. Primero ejecutamos la función para crear la snapshot y definimos los valores necesarios, en este caso el VolumeID de nuestra instancia a la cual queremos hacer un snapshot, además de definir el nombre que debe tener esa snapshot utilizando la variable current_data, que es dinámica según el día en que se ejecute la función.

Por último ejecuto el logger en modo info, que imprime:
Snapshot creada correctamente: {json.dumps(response, default=str)}.
Recordar que la respuesta del proceso de crear la snapshot retorna datos crudos (diccionarios), por lo que para poder observarlos correctamente se setean con json.dumps, y eso es lo que se envía a CloudWatch Logs.

En la excepción, en caso de que falle, ejecuta el logger en modo error:
logger.error(f"Error creando la snapshot {str(e)}").
Esto es super importante ya que esta información la podemos ver en CloudWatch y así depurar errores.

import json
import boto3
import logging
from datetime import datetime

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')

    current_data = datetime.now().strftime("%Y-%m-%d")

    try:
        response = ec2.create_snapshot(
            Description='Snapshot EC2',
            VolumeId='string', #Aqui agregar el volumeID de la instancia 
            TagSpecifications=[
                {
                    'ResourceType': 'snapshot',
                    'Tags': [
                        {
                            'Key': 'Name',
                            'Value': current_data
                        }
                    ]
                }
            ]
        )

        logger.info(f"Snapshot creada correctamente: {json.dumps(response, default=str)}")

    except Exception as e:
        logger.error(f"Error creando la snapshot {str(e)}")

Test a nuestro script

Antes de ejecutar directamente desde la consola de AWS, es recomendable ejecutar nuestro script de manera local (ojo que igualmente interactúa con nuestros recursos). Para esto usamos SAM Local, que es como ejecutar AWS Lambda en tu máquina pero con el mismo runtime y comportamiento que tendría en AWS.

Para esto debemos tener unos archivos previos creados: un event.json (que sería el trigger real de AWS; en este caso lo dejamos vacío) y un template.yaml que contiene la información necesaria para ejecutar el test.

Ejecutamos el comando:
sam local invoke -e event.json
y podremos ver que el script se ejecuta.

Podemos confirmar si funcionó directamente desde la consola de AWS, revisando EC2 → Snapshots. Y como podemos ver, el snapshot fue creado con el nombre dinámico según el día.


Subir script a AWS

Ahora debemos volver a subir nuestro Lambda para actualizarlo. Para esto, simplemente vamos al Visual, damos clic derecho sobre la carpeta del script y seleccionamos Upload Lambda. Con esto se subirá automáticamente al environment de AWS.



Asignar rol a función lambda

El siguiente paso es definir el rol necesario para que nuestra función Lambda pueda interactuar con las snapshots de nuestra instancia. Debemos recordar que al crear la función, se genera un rol asociado sin permisos. Para configurar los permisos:

  • Vamos a la función Lambda.

  • Configuración → Permisos.

  • Entramos al rol.

  • Agregar permisos → buscamos EC2 Full Access (recordar que esto es solo para estudio; en producción debemos usar mínimo privilegio).

  • Agregar.

La función ahora tiene los permisos necesarios para realizar snapshots automáticas.



Configurar Scheduler

Ahora configuramos el scheduler, que será el encargado de ejecutar diariamente nuestro script.

Definimos un nombre.

En Schedule Pattern, dejamos que se ejecute cada 24 horas, sin flexibilidad.

En Timeframe, configuramos la hora la cual debe comenzar el conteo de las 24 horas.

Siguiente → siguiente → Create.

Y tenemos nuestro EventBridge configurado para ejecutar el Lambda cada día a las 1:30 AM.


Prueba de funcionamiento

Antes de la hora programada, revisamos en EC2 que no existen snapshots aún. Esperamos hasta las 1:30 AM.

Y como podemos ver, se creó sin problemas. Si recordamos, configuramos logging, el cual guardó toda la información del response y Lambda debió reenviarla automáticamente a CloudWatch Logs.

Entramos a Lambda → Monitor → View CloudWatch Logs.
(PD: tuve problemas porque la función Lambda estaba configurada para 3 segundos de ejecución, pero el proceso de crear snapshot dura más; lo aumenté a 15s).

Entramos al log event correspondiente a la hora, y podemos ver los eventos del log: el INFO con el response seteado en json, además del mensaje “Snapshot creada correctamente”.

Con esto doy por finalizado mi tercer proyecto utilizando Boto3. Una pincelada de cómo podemos automatizar procesos usando este potente SDK dentro de AWS.

Espero que este proyecto te sea tan útil como a mí.

Saludos.


Referencias y Enlaces