Blog de Amazon Web Services (AWS)

¿Cómo enmascarar archivos usando AWS Lambda para objetos de Amazon Simple Storage Service?

Por Rodrigo Cabrera, Arquitecto de Soluciones de AWS y
Servio Reyes, Arquitecto de Soluciones en AWS México

 

En este blogpost el objetivo es explicar cómo los clientes se pueden beneficiar de usar AWS Lambda para objetos de Amazon Simple Storage Service (Amazon S3), para así poder aprovechar sus ventajas que incluyen la reducción de costos de almacenamiento en Amazon S3, mayor nivel de seguridad al enmascarar el contenido de archivos dependiendo el usuario y el punto de acceso, y también preprocesar la información antes de la entrega para los consumidores. Simplificando el acceso a los datos almacenados para los distintos consumidores y personalizando la información que cada uno de ellos puede ver y obtener.

Amazon S3 es nuestro servicio de almacenamiento de objetos, un servicio totalmente administrado donde puedes subir cualquier tipo de objeto, con un límite de 5TB por objeto. Millones de clientes utilizan Amazon S3 para guardar archivos como lo son imágenes, documentos, videos, entre otros.

En AWS la seguridad es la principal prioridad, y existen múltiples formas de asegurar nuestros objetos que viven en Amazon S3. Un caso de estas prácticas la podemos encontrar en esta publicación, donde ahora podemos hacer diferentes entregas de objetos, según el consumidor que lo descarga. Anteriormente para conseguir esto, se tenían que subir los objetivos en múltiples ubicaciones distintas (ya sea en diferentes carpetas o cubetas de Amazon S3), separándolas dependiendo su uso o acceso, requiriendo múltiples copias.

Caso de Uso

Ejemplificando el caso anterior, tenemos un archivo con información sensible de nuestros clientes, y cada área de negocio tiene diferente interés sobre el contenido de ese archivo. El área operativa quiere explotar la información geográfica de sus clientes, el área de marketing quiere información como edad, género, el área de contact center quiere tener información de contacto con sus clientes, etc. Quedando el diagrama de arquitectura como el siguiente:

 

 

Ya que Amazon S3 se cobra por almacenamiento al tener varias copias del mismo archivo (en diferentes cubetas), podemos incurrir en costos innecesarios. Además de un posible problema de sincronización de datos en el caso que alguna actualización no sea exitosa en todas las cubetas.

Lambda para objetos de Amazon S3, es una capacidad que te permite agregar tu propio código de procesamiento para la recuperación de datos de Amazon S3, antes de llegar a tu aplicación, utilizando funciones AWS Lambda para procesarlos automáticamente. Esta función de AWS Lambda es invocada de la misma forma que una petición tipo GET de Amazon S3, así que no hay necesidad de modificar el código de tu aplicación. Siguiendo el ejemplo anterior de este blog, la nueva arquitectura con la función Lambda para objetos de Amazon S3 se vería así:

 

 

Además de ayudar a los clientes a enmascarar sus archivos, podemos usar la función Lambda para insertar información extra de una base de datos o de un backend. También podemos pensar en un escenario donde tenemos imágenes exclusivas para suscriptores, y los no suscriptores se les agrega una marca de agua, por medio de una función. Siendo posible de desplegar estas funcionalidades por medio de la consola webAWS CLIAWS SDK’s y AWS Serverless Application Model (SAM).

Costo de AWS Lambda para objetos de Amazon S3

Con AWS Lambda para objetos de Amazon S3 pagas el cómputo de la invocación de la función y las peticiones GET que le haces a la cubeta de Amazon S3. Para más información de costos visita nuestro sitio de costo de Amazon S3 y costo de AWS Lambda.

Ejemplo práctico

Objetos de Amazon S3. Para su elaboración se necesita una cuenta activa de AWS, experiencia creando roles en AWS Identity Access Management (IAM), creación de funciones AWS Lambda, creación y subida de documentos a Amazon S3. Todos los recursos creados en este tutorial deberán estar en la región us-east-1.

  1. Creamos una cubeta de Amazon S3, a la cual subimos un documento CSV con el siguiente contenido
Nombre, Direccion, Miembro Prime, Tarjeta de credito
Rodrigo Carera, Tiburcio Sanchez de la Baqrquera 101, Si, 49570298475290800
Juan Perez, Barranca 123, Si, 49570298475290800
Yun Andraca, Mi casa, Si, 49570298475290800
Moro Soe, TU CASA, No, 49570298475290800
Antorcha Corporativa, Pinon 100, No, 49570298475290800
Tela Viv, Delia 20, Si, 49570298475290800
Abece Dario, Circuito Economista 20, Si, 49570298475290800
Poquito Paquito, Merced Gomez 22, No, 49570298475290800
Benito Doque, Periferico 01, No, 49570298475290800
Andres Lopez, Juan Tinoco 21, No, 49570298475290800
Porquito Parquito, Izcapuzalco 0, No, 49570298475290800
Batito Paredes, Acapulco 123, No, 49570298475290800
Bonito Pescado, Calzada de las Brujas 21, Si, 49570298475290800
  1. En la consola de AWS IAM creamos un rol para AWS Lambda con nombre LambdaS3Objeto con la siguiente política:
  2. {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "AllowObjectLambdaAccess",
                "Action": [
                    "s3-object-lambda:WriteGetObjectResponse"
                ],
                "Effect": "Allow",
                "Resource": "*"
            },
            {
                "Effect": "Allow",
                "Action": [
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                ],
                "Resource": "*"
            }
        ]
    }
  3. Creamos una función AWS Lambda, con las siguientes características:
    1. Nombre de función: LambdaS3Objeto
    2. Ambiente de ejecución: Python 3.9
    3. Con un rol existente: LambdaS3Objeto (el que creamos anteriormente)
  4. Agregamos el siguiente código a la función
