Nota
La rama principal actualmente contiene la vista previa de los implementaciones atómicas alfa.
Para el último lanzamiento estable, consulte la ramav0.xConsulte nuestra publicación de blog "El camino a las implementaciones atómicas"
O vea la última revisión de la versión para obtener más información:
Un módulo Terraform de config cero para los sitios de autohospedación de sí mismo. JS Sitios sin servidor en AWS Lambda.
Algunas características aún están en desarrollo, aquí hay una lista de características que actualmente son compatibles y lo que planeamos traer con los próximos lanzamientos:
v0.15+El módulo Next.js Terraform está diseñado como una aplicación completa de pila AWS. Se basa en múltiples servicios de AWS y los conecta para que funcionen como una sola aplicación:

Debe tener las siguientes herramientas instaladas:
Nota: Además, suponemos aquí que ya tiene una zona alojada de ruta pública 53 asociada con su cuenta AWS.
Este es un requisito en la fase de vista previa de las implementaciones atómicas, donde cada implementación obtiene un subdominio único asignado. Cambiará una vez que las implementaciones atómicas estén generalmente disponibles.
El módulo Terraform contiene el sistema que luego se utiliza para crear nuevas implementaciones y administrar los alias (dominios) para sus próximas aplicaciones.js. La creación de la pila de Terraform solo se requiere en la configuración inicial y crea los recursos globales (distribuciones de CloudFront, Tablas de DynamodB, S3 Storage) que se utiliza para manejar las solicitudes entrantes a su sitio web.
Cree un nuevo archivo main.tf en una carpeta vacía (o agréguelo a su pila de terraza existente) y agregue el siguiente contenido:
terraform {
required_providers {
aws = {
source = " hashicorp/aws "
version = " ~> 4.0 "
}
}
}
# Main region where the resources should be created in
# Should be close to the location of your viewers
provider "aws" {
region = " us-west-2 "
}
# Provider used for creating the Lambda@Edge function which must be deployed
# to us-east-1 region (Should not be changed)
provider "aws" {
alias = " global_region "
region = " us-east-1 "
}
# ##########
# Variables
# ##########
variable "custom_domain" {
description = " Your custom domain "
type = string
default = " example.com "
}
# Assuming that the ZONE of your domain is already available in your AWS account (Route 53)
# https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/AboutHZWorkingWith.html
variable "custom_domain_zone_name" {
description = " The Route53 zone name of the custom domain "
type = string
default = " example.com. "
}
# #######
# Locals
# #######
locals {
# A wildcard domain(ex: *.example.com) has to be added when using atomic deployments:
aliases = [ var . custom_domain , " *. ${ var . custom_domain } " ]
}
# ######################
# Route53 Domain record
# ######################
# Get the hosted zone for the custom domain
data "aws_route53_zone" "custom_domain_zone" {
name = var . custom_domain_zone_name
}
# Create a new record in Route 53 for the domain
resource "aws_route53_record" "cloudfront_alias_domain" {
for_each = toset (local . aliases )
zone_id = data . aws_route53_zone . custom_domain_zone . zone_id
name = each . key
type = " A "
alias {
name = module . tf_next . cloudfront_domain_name
zone_id = module . tf_next . cloudfront_hosted_zone_id
evaluate_target_health = false
}
}
# #########
# SSL Cert
# #########
# Creates a free SSL certificate for CloudFront distribution
# For more options (e.g. multiple domains) see:
# https://registry.terraform.io/modules/terraform-aws-modules/acm/aws/
module "cloudfront_cert" {
source = " terraform-aws-modules/acm/aws "
version = " ~> 3.0 "
domain_name = var . custom_domain
zone_id = data . aws_route53_zone . custom_domain_zone . zone_id
subject_alternative_names = slice (local . aliases , 1 , length (local . aliases ))
wait_for_validation = true
tags = {
Name = " CloudFront ${ var . custom_domain } "
}
# CloudFront works only with certs stored in us-east-1
providers = {
aws = aws.global_region
}
}
# #########################
# Terraform Next.js Module
# #########################
module "tf_next" {
source = " milliHQ/next-js/aws "
version = " 1.0.0-canary.4 "
cloudfront_aliases = local . aliases
cloudfront_acm_certificate_arn = module . cloudfront_cert . acm_certificate_arn
deployment_name = " atomic-deployments "
enable_multiple_deployments = true
multiple_deployments_base_domain = " *. ${ var . custom_domain } "
providers = {
aws.global_region = aws.global_region
}
}
# ########
# Outputs
# ########
output "api_endpoint" {
value = module . tf_next . api_endpoint
}
output "api_endpoint_access_policy_arn" {
value = module . tf_next . api_endpoint_access_policy_arn
}Para crear los recursos en su cuenta de AWS, ejecute los siguientes comandos:
terraform init # Only needed on the first time running Terraform
terraform plan # (Optional) See what resources Terraform will create
terraform apply # Create the resources in your AWS account
> Apply complete !
>
> Outputs:
>
> api_endpoint = " https://<api-id>.execute-api.us-west-2.amazonaws.com "
> api_endpoint_access_policy_arn = " arn:aws:iam::123456789012:policy/access-api " La herramienta CLI utiliza el api_endpoint para crear nuevas implementaciones.
Con la política api_endpoint_access_policy_arn AWS, puede crear nuevos usuarios (y asignar esa política) que solo puede usar la herramienta CLI tf-next pero no puede acceder a otros recursos dentro de su cuenta AWS.
Después de la implementación exitosa, su aplicación Next.js está disponible públicamente en el subdominio CloudFront desde la salida cloudfront_domain_name .
Para construir e implementar aplicaciones Next.js en el sistema, creamos una herramienta CLI llamada tf-next .
Es un paquete NPM que se puede instalar con:
npm i -g tf-next@canary A continuación, necesitamos construir el siguiente.js para que pueda ejecutarse en un entorno sin servidor (con AWS Lambda). Esto se archiva ejecutando tf-next build en el mismo directorio donde se encuentra su aplicación Next.js (justo donde se encuentran sus archivos package.json o next.config.js ):
tf-next build
> All serverless functions created in: 20.791ms
> 1752924 total bytes
> Build successful!
Ahora implementa la aplicación Next.js ejecutando tf-next deploy desde el mismo directorio. El comando de implementación se comunica a través de una API asegurada (y autenticada con sus credenciales de AWS) con el módulo Terraform.
Para decirle al comando dónde implementar la aplicación, se debe proporcionar un indicador adicional --endpoint , que debe usar el valor de la salida api_endpoint del paso terraform apply :
tf-next deploy --endpoint https://<api-id>.execute-api.us-west-2.amazonaws.com
> Available at: https://3edade7a2bf7bb0343699af6b851bbfa.example.com/
La implementación de la vista previa ahora puede acceder a la URL mostrada.
Para que la implementación esté disponible desde una URL más legible, puede usar el subcomando tf-next alias :
tf-next alias set my-app.example.com 3edade7a2bf7bb0343699af6b851bbfa.example.com
> Available at: https://my-app.example.com/
Para obtener una lista completa de comandos disponibles que se pueden usar con tf-next , verifique la referencia de comandos.
| Nombre | Versión |
|---|---|
| terraformado | > = 0.15 |
| AWS | > = 4.8 |
| Nombre | Versión |
|---|---|
| AWS | > = 4.8 |
| Nombre | Descripción | Tipo | Por defecto | Requerido |
|---|---|---|---|---|
| CloudFront_ACM_Certificate_arn | Certificado ACM ARN para Custom_Domain | string | null | No |
| Cloudfront_aliases | Alias para custom_domain | list(string) | [] | No |
| CloudFront_Cache_Key_headers | Las teclas de encabezado que deben usarse para calcular la tecla Cache en CloudFront. | list(string) | [ | No |
| CloudFront_Create_Distribution | Controla si se debe crear la distribución principal de Cloudfront. | bool | true | No |
| CloudFront_External_arn | Cuando se usa una distribución externa de Cloudfront proporciona su ARN. | string | null | No |
| CloudFront_External_id | Cuando se utiliza una distribución externa de Cloudfront, proporcione su ID. | string | null | No |
| CloudFront_Minimum_Protocol_version | La versión mínima del protocolo SSL que desea que CloudFront use para las conexiones HTTPS. Uno de SSLV3, TLSV1, TLSV1_2016, TLSV1.1_2016, TLSV1.2_2018 o TLSV1.2_2019. | string | "TLSv1" | No |
| Cloudfront_origin_request_policy | ID de una política de solicitud personalizada que anula la política predeterminada (AllViewer). Puede ser personalizado o administrado. | string | null | No |
| CloudFront_Price_Class | Clase de precios para las distribuciones de CloudFront (configuración principal y proxy). Uno de Priceclass_all, Priceclass_200, Priceclass_100. | string | "PriceClass_100" | No |
| CloudFront_Response_headers_Policy | ID de una política de encabezados de respuesta. Puede ser personalizado o administrado. El valor predeterminado está vacío. | string | null | No |
| CloudFront_WebAcl_id | Una ID de ARN o WebaCl WebAcl2 opcional para asociarse con la distribución de CloudFront | string | null | No |
| create_image_optimization | Controla si los recursos para el soporte de optimización de imágenes deben crearse o no. | bool | true | No |
| debug_use_local_packages | Use paquetes construidos localmente en lugar de descargarlos desde NPM. | bool | false | No |
| implementment_name | Identificador para el grupo de implementación (solo se permiten caracteres alfanuméricos en minúsculas y guiones). | string | "tf-next" | No |
| enable_multiple_deployments | Controla si debería ser posible ejecutar múltiples implementaciones en paralelo (requiere múltiples_deployments_base_domain). | bool | false | No |
| image_optimization_lambda_memory_size | Cantidad de memoria en MB La función Lambda de trabajadores para la optimización de imágenes puede usar. Valor válido entre 128 MB y 10,240 MB, en incrementos de 1 MB. | number | 2048 | No |
| lambda_attach_policy_json | Si implementar políticas adicionales de lambda json. Si False, Lambda_Policy_Json no se adjuntará a la función Lambda. (Necesarias ya que las cadenas de políticas solo se conocen después de aplicarse cuando se usan datos Terraforms.aws_iam_policy_document) | bool | false | No |
| lambda_attach_to_vpc | Establecer en True si las funciones Lambda deben adjuntar a un VPC. Use esta configuración si las funciones LAMBDA deben acceder a los recursos VPC. Al configurar esto en True, use VPC_Security_Group_ids y VPC_SUBNET_IDS para especificar la red VPC. Tenga en cuenta que unirse a un VPC introduciría un retraso en los inicios de frío | bool | false | No |
| lambda_policy_json | Documento de política adicional como JSON para adjuntar al rol de función Lambda | string | null | No |
| lambda_role_permissions_boundary | Política ARN de IAM que alcanza el acceso AWS_IAM_ROLE para la Lambda | string | null | No |
| múltiple_deployments_base_domain | Dominio de comodín predeterminado donde deberían estar disponibles nuevas implementaciones. Debe estar en forma de *.example.com. | string | null | No |
| etiquetas | Etiqueta metadatos para etiquetar los recursos de AWS que admiten etiquetas. | map(string) | {} | No |
| etiquetas_s3_bucket | Etiqueta metadatos para etiquetar cubos AWS S3. Anula etiquetas con el mismo nombre en las etiquetas de variables de entrada. | map(string) | {} | No |
| vpc_security_group_ids | La lista de ID de grupo de seguridad para ser utilizadas por las funciones Lambda. lambda_attach_to_vpc debe establecerse en verdadero para que se apliquen. | list(string) | [] | No |
| vpc_subnet_ids | La lista de ID de subred VPC para adjuntar las funciones Lambda. lambda_attach_to_vpc debe establecerse en verdadero para que se apliquen. | list(string) | [] | No |
| Nombre | Descripción |
|---|---|
| API_Endpoint | Punto final API que usa la CLI. |
| api_endpoint_access_policy_arn | ARN de la política que otorga acceso al punto final de la API. |
| CloudFront_Custom_Error_Response | Respuesta de error personalizada preconfigurada La distribución de CloudFront debe usar. |
| Cloudfront_default_cache_behavior | Comportamiento de caché predeterminado preconfigurado La distribución de CloudFront debe usar. |
| Cloudfront_default_root_object | Objeto de raíz preconfigurado La distribución de CloudFront debe usar. |
| CloudFront_Domain_Name | Dominio de la distribución principal de Cloudfront (cuando se crea). |
| CloudFront_Hosted_Zone_ID | ID de zona de la distribución principal de Cloudfront (cuando se crea). |
| CloudFront_Ordered_cache_Behaviors | Comportamientos de caché ordenados preconfigurados que debe usar la distribución de Cloudfront. |
| CloudFront_origins | Orígenes preconfigurados La distribución de Cloudfront debe usar. |
| cargue_bucket_id | n / A |
Debajo del capó, este módulo usa una gran cantidad de tubería de construcción de Vercel. Por lo tanto, es probable que los problemas que existen en Vercel también ocurran en este proyecto.
La deleción de la pila ( terraform destroy ) falla en la primera carrera (Terraform-Provider-AWS#1721)
Esto es intencional porque no podemos eliminar una función Lambda@Edge (utilizada por el módulo proxy) de una manera sincrónica. AWS puede tomar hasta una hora para desahogar una función Lambda@Edge de su distribución de Cloudfront incluso cuando la distribución ya está destruida.
Solución:
Después de ejecutar el comando inicial terraform destroy (que falló), espere ~ 1 hora y ejecute el comando nuevamente. Esta vez debe funcionar con éxito y eliminar el resto de la pila.
Aplicación inicial falla con el mensaje de error Error: error creating Lambda Event Source Mapping (#138)
Hay alguna condición de carrera cuando los permisos se crean para la lambda de implementación estática. Esto solo debería suceder en la primera implementación.
Solución:
Debería poder ejecutar terraform apply de nuevo y la creación de la pila continuaría sin este error.
¡Las contribuciones son bienvenidas!
Si desea mejorar este módulo, eche un vistazo a nuestras pautas contribuyentes para comenzar.
Este proyecto es mantenido por la infraestructura Millivolt.
Creamos soluciones de infraestructura personalizadas para cualquier proveedor de nubes.
Apache -2.0 - Vea la licencia para más detalles.
Nota: Todos los proyectos de muestra en
examples/*tienen licencia como MIT para cumplir con los ejemplos oficiales de Next.js.