Configurando AWS Batch
Published: 2023-07-14 05:03:06

En este tutorial se creará un sencillo ejemplo del uso de AWS Batch. Nuestra aplicación consistirá en tomar un frame (imagen) desde un video procesado. En este caso usaremos Batch sobre Fargate, crearemos una imagen docker que se encargará de compilar la aplicación y AWS Batch se encargará de tener el ambiente de ejecución listo y realizar el job.

Tomaremos como ejemplo este código sencillo en Python:

```
import boto3
import cv2
import os
import logging

# Configuración de logging
logging.basicConfig(level=logging.INFO)

# Variables de entorno
INPUT_URL = os.getenv('INPUT_URL')
OUTPUT_BUCKET = os.getenv('OUTPUT_BUCKET')

s3_client = boto3.client('s3')

def download_video(input_url):
    logging.info('Descargando video...')
    cap = cv2.VideoCapture(input_url)
    if not cap.isOpened():
        logging.error('No se pudo abrir el video.')
        return None
    return cap

def process_video(cap):
    logging.info('Procesando video...')
    # Aquí debes incluir tu propio código de procesamiento de video.
    # Por ahora, simplemente leemos el primer frame del video.
    ret, frame = cap.read()
    if not ret:
        logging.error('No se pudo leer el video.')
        return None
    # Guardamos el frame como una imagen JPEG.
    cv2.imwrite('/tmp/frame.jpg', frame)
    return '/tmp/frame.jpg'

def upload_to_s3(file_path, bucket_name):
    logging.info('Subiendo archivo a S3...')
    with open(file_path, 'rb') as data:
        s3_client.upload_fileobj(data, bucket_name, os.path.basename(file_path))

def main():
    cap = download_video(INPUT_URL)
    if cap is None:
        return
    output_file = process_video(cap)
    if output_file is None:
        return
    upload_to_s3(output_file, OUTPUT_BUCKET)

if __name__ == '__main__':
    main()

```
Creamos el Dockerfile

```
FROM python:3.8

WORKDIR /app

COPY . .

RUN pip install boto3 opencv-python-headless

CMD ["python", "./script.py"]

```
Creamos la imagen con el comando Docker

```
docker build -t myimage .

```
Nos autenticamos con ECR, previamente habiendo configurado nuestro AWS profile para ejecución de comandos por AWS cli y habiendo creado el repositorio ECR en la consola.

```
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin [your-id-account].dkr.ecr.us-east-1.amazonaws.com
```
Tageamos la imagen creada y hacemos push sobre ECR

```
docker tag videoprocess:latest [your-id-account].dkr.ecr.us-east-1.amazonaws.com/repo_videoprocess:latest
```

```
docker push [your-id-account].dkr.ecr.us-east-1.amazonaws.com/repo_videoprocess:latest
```

Y obtenemos lo siguiente:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c0xdl35lvsr8etxizuqy.png)

Antes de configurar AWS Batch explicaré como se relacionan ciertos conceptos que posteriormente configuraremos:

- Jobs: Un trabajo es la unidad de trabajo, como un script o una aplicación, que se envía a AWS Batch para que se ejecute en un entorno de cálculo. Cada trabajo se define con una definición de trabajo y se envía a una cola de trabajo.

- Job definitions: Una definición de trabajo es una serie de parámetros que AWS Batch utiliza para ejecutar un trabajo. Esta definición especifica la imagen de Docker a utilizar, el número de vCPUs y la cantidad de memoria, entre otros parámetros. En esencia, la definición del trabajo es una "plantilla" que se utiliza para ejecutar uno o varios trabajos. Por lo tanto, un trabajo se basa en una definición de trabajo.

- Job queues: Una cola de trabajo es un lugar donde se envían los trabajos para ser ejecutados. Cada cola de trabajo se asocia con uno o más entornos de cálculo y tiene una prioridad asignada. AWS Batch utiliza estas prioridades para determinar el orden en el que se deben ejecutar los trabajos. Por lo tanto, un trabajo es enviado a una cola de trabajo, y desde allí AWS Batch lo asigna a un entorno de cálculo.

