Sirva contenido estático en un bucket de Amazon S3 a través de un VPC mediante Amazon CloudFront - Recomendaciones de AWS

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Sirva contenido estático en un bucket de Amazon S3 a través de un VPC mediante Amazon CloudFront

Creada por Angel Emmanuel Hernandez Cebrian

Entorno: PoC o piloto

Tecnologías: entrega de contenido; redes; seguridad, identidad y conformidad; sin servidor; aplicaciones web y móviles

AWSservicios: Amazon CloudFront; Elastic Load Balancing (ELB); AWS Lambda

Resumen

Al publicar contenido estático alojado en Amazon Web Services (AWS), se recomienda utilizar un depósito de Amazon Simple Storage Service (S3) como origen y utilizar CloudFront Amazon para distribuir el contenido. Esta solución tiene dos ventajas principales: la comodidad de almacenar en caché el contenido estático en ubicaciones periféricas y la posibilidad de definir listas de control de acceso web (webACLs) para la CloudFront distribución, lo que le ayuda a proteger las solicitudes de contenido con una configuración y una sobrecarga administrativa mínimas.

Sin embargo, el enfoque estándar recomendado tiene una limitación arquitectónica común. En algunos entornos, es recomendable implementar dispositivos de firewall virtuales en una nube privada virtual (VPC) para inspeccionar todo el contenido, incluido el contenido estático. El enfoque estándar no dirige el tráfico a través de ella VPC para su inspección. Este patrón proporciona una solución arquitectónica alternativa. Se sigue utilizando una CloudFront distribución para ofrecer contenido estático en un bucket de S3, pero el tráfico se enruta a través de él VPC mediante un Application Load Balancer. A continuación, una función AWS Lambda recupera y devuelve el contenido del depósito de S3.

Requisitos previos y limitaciones

Requisitos previos 

  • Una cuenta de AWS activa.

  • Contenido estático del sitio web alojado en un bucket de S3.

Limitaciones

  • Los recursos de este patrón deben estar en una sola AWS región, pero se pueden aprovisionar en cuentas diferentes. AWS

  • Los límites se aplican al tamaño máximo de solicitud y respuesta que la función de Lambda puede, respectivamente, recibir y enviar. Para obtener más información, consulte Límites en Funciones de Lambda como destinos (documentación de Elastic Load Balancing).

  • Al usar este enfoque, es importante encontrar un buen equilibrio entre el rendimiento, la escalabilidad, la seguridad y la rentabilidad. A pesar de la alta escalabilidad de Lambda, si el número de invocaciones simultáneas de Lambda supera la cuota máxima, algunas solicitudes se limitarán. Para más información, consulte las cuotas de Lambda (documentación de Lambda). También debe tener en cuenta los precios de uso de Lambda. Para minimizar las invocaciones a Lambda, asegúrese de definir correctamente la caché de la distribución. CloudFront Para obtener más información, consulte Optimización del almacenamiento en caché y la disponibilidad (documentación)CloudFront .

Arquitectura

Pila de tecnología de destino

  • CloudFront

  • Amazon Virtual Private Cloud (AmazonVPC)

  • Equilibrador de carga de aplicación

  • Lambda

  • Amazon S3

Arquitectura de destino

La siguiente imagen muestra la arquitectura sugerida cuando es necesario utilizarla CloudFront para servir contenido estático desde un bucket de S3 a través de unVPC.

Flujo de tráfico a través de los balanceadores de carga de aplicaciones en VPC la función Lambda.
  1. El cliente solicita la CloudFront distribución para incluir un archivo URL de sitio web concreto en el bucket de S3.

  2. CloudFront envía la solicitud a AWSWAF. AWSWAFfiltra la solicitud mediante la web ACLs aplicada a la CloudFront distribución. Si se determina que la solicitud es válida, el flujo continúa. Si se determina que la solicitud no es válida, el cliente recibe un error 403.

  3. CloudFront comprueba su caché interna. Si hay una clave válida que coincida con la solicitud entrante, el valor asociado se devuelve al cliente como respuesta. Si no es así, el flujo continúa.

  4. CloudFront reenvía la solicitud al URL Application Load Balancer especificado.

  5. El equilibrador de carga de aplicación tiene un oyente asociado a un grupo objetivo basado en una función de Lambda. El equilibrador de carga de aplicación invoca la función de Lambda.

  6. La función de Lambda se conecta al bucket de S3, realiza una operación GetObject en él y devuelve el contenido como respuesta.

Automatizar y escalar

Para automatizar la implementación de contenido estático mediante este enfoque, cree procesos de CI/CD para actualizar los buckets de Amazon S3 que alojan sitios web.

La función de Lambda escala automáticamente para gestionar las solicitudes concurrentes, dentro de las cuotas y limitaciones del servicio. Para obtener más información, consulte Escalado de función de Lambda y Cuotas de Lambda (documentación de Lambda). Para los demás AWS servicios y funciones, como CloudFront Application Load Balancer, los AWS escala automáticamente.