import boto3
import urllib3

def lambda_handler(event, context):
    object_get_context = event["getObjectContext"]
    request_route = object_get_context["outputRoute"]
    request_token = object_get_context["outputToken"]
    s3_url = object_get_context["inputS3Url"]

    # Obtenemos el archivo de Amazon S3 
    http = urllib3.PoolManager()
    response = http.request('GET', s3_url)
    original_object = response.data.decode('utf-8')
    
    # Transformamos el archivo
    lines = original_object.splitlines()
    transformed_object = [lines[0]]
    hidden_address = "*"*23
    hidden_card = "*"*18
    for line in lines[1:]:
        data = line.split(',')
        name = data[0]
        prime = data[2]
        transformed_object.append(f"{name}, {hidden_address}, {prime}, {hidden_card}")
    
    # Escribimos el nuevo objeto a la funcion Lambda para regresarlo
    s3 = boto3.client('s3')
    s3.write_get_object_response(
        Body="\n".join(transformed_object),
        RequestRoute=request_route,
        RequestToken=request_token)
  1. Guardamos y desplegamos la función.
  2. Clic en la pestaña de Configuración.

 

 

  1. Clic en la sección lateral que dice Configuración General y después en Editar.

 

 

  1. En la pantalla de Editar configuración básica, buscamos la sección de tiempo de espera y lo cambiamos a 1 minuto. Y clic en Guardar. Este parámetro representa el tiempo máximo de ejecución de la función.

 

 

  1. Ahora vamos a generar una función AWS Lambda para objetos de Amazon S3 desde nuestra consola. Con la finalidad que se personalice la descarga del documento CSV subido en el primer paso, enmascarando ciertos campos. Primero tenemos que generar un Punto de acceso de la cubeta donde vivirá nuestro archivo. Estando en la consola, en el servicio de Amazon S3, damos clic en Puntos de Acceso:
  2. En la siguiente pantalla clic en Crear punto de acceso del objeto Lambda. 

  3. Asignamos un nombre al punto de acceso: pa-s3-lambda.Vinculamos con la cubeta creada anteriormente, seleccionamos la opción de origen de red: Internet. Dejando el resto de la configuración con los valores de defecto. Y clic en el botón Crear punto de acceso en la parte inferior de la pantalla. 

  4. Con este punto de acceso, ahora podemos crear nuestro Punto de acceso del objeto Lambda. En la consola de Amazon S3 clic en Puntos de acceso del objeto Lambda: 

     

  5. En la siguiente pantalla clic en Crear puntos de acceso del objeto Lambda. 

     

  6. En la siguiente pantalla asignamos el nombre del punto de acceso, y en la sección de Punto de acceso de apoyo, vinculamos el punto de acceso previamente creado para la cubeta de Amazon S3. 

     

  7. En la sección de Función Lambda, introducimos el ARN de la función AWS Lambda que va a hacer la transformación del objeto (creada previamente). 

    Nota: Puede seleccionar soporte para arreglo de bytes, y Part Number lo que nos ayuda al manejo de re intentos ya que podemos obtener una parte específica del objeto en la petición GET, para obtener más detalles sobre esta funcionalidad puede visitar este enlace. Podrá agregar un Payload (opcional) para siempre enviarlo a la función Lambda invocada desde ese Punto de Acceso. Y también podrá agregar una política (como en cualquier Punto de Acceso de Amazon S3) para proveer acceso granular a los usuarios.

  8. Dejamos el resto de la configuración con los valores por defecto y clic en Crear punto de acceso del objeto Lambda.
  9. Probando nuestra función AWS Lambda para objetos de Amazon S3 desde la consola. Podemos ir a nuestro Punto de acceso del objeto Lambda que creamos en el paso anterior, lo seleccionamos y veremos los archivos que actualmente se encuentran en nuestro bucket. Seleccionamos el archivo a probar y clic en descargar: 

  10. Si la configuración fue exitosa, el descargar nos abrirá una nueva página mostrando el archivo de respuesta procesado siguiendo un formato CSV: 

 

Conclusión

En este blogpost se demostró cómo es posible utilizar AWS Lambda para objetos de Amazon S3 para un caso en particular sobre obtención de archivos, el cual puede ser extendido a otros tipos de escenarios dependiendo sus necesidades. Siendo otros ejemplos la transformación al vuelo de un archivo en otro formato, comprimir o descomprimir archivos de guardados en Amazon S3, cambiar el tamaño o agregar marcas de agua imágenes, o incluso enriquecer los archivos con más datos de otras fuentes. Usando las funciones de AWS Lambda para objetos de Amazon S3, se pueden hacer accesos granulares de diferentes archivos incluyendo la capacidad de hacer modificaciones en la descarga de los datos sin tener que alterar el archivo origen.

 


Sobre los autores

Rodrigo Cabrera es arquitecto de soluciones de AWS.

 

 

 

 

 

Servio Reyes es arquitecto de soluciones en AWS México.

 

 

 

 

 

Sobre los revisores

Diego Olivera Weinberger es arquitecto de soluciones en AWS México. Cuenta con más de 15 años de experiencia en la industria.

 

 

 

 

Carlos Landaeta cuenta con más de 15 años de experiencia en infraestructura de TI y se desempeña como Arquitecto de Soluciones para clientes del sector empresarial en AWS México.