- Compute environments: Un entorno de cálculo es un conjunto de recursos de cálculo, como instancias de EC2 o AWS Fargate, que se utilizan para ejecutar trabajos. Los trabajos en una cola de trabajo se ejecutan en uno de los entornos de cálculo asociados con la cola de trabajo. Cada entorno de cálculo define el tipo de recursos que se deben utilizar (CPU, memoria, etc.) y otras configuraciones, como la VPC en la que se deben ejecutar los trabajos.

---

Entonces configuremos

Compute Environment:

a. Inicia sesión en la consola de AWS y abre la consola de AWS Batch.

b. En el panel de navegación, elige 'Compute environments', luego 'Create'.

c. En la página 'Create compute environment', proporciona los detalles del entorno de computación, como el nombre, el tipo de servicio (administrado o no administrado), y los detalles del tipo de instancia.

d. Especifica la VPC, las subredes y las políticas de seguridad que quieras que tenga tu Compute Environment.

e. Si se necesita, configura el límite de vCPU y el tipo de instancias a utilizar.

f. Elige 'Create' para crear el entorno de computación.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c16dhmc4nqkqmnu8s36g.png)


Job Definition:

a. En la consola de AWS Batch, elige 'Job definitions', luego 'Create'.

b. En la página 'Create job definition', proporciona los detalles de la definición del trabajo, como el nombre, la imagen de Docker a utilizar, los volúmenes a montar, la cantidad de vCPU y memoria que el trabajo necesita, y el comando a ejecutar.

c. Asegúrate de especificar cualquier otra configuración necesaria para tu trabajo, como variables de entorno, roles de IAM (mandatorio crear roles que permitan acceso a S3), etc.

d. Para nuestro caso usaremos 2 variables de entorno. El primero es el URL de nuestro video que subimos previamente a un S3 y el segundo el nombre del bucket donde guardaremos la imagen luego de haberse procesado nuestro código en batch.

- INPUT_URL	https://s3-awsbatch.s3.amazonaws.com/158980+(Original).mp4
- OUTPUT_BUCKET	s3-awsbatch

d. Elige 'Create' para crear la definición del trabajo.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttn733bq1na6cuip6arb.png)


Job Queue:

a. En la consola de AWS Batch, elige 'Job queues', luego 'Create'.

b. En la página 'Create job queue', proporciona los detalles de la cola de trabajo, como el nombre, la prioridad y los entornos de computación a los que los trabajos pueden ser enviados.

c. Elige 'Create' para crear la cola de trabajo.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxuvxbs9aqgdx5j48m1k.png)

Ejecutaremos el job desde AWS cli

```
aws batch submit-job --job-name batch-job --job-queue video-processing-queue --job-definition video-processing-definition

```

---

Resultado:

Nuestra imagen en S3


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dw7x6rd8xdp8nd3ojwf1.png)

Podemos revisar tambien el resultado de los logs del job se pueden encontrar en la pestaña logging luego de ubicar nuestro job en la opción Jobs en el panel izquierdo de la consola


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dts9q2d0iw29d102uniq.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c0o3l7y9fh1ytpjjbauk.png)

---
¡Felicidades! Has navegado con éxito a través del proceso de creación de una aplicación de procesamiento de video escalable utilizando AWS Batch y Docker. Comenzaste con la definición de tu propósito: procesar un video utilizando un script de Python. Luego, creaste una imagen Docker que contiene tu script y todas sus dependencias, garantizando así la portabilidad y la reproducibilidad de tu entorno de ejecución. Después de eso, configuraste AWS Batch con gran detalle, estableciendo una definición de trabajo, un entorno de computación y una cola de trabajos. Todo este proceso te permitió tener una solución robusta y flexible, capaz de manejar no sólo un solo trabajo, sino potencialmente miles de ellos simultáneamente. 

Como reto podrías modificar el código y generar cientos de imágenes del contenido de tu video.