Herramientas

  • Amazon CloudFront acelera la distribución de tu contenido web al distribuirlo a través de una red mundial de centros de datos, lo que reduce la latencia y mejora el rendimiento.

  • Elastic Load Balancing (ELB) distribuye el tráfico entrante de aplicaciones o redes entre varios destinos. En este patrón, se emplea un equilibrador de carga de aplicación, aprovisionado mediante Elastic Load Balancing, para dirigir el tráfico a la función de Lambda.

  • AWSLambda es un servicio informático que le ayuda a ejecutar código sin necesidad de aprovisionar o administrar servidores. Ejecuta el código solo cuando es necesario y amplía la capacidad de manera automática, por lo que solo pagará por el tiempo de procesamiento que utilice.

  • Amazon Simple Storage Service (Amazon S3) es un servicio de almacenamiento de objetos basado en la nube que le ayuda a almacenar, proteger y recuperar cualquier cantidad de datos.

  • Amazon Virtual Private Cloud (AmazonVPC) le ayuda a lanzar AWS recursos en una red virtual que haya definido. Esta red virtual se parece a una red tradicional que utilizaría en su propio centro de datos, con las ventajas de utilizar la infraestructura escalable que ofreceAWS.

Epics

TareaDescripciónHabilidades requeridas

Cree unVPC.

Cree un VPC para alojar los recursos desplegados en este patrón, como el Application Load Balancer y la función Lambda.  Para obtener instrucciones, consulta Crear un VPC (VPCdocumentación de Amazon).

Arquitecto de la nube

Crea una AWS WAF webACL.

Crea una AWS WAF webACL. Más adelante en este patrón, se aplica esta web ACL a la CloudFront distribución. Para obtener instrucciones, consulte Creación de una web ACL (AWSWAFdocumentación).

Arquitecto de la nube

Crear la función de Lambda.

Cree la función de Lambda que sirva el contenido estático alojado en el bucket de S3 como sitio web. Use el código que se proporciona en la sección de Información adicional de este patrón. Personalice el código para identificar su bucket de S3 de destino.

General AWS

Cargar la función de Lambda.

Introduzca el siguiente comando para cargar el código de la función de Lambda en un archivo .zip en Lambda.

aws lambda update-function-code \ --function-name \ --zip-file fileb://lambda-alb-s3-website.zip
General AWS

Cree un Equilibrador de carga de aplicación.

Cree un equilibrador de carga de aplicación con acceso a Internet que apunte a la función de Lambda. Para obtener instrucciones, consulte Crear un grupo de destino para la función de Lambda (documentación de Elastic Load Balancing). Para una configuración de alta disponibilidad, cree el equilibrador de carga de aplicación y adjúntelo a subredes privadas en distintas zonas de disponibilidad.

Arquitecto de la nube

Crea una CloudFront distribución.

Cree una CloudFront distribución que apunte al Application Load Balancer que creó.

  1. Inicie sesión en la consola de AWS administración y abra la CloudFront consola en la versión https://console.aws.amazon.com/cloudfront/v3/home.

  2. Seleccione Create Distribution (Crear distribución).

  3. En la primera página del Create Distribution Wizard (Asistente de creación de distribuciones), en la sección Web, elija Get Started (Empezar).

  4. Especifique la configuración de su distribución. Para obtener más información, consulte Valores que especifica cuando crea o actualiza una distribución. Tenga en cuenta lo siguiente:

    1. Establezca el equilibrador de carga de aplicación como origen.

    2. En la configuración de distribución, elija la web ACLs existente a través de la cual desee realizar la solicitud. AWS WAF Para obtener más información, consulte la AWSWAFweb ACL.

  5. Guarde los cambios.

  6. Una CloudFront vez creada la distribución, el valor de la columna Estado de la distribución cambia de InProgressa Implementada. Si decidió habilitar la distribución, estará lista para procesar solicitudes cuando el estado cambie a Deployed (Implementado).

Arquitecto de la nube

Recursos relacionados

AWSdocumentación

AWSsitios web de servicios

Información adicional

Código

El siguiente ejemplo de función de Lambda está escrito en Node.js. Esta función de Lambda actúa como un servidor web que realiza una operación GetObject en un bucket de S3 que contiene los recursos del sitio web.

/** * This is an AWS Lambda function created for demonstration purposes. * It retrieves static assets from a defined Amazon S3 bucket. * To make the content available through a URL, use an Application Load Balancer with a Lambda integration. * * Set the S3_BUCKET environment variable in the Lambda function definition. */ var AWS = require('aws-sdk'); exports.handler = function(event, context, callback) { var bucket = process.env.S3_BUCKET; var key = event.path.replace('/', ''); if (key == '') { key = 'index.html'; } // Fetch from S3 var s3 = new AWS.S3(); return s3.getObject({Bucket: bucket, Key: key}, function(err, data) { if (err) { return err; } var isBase64Encoded = false; var encoding = 'utf8'; if (data.ContentType.indexOf('image/') > -1) { isBase64Encoded = true; encoding = 'base64' } var resp = { statusCode: 200, headers: { 'Content-Type': data.ContentType, }, body: new Buffer(data.Body).toString(encoding), isBase64Encoded: isBase64Encoded }; callback(null, resp); } ); };