Sirva contenido estático en un bucket de Amazon S3 a través de una 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 una 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

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

Resumen

Cuando publicas contenido estático alojado en Amazon Web Services (AWS), el enfoque recomendado es 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 las ubicaciones periféricas y la capacidad de definir listas de control de acceso web (ACL web) 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, puede ser deseable que los dispositivos de firewall virtual se implementen 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 la 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 la VPC mediante un Application Load Balancer. A continuación, una función de Lambda de AWS recupera y devuelve el contenido del bucket 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 región de AWS, pero se pueden aprovisionar en diferentes cuentas de 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 (Amazon VPC)

  • 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 una VPC.

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

  2. CloudFront envía la solicitud a AWS WAF. AWS WAF filtra la solicitud mediante las ACL web aplicadas a la distribución. CloudFront 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 a la URL del 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 servicios y características de AWS, como CloudFront el Application Load Balancer, AWS los 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.

  • AWS Lambda es un servicio de computación que ayuda a ejecutar código sin necesidad de aprovisionar ni 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 (Amazon VPC) le permite lanzar recursos de AWS en una red virtual que haya definido. Esta red virtual es similar a la red tradicional que utiliza en su propio centro de datos, con los beneficios de usar la infraestructura escalable de AWS.

Epics

TareaDescripciónHabilidades requeridas

Cree una VPC.

Cree una VPC para alojar los recursos implementados en este patrón, como el equilibrador de carga de aplicación y la función de Lambda.  Para obtener instrucciones, consulte Crear una VPC (documentación de Amazon VPC).

Arquitecto de la nube

Cree una ACL web de AWS WAF.

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

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.

AWS general

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
AWS general

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

Cree 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 administración de AWS y abra la CloudFront consola en 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 las ACL web existentes que desee aplicar a través de AWS WAF. Para más información, consulte ACL web de AWS WAF.

  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

Documentación de AWS

Sitios web de servicios de AWS

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); } ); };