ملحوظة
يحتوي الفرع الرئيسي حاليًا على عمليات النشر الذرية ALPHA معاينة.
لأحدث إصدار مستقر ، تحقق من فرعv0.xيرجى الاطلاع على منشور مدونتنا "الطريق إلى عمليات النشر الذرية"
أو شاهد أحدث مراجعة للإصدار لمزيد من المعلومات:
وحدة Terraform ذات الصفر من أجل الاستضافة الذاتية.
بعض الميزات لا تزال قيد التطوير ، إليك قائمة بالميزات المدعومة حاليًا وما نخطط لجلبه مع الإصدارات التالية:
v0.15+تم تصميم وحدة Next.js terraform كتطبيق كامل مكدس AWS. يعتمد على خدمات AWS متعددة ويربطهم بالعمل كتطبيق واحد:

يجب أن يكون لديك الأدوات التالية مثبتة:
ملاحظة: بالإضافة إلى ذلك ، نفترض هنا أن لديك بالفعل منطقة استضافة عامة ROTE53 مرتبطة بحساب AWS الخاص بك.
هذا مطلب في مرحلة المعاينة من عمليات النشر الذرية ، حيث يحصل كل نشر على نطاق فرعي فريد. سيتغير بمجرد أن تصبح عمليات النشر الذرية متاحة بشكل عام.
تحتوي وحدة Terraform على النظام الذي يتم استخدامه لاحقًا لإنشاء عمليات نشر جديدة وإدارة الأسماء المستعارة (المجالات) لتطبيقات (تطبيقات) Next.js. لا يلزم إنشاء مكدس terraform إلا عند الإعداد الأولي وإنشاء الموارد العالمية (توزيعات CloudFront ، جداول DynamoDB ، تخزين S3) التي يتم استخدامها للتعامل مع الطلبات الواردة لموقع الويب الخاص بك.
قم بإنشاء ملف main.tf جديد في مجلد فارغ (أو إضافته إلى مكدس terraform الحالي) وأضف المحتوى التالي:
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
}لإنشاء الموارد في حساب AWS الخاص بك ، قم بتشغيل الأوامر التالية:
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 " يتم استخدام api_endpoint لاحقًا بواسطة أداة CLI لإنشاء عمليات نشر جديدة.
باستخدام سياسة api_endpoint_access_policy_arn AWS ، يمكنك إنشاء مستخدمين جدد (وتعيين هذه السياسة) التي يمكنها فقط استخدام أداة CLI tf-next ولكن لا يمكنها الوصول إلى موارد أخرى داخل حساب AWS الخاص بك.
بعد النشر الناجح ، يتوفر تطبيق Next.js بشكل عام في مجال CloudFront الفرعي من إخراج cloudfront_domain_name .
لبناء ونشر تطبيقات Next.js على النظام ، أنشأنا أداة CLI تسمى tf-next .
إنها حزمة NPM يمكن تثبيتها بـ:
npm i -g tf-next@canary بعد ذلك ، نحتاج إلى إنشاء next.js حتى يمكن تشغيله في بيئة بدون خادم (مع AWS lambda). يتم أرشفة هذا عن طريق تشغيل tf-next build في نفس الدليل حيث يوجد تطبيق NEXT.JS (حيث توجد ملفات package.json أو next.config.js ):
tf-next build
> All serverless functions created in: 20.791ms
> 1752924 total bytes
> Build successful!
نشر الآن تطبيق Next.js عن طريق تشغيل tf-next deploy من نفس الدليل. يتواصل أمر النشر من خلال واجهة برمجة تطبيقات مضمونة (ومصادقة مع بيانات اعتماد AWS الخاصة بك) مع وحدة Terraform.
لإخبار الأمر بمكان نشر التطبيق ، يجب توفير علامة إضافية --endpoint توفير علامة ، والتي يجب أن تستخدم القيمة من إخراج api_endpoint من خطوة terraform apply :
tf-next deploy --endpoint https://<api-id>.execute-api.us-west-2.amazonaws.com
> Available at: https://3edade7a2bf7bb0343699af6b851bbfa.example.com/
يمكن الآن الوصول إلى نشر المعاينة بواسطة عنوان URL المعروض.
لجعل النشر متاحًا من عنوان URL أكثر قابلية للقراءة ، يمكنك استخدام tf-next alias Subormand:
tf-next alias set my-app.example.com 3edade7a2bf7bb0343699af6b851bbfa.example.com
> Available at: https://my-app.example.com/
للحصول على قائمة كاملة بالأوامر المتاحة التي يمكن استخدامها مع tf-next ، تحقق من مرجع الأمر.
| اسم | إصدار |
|---|---|
| terraform | > = 0.15 |
| AWS | > = 4.8 |
| اسم | إصدار |
|---|---|
| AWS | > = 4.8 |
| اسم | وصف | يكتب | تقصير | مطلوب |
|---|---|---|---|---|
| cloudfront_acm_certificate_arn | شهادة ACM ARN لـ Custom_domain | string | null | لا |
| cloudfront_aliases | الاسم المستعار لـ Custom_domain | list(string) | [] | لا |
| cloudfront_cache_key_headers | مفاتيح الرأس التي يجب استخدامها لحساب مفتاح ذاكرة التخزين المؤقت في CloudFront. | list(string) | [ | لا |
| cloudfront_create_distribution | يتحكم في ما إذا كان ينبغي إنشاء توزيع CloudFront الرئيسي. | bool | true | لا |
| cloudfront_external_arn | عند استخدام توزيع CloudFront الخارجي ، توفر ARN. | string | null | لا |
| cloudfront_external_id | عند استخدام توزيع CloudFront الخارجي ، توفير معرفه. | string | null | لا |
| cloudfront_minimum_protocol_version | الحد الأدنى من بروتوكول SSL الذي تريد استخدام CloudFront لاتصالات HTTPS. واحد من SSLV3 ، TLSV1 ، TLSV1_2016 ، TLSV1.1_2016 ، TLSV1.2_2018 أو TLSV1.2_2019. | string | "TLSv1" | لا |
| cloudfront_origin_request_policy | معرف سياسة الطلب المخصص التي تتجاوز السياسة الافتراضية (Allviewer). يمكن أن تكون مخصصة أو تدار. | string | null | لا |
| cloudfront_price_class | فئة السعر لتوزيعات CloudFront (Config Main & Proxy). واحدة من priceClass_all ، priceClass_200 ، priceClass_100. | string | "PriceClass_100" | لا |
| cloudfront_response_headers_policy | معرف سياسة رؤوس الاستجابة. يمكن أن تكون مخصصة أو تدار. الافتراضي فارغ. | string | null | لا |
| cloudfront_webacl_id | معرف WebACL2 ARN أو WebACL الاختياري لربطه بتوزيع CloudFront | string | null | لا |
| create_image_optimization | يتحكم في ما إذا كان ينبغي إنشاء موارد لدعم تحسين الصورة أم لا. | bool | true | لا |
| debug_use_local_packages | استخدم الحزم المبنية محليًا بدلاً من تنزيلها من NPM. | bool | false | لا |
| deployment_name | معرف لمجموعة النشر (يُسمح فقط بالأحرف الأبجدية والوصلات الأبجدية الصغيرة). | string | "tf-next" | لا |
| enable_multiple_deployments | يتحكم في ما إذا كان ينبغي أن يكون من الممكن تشغيل عمليات نشر متعددة بالتوازي (يتطلب multiployments_base_domain). | bool | false | لا |
| image_optimization_lambda_memory_size | مقدار الذاكرة في MB يمكن استخدام وظيفة Lambda العامل لتحسين الصورة. قيمة صالحة بين 128 ميغابايت إلى 10،240 ميغابايت ، بزيادات 1 ميغابايت. | number | 2048 | لا |
| lambda_attach_policy_json | ما إذا كان لن يتم نشر سياسات Lambda JSON إضافية. إذا كان خطأ ، فلن يتم إرفاق lambda_policy_json بوظيفة Lambda. (ضروري نظرًا لأن سلاسل السياسة معروفة فقط بعد تطبيقها عند استخدام بيانات terraforms.aws_iam_policy_document) | bool | false | لا |
| lambda_attach_to_vpc | تعيين إلى صحيح إذا كان ينبغي إرفاق وظائف Lambda بـ VPC. استخدم هذا الإعداد إذا كان ينبغي الوصول إلى موارد VPC بواسطة وظائف Lambda. عند تعيين هذا إلى TRUE ، استخدم vpc_security_group_ids و vpc_subnet_ids لتحديد شبكات VPC. لاحظ أن الإرفاق بـ VPC من شأنه أن يقدم تأخيرًا إلى البرد يبدأ | bool | false | لا |
| lambda_policy_json | وثيقة سياسية إضافية كـ JSON لإرفاقها بدور وظيفة Lambda | string | null | لا |
| lambda_role_permissions_boundary | Arn of IAM Policy التي يتم الوصول إلى AWS_IAM_ROLE للوصول إلى Lambda | string | null | لا |
| MOUNTION_DEPLoyments_Base_DOMAIN | مجال Wildcard الافتراضي حيث يجب أن تكون عمليات النشر الجديدة متاحة. يجب أن يكون في شكل *.example.com. | string | null | لا |
| العلامات | TAG METADATA لتسمية موارد AWS التي تدعم العلامات. | map(string) | {} | لا |
| TAGS_S3_BUCKET | وصف البيانات الوصفية لتسمية دلاء AWS S3. يتجاوز العلامات مع نفس الاسم في علامات متغير الإدخال. | map(string) | {} | لا |
| vpc_security_group_ids | قائمة معرفات مجموعة الأمان لاستخدامها من قبل وظائف Lambda. يجب ضبط Lambda_attach_to_vpc على صواب لتطبيق هذه. | list(string) | [] | لا |
| VPC_SUBNET_IDS | قائمة معرفات الشبكة الفرعية VPC لإرفاق وظائف Lambda. يجب ضبط Lambda_attach_to_vpc على صواب لتطبيق هذه. | list(string) | [] | لا |
| اسم | وصف |
|---|---|
| api_endpoint | نقطة نهاية API التي يستخدمها CLI. |
| api_endpoint_access_policy_arn | ARN من السياسة التي تمنح الوصول إلى نقطة نهاية API. |
| cloudfront_custom_error_response | استجابة خطأ مخصص تم تكوينها مسبقًا يجب أن يستخدم توزيع CloudFront. |
| CloudFront_Default_Cache_Behavior | سلوك ذاكرة التخزين المؤقت الافتراضية المسبقة التي يجب أن يستخدمها توزيع CloudFront. |
| CloudFront_Default_Root_Object | كائن الجذر المسبق لتوزيع CloudFront يجب أن يستخدمه. |
| cloudfront_domain_name | مجال توزيع CloudFront الرئيسي (عند الإنشاء). |
| cloudfront_hosted_zone_id | معرف المنطقة لتوزيع CloudFront الرئيسي (عند الإنشاء). |
| cloudfront_ordered_cache_behaviors | سلوكيات ذاكرة التخزين المؤقت المسبقة المسبقة يجب استخدامها. |
| Cloudfront_origins | الأصول المكوّنة مسبقًا يجب أن تستخدم توزيع CloudFront. |
| تحميل _bucket_id | ن/أ |
تحت الغطاء ، تستخدم هذه الوحدة الكثير من خط أنابيب بناء Vercel. لذلك من المحتمل أن تحدث القضايا الموجودة في Vercel في هذا المشروع أيضًا.
فشل حذف Stack ( terraform destroy ) في التشغيل الأول (Terraform-Provider-AWS#1721)
هذا مقصود لأنه لا يمكننا حذف وظيفة lambda@edge (تستخدمها وحدة الوكيل) بطريقة متزامنة. قد يستغرق الأمر ما يصل إلى ساعة لكي تقوم AWS بإلغاء إثارة وظيفة Lambda@Edge من توزيع CloudFront حتى عند تدمير التوزيع بالفعل.
الحل البديل:
بعد تشغيل أمر terraform destroy (الذي فشل) انتظر ~ ساعة واحدة وقم بتشغيل الأمر مرة أخرى. هذه المرة يجب أن تعمل بنجاح وحذف بقية المكدس.
يفشل التطبيق الأولي مع خطأ رسالة Error: error creating Lambda Event Source Mapping (#138)
هناك بعض حالات السباق عند إنشاء الأذونات لنشر Lambda الثابت. يجب أن يحدث هذا فقط في النشر الأول.
الحل البديل:
يجب أن تكون قادرًا على تشغيل terraform apply مرة أخرى وسيتم إنشاء إنشاء المكدس بدون هذا الخطأ.
المساهمات مرحب بها!
إذا كنت ترغب في تحسين هذه الوحدة ، فيرجى إلقاء نظرة على إرشاداتنا المساهمة للبدء.
يتم الحفاظ على هذا المشروع بواسطة البنية التحتية Millivolt.
نقوم ببناء حلول بنية تحتية مخصصة لأي مزود سحابة.
Apache -2.0 - انظر الترخيص للحصول على التفاصيل.
ملاحظة: يتم ترخيص جميع مشاريع العينة في
examples/*كمعهد ماساتشوستس للتكنولوجيا للامتثال لأمثلة Next.js الرسمية.