Note
La branche principale contient actuellement l'aperçu des déploiements atomiques Alpha.
Pour la dernière version stable, consultez la branchev0.xVeuillez consulter notre article de blog "La route vers les déploiements atomiques"
Ou regardez la dernière revue de publication pour plus d'informations:
Un module Terraform zéro config pour l'auto-hébergement next.js sites sans serveur sur AWS Lambda.
Certaines fonctionnalités sont toujours en cours de développement, voici une liste des fonctionnalités actuellement prises en charge et ce que nous prévoyons d'apporter avec les prochaines versions:
v0.15+Le module Terraform suivant.js est conçu comme une application AWS complète. Il s'appuie sur plusieurs services AWS et les relie pour travailler comme une seule application:

Vous devez faire installer les outils suivants:
Remarque: De plus, nous supposons ici que vous avez déjà une zone hébergée publique53 associée à votre compte AWS.
Il s'agit d'une exigence dans la phase d'aperçu des déploiements atomiques, où chaque déploiement obtient un sous-domaine unique attribué. Il changera une fois que les déploiements atomiques seront généralement disponibles.
Le module Terraform contient le système utilisé plus tard pour créer de nouveaux déploiements et gérer les alias (domaines) pour votre ou vos applications Next.js. La création de la pile Terraform n'est requise que sur la configuration initiale et crée les ressources globales (distributions CloudFront, Tables DynamoDB, S3 Storage) qui est utilisée pour gérer les demandes entrantes à votre site Web.
Créez un nouveau fichier main.tf dans un dossier vide (ou ajoutez-le à votre pile Terraform existante) et ajoutez le contenu suivant:
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
}Pour créer les ressources dans votre compte AWS, exécutez les commandes suivantes:
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 " L' api_endpoint est utilisé plus tard par l'outil CLI pour créer de nouveaux déploiements.
Avec la stratégie api_endpoint_access_policy_arn AWS, vous pouvez créer de nouveaux utilisateurs (et attribuer cette stratégie) qui ne peut utiliser que l'outil CLI tf-next mais ne peut pas accéder à d'autres ressources à l'intérieur de votre compte AWS.
Après le déploiement réussi, votre application Next.js est accessible au public au sous-domaine CloudFront de la sortie cloudfront_domain_name .
Pour construire et déployer des applications Next.js au système, nous avons créé un outil CLI appelé tf-next .
Il s'agit d'un package NPM qui peut être installé avec:
npm i -g tf-next@canary Ensuite, nous devons construire le suivant.js afin qu'il puisse s'exécuter dans un environnement sans serveur (avec AWS Lambda). Ceci est archivé en exécutant tf-next build dans le même répertoire où se trouve votre application Next.js (là où se trouvent votre package.json ou next.config.js les fichiers):
tf-next build
> All serverless functions created in: 20.791ms
> 1752924 total bytes
> Build successful!
Déplacez maintenant l'application suivante.js en exécutant tf-next deploy à partir du même répertoire. La commande de déploiement communique via une API sécurisée (et authentifiée avec votre AWS Credentials) avec le module Terraform.
Pour indiquer à la commande où déployer l'application, un indicateur --endpoint supplémentaire doit être fourni, qui doit utiliser la valeur de la sortie api_endpoint de l'étape de l' terraform apply :
tf-next deploy --endpoint https://<api-id>.execute-api.us-west-2.amazonaws.com
> Available at: https://3edade7a2bf7bb0343699af6b851bbfa.example.com/
Le déploiement d'aperçu est désormais accessible par l'URL affichée.
Pour rendre le déploiement disponible à partir d'une URL plus lisible, vous pouvez utiliser la sous-commande tf-next alias :
tf-next alias set my-app.example.com 3edade7a2bf7bb0343699af6b851bbfa.example.com
> Available at: https://my-app.example.com/
Pour une liste complète des commandes disponibles qui peuvent être utilisées avec tf-next , vérifiez la référence de commande.
| Nom | Version |
|---|---|
| terraform | > = 0,15 |
| AWS | > = 4.8 |
| Nom | Version |
|---|---|
| AWS | > = 4.8 |
| Nom | Description | Taper | Défaut | Requis |
|---|---|---|---|---|
| cloudfront_acm_certificate_arn | Certificat ACM ARN pour Custom_domain | string | null | Non |
| cloudfront_aliases | Alias pour Custom_domain | list(string) | [] | Non |
| cloudfront_cache_key_headers | Clés d'en-tête qui doivent être utilisées pour calculer la touche de cache dans CloudFront. | list(string) | [ | Non |
| cloudfront_create_distribution | Contrôle si la distribution principale du cloudfront doit être créée. | bool | true | Non |
| cloudfront_external_arn | Lors de l'utilisation d'une distribution de front de nuage externe, fournissez son ARN. | string | null | Non |
| cloudfront_external_id | Lors de l'utilisation d'une distribution externe CloudFront, fournissez son ID. | string | null | Non |
| cloudfront_minimum_protocol_version | La version minimale du protocole SSL que vous souhaitez que CloudFront utilise pour les connexions HTTPS. L'un des SSLV3, TLSV1, TLSV1_2016, TLSV1.1_2016, TLSV1.2_2018 ou TLSV1.2_2019. | string | "TLSv1" | Non |
| cloudfront_origin_request_policy | ID d'une stratégie de demande personnalisée qui remplace la stratégie par défaut (AllViewer). Peut être personnalisé ou géré. | string | null | Non |
| cloudfront_price_class | Classe de prix pour les distributions CloudFront (configuration principale et proxy). L'un de PRICECLASS_ALL, PRICECLASS_200, PRICECLASS_100. | string | "PriceClass_100" | Non |
| cloudfront_response_headers_policy | ID d'une politique des en-têtes de réponse. Peut être personnalisé ou géré. La valeur par défaut est vide. | string | null | Non |
| cloudfront_webacl_id | Un ID Webacl2 ARN ou WebACl en option pour associer à la distribution CloudFront | string | null | Non |
| create_image_optimisation | Contrôle si les ressources pour le support d'optimisation d'image doivent être créées ou non. | bool | true | Non |
| debug_use_local_packages | Utilisez des packages construits localement plutôt que de les télécharger à partir de NPM. | bool | false | Non |
| Deployment_name | L'identifiant pour le groupe de déploiement (seuls les caractères alphanumériques minuscules et les traits de traits sont autorisés). | string | "tf-next" | Non |
| activer_multiple_deployments | Contrôle s'il devrait être possible d'exécuter plusieurs déploiements en parallèle (nécessite plusieurs_deployments_base_domain). | bool | false | Non |
| image_optimisation_lambda_memory_size | Quantité de mémoire dans MB La fonction Lambda du travailleur pour l'optimisation de l'image peut utiliser. Valeur valide entre 128 Mo et 10 240 Mo, par incréments de 1 Mo. | number | 2048 | Non |
| lambda_attach_policy_json | S'il faut déployer des politiques JSON Lambda supplémentaires. Si FALSE, LAMBDA_POLICY_JSON ne sera pas attaché à la fonction lambda. (Nécessaire car les chaînes de stratégie ne sont connues qu'après s'appliquer lors de l'utilisation de Terraforms data.aws_iam_policy_document) | bool | false | Non |
| lambda_attach_to_vpc | Réglé sur true si les fonctions lambda doivent être attachées à un VPC. Utilisez ce paramètre si les ressources VPC doivent être accessibles par les fonctions Lambda. Lorsque vous définissez ceci sur true, utilisez VPC_SECURITY_GROUP_IDS et VPC_SUBNET_IDS pour spécifier le réseau VPC. Notez que la fixation à un VPC introduirait un retard au froid démarre | bool | false | Non |
| lambda_policy_json | Document de politique supplémentaire en tant que JSON à attacher au rôle de fonction lambda | string | null | Non |
| lambda_role_permissions_boundary | ARN OF IAM POLITIQUE QUE SCOPES AWS_IAM_ROLE ACCORD POUR LAMBDA | string | null | Non |
| multiples_deployments_base_domain | Domaine générique par défaut où de nouveaux déploiements devraient être disponibles. Devrait être sous la forme de * .example.com. | string | null | Non |
| balises | Métadonnées de balises pour étiqueter les ressources AWS qui prennent en charge les balises. | map(string) | {} | Non |
| Tags_s3_bucket | Tag métadonnées pour étiqueter les seaux AWS S3. Remplace les balises avec le même nom dans les balises de variable d'entrée. | map(string) | {} | Non |
| vpc_security_group_ids | La liste des ID de groupe de sécurité à utiliser par les fonctions lambda. Lambda_attach_to_vpc doit être défini sur true pour que ceux-ci soient appliqués. | list(string) | [] | Non |
| VPC_SUBNET_IDS | La liste des ID de sous-réseau VPC pour joindre les fonctions lambda. Lambda_attach_to_vpc doit être défini sur true pour que ceux-ci soient appliqués. | list(string) | [] | Non |
| Nom | Description |
|---|---|
| api_endpoint | Point de terminaison de l'API qui est utilisé par la CLI. |
| api_endpoint_access_policy_arn | ARN de la politique qui accorde l'accès au point de terminaison de l'API. |
| cloudfront_custom_error_response | Réponse d'erreur personnalisée préconfigurée La distribution CloudFront doit être utilisée. |
| cloudfront_default_cache_behavior | Comportement de cache par défaut préconfiguré La distribution CloudFront doit être utilisée. |
| cloudfront_default_root_object | Objet racine préconfiguré que la distribution CloudFront doit être utilisée. |
| cloudfront_domain_name | Domaine de la distribution principale du cloudfront (lorsqu'elle est créée). |
| cloudfront_hosted_zone_id | ID de zone de la distribution principale du cloudfront (lorsqu'il est créé). |
| cloudfront_ordred_cache_behaviors | Comportements de cache ordonnés préconfigurés que la distribution de CloudFront devrait utiliser. |
| cloudfront_origins | Origines préconfigurées que la distribution de CloudFront devrait utiliser. |
| upload_bucket_id | n / A |
Sous le capot, ce module utilise beaucoup de pipeline de construction de Vercel. Les problèmes qui existent sur Vercel sont également susceptibles de se produire sur ce projet.
La délétion de la pile ( terraform destroy ) échoue lors de la première course (Terraform-Provider-AWS # 1721)
Ceci est intentionnel car nous ne pouvons pas supprimer une fonction lambda @ edge (utilisée par le module proxy) de manière synchrone. Il peut prendre jusqu'à une heure pour que AWS déforme une fonction lambda @ edge de sa distribution de cloudfront même lorsque la distribution est déjà détruite.
Solution:
Après avoir exécuté la commande terraform destroy initiale (qui a échoué), attendez ~ 1 heure et exécutez à nouveau la commande. Cette fois, il devrait s'exécuter avec succès et supprimer le reste de la pile.
L'application initiale échoue avec le message d'erreur Erreur Error: error creating Lambda Event Source Mapping (# 138)
Il y a une condition de course lorsque les autorisations sont créées pour le déploiement statique Lambda. Cela ne devrait se produire que lors du premier déploiement.
Solution:
Vous devriez être en mesure d'exécuter terraform apply à nouveau et la création de pile se déroulerait sans cette erreur.
Les contributions sont les bienvenues!
Si vous souhaitez améliorer ce module, veuillez consulter nos directives contributives pour commencer.
Ce projet est maintenu par Millivolt Infrastructure.
Nous créons des solutions d'infrastructure personnalisées pour tout fournisseur de cloud.
Apache-2.0 - Voir la licence pour plus de détails.
Remarque: Tous les exemples de projets dans
examples/*sont sous licence MIT pour se conformer aux exemples officiels Next.js.