|
Con S3 Object Lambda, puede usar su propio código para procesar los datos recuperados de Amazon S3 a medida que se devuelven a una aplicación. Con el tiempo, agregamos nuevas capacidades a S3 Object Lambda, como la posibilidad de agregar su propio código a las solicitudes de la API S3 HEAD y LIST, además de la compatibilidad con las solicitudes S3 GET que estaba disponible en el lanzamiento.
Hoy estamos lanzando alias para puntos de acceso S3 Object Lambda. Los alias ahora se generan automáticamente cuando se crean los puntos de acceso Lambda de objetos de S3 y son intercambiables con los nombres de depósito en cualquier lugar donde use un nombre de depósito para acceder a los datos almacenados en Amazon S3. Por lo tanto, sus aplicaciones no necesitan conocer S3 Object Lambda y pueden considerar el alias como un nombre de depósito.
Ahora puede utilizar un alias de punto de acceso Lambda de objeto de S3 como origen de su distribución de Amazon CloudFront para adaptar o personalizar los datos para los usuarios finales. Puede usar esto para implementar el cambio de tamaño de imagen automático o para etiquetar o anotar contenido a medida que se descarga. Muchas imágenes todavía usan formatos más antiguos como jpeg o PNGy puede usar una función de transcodificación para entregar imágenes en formatos más eficientes como WebP, GBPo HEIC. Las imágenes digitales contienen metadatos y puede implementar una función que elimine los metadatos para ayudar a satisfacer los requisitos de privacidad de datos.
Veamos cómo funciona esto en la práctica. Primero, mostraré un ejemplo simple usando texto que puede seguir simplemente usando la Consola de administración de AWS. Después de eso, implementaré un caso de uso más avanzado procesando imágenes.
Uso de un punto de acceso de S3 Object Lambda como origen de una distribución de CloudFront
Para simplificar, estoy usando la misma aplicación en la publicación de inicio que cambia todo el texto del archivo original a mayúsculas. Esta vez, utilizo el alias del punto de acceso Lambda del objeto S3 para configurar una distribución pública con CloudFront.
Sigo los mismos pasos que en la publicación de lanzamiento para crear el punto de acceso S3 Object Lambda y la función Lambda. Debido a que los tiempos de ejecución de Lambda para Python 3.8 y versiones posteriores no incluyen el requests
módulo, actualizo el código de función para usar urlopen
desde el Biblioteca estándar de Python:
import boto3
from urllib.request import urlopen
s3 = boto3.client('s3')
def lambda_handler(event, context):
print(event)
object_get_context = event['getObjectContext']
request_route = object_get_context['outputRoute']
request_token = object_get_context['outputToken']
s3_url = object_get_context['inputS3Url']
# Get object from S3
response = urlopen(s3_url)
original_object = response.read().decode('utf-8')
# Transform object
transformed_object = original_object.upper()
# Write object back to S3 Object Lambda
s3.write_get_object_response(
Body=transformed_object,
RequestRoute=request_route,
RequestToken=request_token)
return
Para probar que esto funciona, abro el mismo archivo desde el depósito y a través del punto de acceso de S3 Object Lambda. En la consola S3, selecciono el depósito y un archivo de muestra (llamado s3.txt
) que subí anteriormente y elijo Abierto.
Se abre una nueva pestaña del navegador (es posible que deba deshabilitar el bloqueador de ventanas emergentes en su navegador) y su contenido es el archivo original con texto en mayúsculas y minúsculas:
Amazon Simple Storage Service (Amazon S3) is an object storage service that offers...
yo elijo Objeto Puntos de acceso Lambda en el panel de navegación y seleccione la región de AWS que usé antes en el menú desplegable. Luego, busco el punto de acceso S3 Object Lambda que acabo de crear. Selecciono el mismo archivo que antes y elijo Abierto.
En la nueva pestaña, el texto ha sido procesado por la función Lambda y ahora está todo en mayúsculas:
AMAZON SIMPLE STORAGE SERVICE (AMAZON S3) IS AN OBJECT STORAGE SERVICE THAT OFFERS...
Ahora que el punto de acceso de S3 Object Lambda está configurado correctamente, puedo crear la distribución de CloudFront. Antes de hacer eso, en la lista de puntos de acceso Lambda de objeto S3 en la consola S3, copio el Objeto Alias de punto de acceso de Lambda que se ha creado automáticamente:
En la consola de CloudFront, elijo Distribuciones en el panel de navegación y luego Crear distribución. En el Dominio de origen, utilizo el alias del punto de acceso Lambda del objeto S3 y la región. La sintaxis completa del dominio es:
ALIAS.s3.REGION.amazonaws.com
Los puntos de acceso de S3 Object Lambda no pueden ser públicos, y utilizo el control de acceso de origen (OAC) de CloudFront para autenticar las solicitudes en el origen. Para Acceso de origenYo selecciono Configuración de control de acceso de origen y elige Crear ajuste de control. Escribo un nombre para la configuración de control y selecciono Firmar solicitudes y S3 en el Tipo de origen desplegable.
Ahora mi Configuración de control de acceso de origen use la configuración que acabo de crear.
Para reducir la cantidad de solicitudes que pasan por S3 Object Lambda, habilito Escudo de origen y elige el más cercano Región del escudo de origen a la región que estoy usando. Luego, selecciono el CachingOptimized
política de caché y crear la distribución. A medida que se implementa la distribución, actualizo los permisos para los recursos utilizados por la distribución.
Configuración de permisos para utilizar un punto de acceso Lambda de objeto de S3 como origen de una distribución de CloudFront
En primer lugar, el punto de acceso de S3 Object Lambda debe dar acceso a la distribución de CloudFront. En la consola de S3, selecciono el punto de acceso de S3 Object Lambda y, en el permisos pestaña, actualizo la política con lo siguiente:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3-object-lambda:Get*",
"Resource": "arn:aws:s3-object-lambda:REGION:ACCOUNT:accesspoint/NAME",
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:cloudfront::ACCOUNT:distribution/DISTRIBUTION-ID"
}
}
}
]
}
El punto de acceso compatible también debe permitir el acceso a CloudFront cuando se lo llama a través de S3 Object Lambda. Selecciono el punto de acceso y actualizo la política en el permisos pestaña:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "s3objlambda",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:REGION:ACCOUNT:accesspoint/NAME",
"arn:aws:s3:REGION:ACCOUNT:accesspoint/NAME/object/*"
],
"Condition": {
"ForAnyValue:StringEquals": {
"aws:CalledVia": "s3-object-lambda.amazonaws.com"
}
}
}
]
}
El depósito S3 debe permitir el acceso al punto de acceso de soporte. Selecciono el cubo y actualizo la política en el permisos pestaña:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "*",
"Resource": [
"arn:aws:s3:::BUCKET",
"arn:aws:s3:::BUCKET/*"
],
"Condition": {
"StringEquals": {
"s3:DataAccessPointAccount": "ACCOUNT"
}
}
}
]
}
Finalmente, CloudFront debe poder invocar la función Lambda. En la consola Lambda, elijo la función Lambda utilizada por S3 Object Lambda y luego, en el Configuración pestaña, yo elijo permisos. En el Declaraciones de políticas basadas en recursos sección, elijo Agregar permisos y seleccione Cuenta de AWS. Entro en un único ID de estado de cuenta. Entonces, entro cloudfront.amazonaws.com
como Principal y seleccione lambda:InvokeFunction
desde el Acción menú desplegable y Ahorrar. Estamos trabajando para simplificar este paso en el futuro. Actualizaré esta publicación cuando esté disponible.
Prueba de la distribución de CloudFront
Cuando se implementó la distribución, pruebo que la configuración funciona con el mismo archivo de muestra que usé antes. En la consola de CloudFront, selecciono la distribución y copio el Nombre de dominio de distribución. Puedo usar el navegador y entrar https://DISTRIBUTION_DOMAIN_NAME/s3.txt
en la barra de navegación para enviar una solicitud a CloudFront y obtener el archivo procesado por S3 Object Lambda. Para obtener rápidamente toda la información, uso rizo con el -i
opción para ver el estado HTTP y los encabezados en la respuesta:
¡Funciona! Como era de esperar, el contenido procesado por la función Lambda está todo en mayúsculas. Dado que esta es la primera invocación de la distribución, no se ha devuelto desde la memoria caché (x-cache: Miss from cloudfront
). La solicitud pasó por S3 Object Lambda para procesar el archivo usando la función Lambda que proporcioné.
Intentemos la misma solicitud de nuevo:
Esta vez, el contenido se devuelve desde la caché de CloudFront (x-cache: Hit from cloudfront
), y S3 Object Lambda no procesó más. Al usar S3 Object Lambda como origen, la distribución de CloudFront ofrece contenido que ha sido procesado por una función de Lambda y se puede almacenar en caché para reducir la latencia y optimizar los costos.
Cambiar el tamaño de las imágenes con S3 Object Lambda y CloudFront
Como mencioné al principio de esta publicación, uno de los casos de uso que se pueden implementar con S3 Object Lambda y CloudFront es la transformación de imágenes. Vamos a crear una distribución de CloudFront que pueda cambiar el tamaño de una imagen dinámicamente pasando el ancho y el alto deseados como parámetros de consulta (w
y h
respectivamente). Por ejemplo:
Para que esta configuración funcione, necesito hacer dos cambios en la distribución de CloudFront. Primero, creo una nueva política de caché para incluir parámetros de consulta en la clave de caché. En la consola de CloudFront, elijo Políticas en el panel de navegación. En el Cache pestaña, yo elijo Crear política de caché. Luego, ingreso un nombre para la política de caché.
En el Configuración de consultas del Configuración de claves de cachéselecciono la opción de Incluya los siguientes parámetros de consulta y añadir w
(para el ancho) y h
(para la altura).
Entonces, en el Comportamientos pestaña de la distribución, selecciono el comportamiento predeterminado y elijo Editar.
Ahí actualizo el Clave de caché y solicitudes de origen sección:
- En el Política de cachéutilizo la nueva política de caché para incluir el
w
yh
parámetros de consulta en la clave de caché. - En el Política de solicitud de origenutilizar el
AllViewerExceptHostHeader
política administrada para reenviar parámetros de consulta al origen.
Ahora puedo actualizar el código de la función Lambda. Para cambiar el tamaño de las imágenes, esta función utiliza el Almohada módulo que debe empaquetarse con la función cuando se carga en Lambda. Puede implementar la función mediante una herramienta como la CLI de AWS SAM o el CDK de AWS. En comparación con el ejemplo anterior, esta función también maneja y devuelve errores HTTP, como cuando no se encuentra contenido en el depósito.
import io
import boto3
from urllib.request import urlopen, HTTPError
from PIL import Image
from urllib.parse import urlparse, parse_qs
s3 = boto3.client('s3')
def lambda_handler(event, context):
print(event)
object_get_context = event['getObjectContext']
request_route = object_get_context['outputRoute']
request_token = object_get_context['outputToken']
s3_url = object_get_context['inputS3Url']
# Get object from S3
try:
original_image = Image.open(urlopen(s3_url))
except HTTPError as err:
s3.write_get_object_response(
StatusCode=err.code,
ErrorCode="HTTPError",
ErrorMessage=err.reason,
RequestRoute=request_route,
RequestToken=request_token)
return
# Get width and height from query parameters
user_request = event['userRequest']
url = user_request['url']
parsed_url = urlparse(url)
query_parameters = parse_qs(parsed_url.query)
try:
width, height = int(query_parameters['w'][0]), int(query_parameters['h'][0])
except (KeyError, ValueError):
width, height = 0, 0
# Transform object
if width > 0 and height > 0:
transformed_image = original_image.resize((width, height), Image.ANTIALIAS)
else:
transformed_image = original_image
transformed_bytes = io.BytesIO()
transformed_image.save(transformed_bytes, format="JPEG")
# Write object back to S3 Object Lambda
s3.write_get_object_response(
Body=transformed_bytes.getvalue(),
RequestRoute=request_route,
RequestToken=request_token)
return
Subo una foto que tomé del fuente de Trevi en el depósito de origen. Para empezar, genero una miniatura pequeña (200 por 150 píxeles).
https://DISTRIBUTION_DOMAIN_NAME/trevi-fountain.jpeg?w=200&h=150
Ahora, pido una versión un poco más grande (400 por 300 píxeles):
Funciona como se esperaba. La función Lambda procesa la primera invocación con un tamaño específico. Las solicitudes adicionales con el mismo ancho y alto se atienden desde la caché de CloudFront.
Disponibilidad y precios
Los alias para los puntos de acceso de S3 Object Lambda están disponibles hoy en todas las regiones comerciales de AWS. No hay costo adicional para los alias. Con S3 Object Lambda, usted paga por los cargos de solicitud y cómputo de Lambda necesarios para procesar los datos, y por los datos que S3 Object Lambda devuelve a su aplicación. También paga por las solicitudes de S3 que invoca la función de Lambda. Para obtener más información, consulte Precios de Amazon S3.
Los alias ahora se generan automáticamente cuando se crea un punto de acceso de S3 Object Lambda. Para los puntos de acceso de S3 Object Lambda existentes, los alias se asignan automáticamente y están listos para usar.
Ahora es más fácil usar S3 Object Lambda con aplicaciones existentes y los alias abren muchas posibilidades nuevas. Por ejemplo, puede usar alias con CloudFront para crear un sitio web que convierta el contenido en Reducción a HTML, cambia el tamaño y las marcas de agua de las imágenes, o enmascara la información de identificación personal (PII) de texto, imágenes y documentos.
Personalice el contenido para sus usuarios finales mediante S3 Object Lambda con CloudFront.
— Danilo