يُحوّل هذا الدرس الختامي كل مفهوم من مفاهيم الدروس السابقة — بنية HCL، الموفرون، المتغيرات، الحالة، الخلفيات البعيدة، مصادر البيانات، الوسيطات التعريفية، والوحدات — إلى مشروع متكامل جاهز للإنتاج. ستُنشئ بنية ويب ثلاثية الطبقات على AWS: شبكة VPC مخصصة بشبكات فرعية عامة وخاصة عبر مناطق توافر متعددة، ومجموعة توسع تلقائي (ASG) من نسخ EC2 خلف موازن تحميل للتطبيقات (ALB)، مع تخزين الحالة عن بُعد في S3 ومزامنة DynamoDB. هذا هو النمط الذي تستخدمه فرق هندسة المنصات في شركات مثل Stripe وShopify وAirbnb لعملياتها السحابية الأساسية.
التمهيد مقابل الحالة المُدارة: مجلد backend-bootstrap/ هو فضاء عمل Terraform صغير منفصل يستخدم الحالة المحلية ويُشغَّل مرة واحدة فقط لكل بيئة. ينشئ دلو S3 (مع الإصدارات والتشفير) وجدول DynamoDB. بما أن هذه الموارد تحمل حالة المشروع الرئيسي، يجب ألا تُدار أبدًا من قِبل المشروع الرئيسي نفسه — تنفيذ destroy سيمحو ملف الحالة ويُوقعك في كارثة لا يمكن التعافي منها.
الخطوة الأولى — تمهيد الحالة البعيدة
قبل أن يتمكن المشروع الرئيسي من استخدام خلفية بعيدة، يجب أن تكون بنية الخلفية موجودة. هذه عملية تُنفَّذ مرة واحدة لكل بيئة. في خطوط أنابيب CI بالمؤسسات الكبيرة، تخضع هذه الخطوة لخط أنابيب "تمهيد" منفصل يستلزم موافقة SRE للتشغيل.
الخطوة الثانية — الوحدة الجذرية: الإصدارات والخلفية والمحليات
يُثبّت ملف versions.tf كل موفر في نطاق إصدار فرعي باستخدام عامل القيد المتشائم (~>). الموفرون غير المُثبَّتين هم أحد أكثر أسباب الانجراف غير المتوقع للبنية التحتية شيوعًا في المستودعات المشتركة — تشغيل terraform init -upgrade على جهاز زميل قد يسحب موفرًا يحتوي على تغيير كاسر ويُتلف بنية تحتية حقيقية إذا طُبّق التخطيط تلقائيًا.
تبني وحدة الشبكة VPC بتصميم مركزي: الشبكات الفرعية العامة تستضيف موازن التحميل وبوابات NAT، بينما تستضيف الشبكات الفرعية الخاصة نسخ EC2. كل منطقة توافر تحصل على شبكة فرعية عامة وأخرى خاصة. استخدام for_each على شريحة من قائمة مناطق التوافر يجعل الوحدة مستقلة عن عدد المناطق — تعمل مع بيئة تطوير بمنطقتين وبيئة إنتاج بثلاث، مدفوعةً بمتغير واحد فقط.
تصميم VPC بثلاث مناطق توافر: عُقد ALB وبوابات NAT في الشبكات الفرعية العامة؛ نسخ EC2 (ASG) في الشبكات الخاصة وتصل إلى الإنترنت عبر NAT فقط.
الخطوة الرابعة — وحدة الحوسبة (ALB + ASG)
تربط وحدة الحوسبة موازن التحميل في الشبكات الفرعية العامة، وقالب الإطلاق المشير إلى أحدث AMI لـ Amazon Linux 2023 عبر مصدر بيانات، ومجموعة التوسع التلقائي الممتدة على الشبكات الفرعية الخاصة. نموذج مجموعة الأمان صريح ومحدود: موازن التحميل يقبل المنفذ 443 من الإنترنت، ونسخ EC2 تقبل المنفذ 443 من مجموعة أمان موازن التحميل فقط — لا من 0.0.0.0/0 أبدًا.
خطأ إنتاجي — IMDSv1 على EC2: حذف http_tokens = "required" من قالب الإطلاق يُبقي IMDSv1 مُفعَّلًا. يمكن الوصول إلى IMDSv1 من أي عملية على النسخة، بما في ذلك ثغرات SSRF في كود التطبيق. اختراق Capital One (2019) استغل IMDS لسرقة بيانات اعتماد IAM. أَلزِم IMDSv2 دائمًا في كل قالب إطلاق. تضبط AWS الحسابات الجديدة على IMDSv2 افتراضيًا، لكن الحسابات القديمة والـ AMIs قد تبقى على IMDSv1.
الخطوة الخامسة — الوحدة الجذرية وسير العمل
تربط الوحدة الجذرية الوحدتين الفرعيتين معًا، ممررةً مخرجات الشبكة إلى مدخلات وحدة الحوسبة. كما تُصدر المخرجات الجوهرية التي تستهلكها خطوات خط أنابيب CI اللاحقة — رابط اختبار الدخان واسم ARN لموازن التحميل لإنشاء سجل DNS.
دائمًا طبّق ملف التخطيط المحفوظ في CI. تشغيل terraform apply دون -out=tfplan ثم terraform apply tfplan يعني أن Terraform تُنشئ تخطيطًا جديدًا عند التطبيق. بين مراجعة الإنسان والتطبيق، قد يُغيّر خط أنابيب آخر أو تغيير يدوي الحالة — منتجًا تطبيقًا لا يطابق ما جرى مراجعته. حفظ التخطيط بـ -out وتطبيق تلك القطعة الأثرية بالضبط هو الطريق الوحيد لضمان سلامة مراجعة التخطيط. تفرض Terraform Cloud من HashiCorp هذا كميزة سير عمل إلزامية في خطط المؤسسات.
أنماط الفشل الإنتاجية التي يجب معرفتها
بعد تشغيل عشرات من نشر الـ Terraform ستواجه أنماط فشل متكررة. معرفتها مسبقًا تحوّل حادثة منتصف الليل إلى إصلاح في عشر دقائق:
قفل الحالة غير محرَّر بعد تطبيق منقطع: شغّل terraform force-unlock <LOCK_ID> — معرف القفل يظهر في رسالة الخطأ. تحقق من أن التطبيق السابق فشل فعلًا قبل الإلغاء؛ إن اكتمل فالإلغاء آمن. إن كان تطبيق آخر يعمل فعلًا، لا تُلغِ القفل أبدًا.
انجراف الطاقة المطلوبة في ASG: إن ضبط مشغّل desired_capacity يدويًا في وحدة التحكم AWS، ستعرض terraform plan التالية فرقًا وتُعيد ضبطها. استخدم ignore_changes = [desired_capacity] في كتلة lifecycle للـ ASG إن كنت تدير الطاقة المطلوبة عبر سياسة تحجيم تلقائي منفصلة.
حد EIP لبوابة NAT: الحد الافتراضي لـ AWS هو 5 عناوين EIP لكل منطقة. البنية ذات ثلاث مناطق توافر تحتاج 3 EIPs لبوابات NAT. عبر بيئات متعددة في منطقة واحدة تصل الحد بسرعة — اطلب رفع الحصة ضمن إعداد البنية التحتية الأولي قبل أول تطبيق.
إلغاء تسجيل AMI: إن أُلغي تسجيل AMI المستخدم في قالب الإطلاق، تفشل نسخ ASG الجديدة في الإطلاق لكن النسخ القائمة لا تتأثر. الحل هو تحديث مرجع AMI في قالب الإطلاق وتشغيل تحديث النسخ. أثبّت دائمًا قوالب الإطلاق على AMIs مُدارة عبر AWS Image Builder أو Packer، لا AMIs عامة قد تُحذف.
تعارض إصدار الموفر عبر الفضاءات: زميل يشغّل terraform init -upgrade ويُدرج ملف .terraform.lock.hcl محدَّثًا بإصدار موفر جديد. يلتقطه CI في المرة التالية. قد يحتوي الموفر الجديد على تغيير كاسر لمورد تستخدمه. الحل: راجع فروق ملف lock في طلبات الدمج بالجدية ذاتها التي تراجع بها كود التطبيق.
إصدار الوحدات في البيئات الجماعية: في مشاريع الأفراد أو الفرق الصغيرة يُقبل الرجوع إلى الوحدات عبر مسارات نسبية (./modules/network). في المؤسسات الكبيرة، تُنشر الوحدات في سجل Terraform خاص أو مستودع Git بإصدارات موسومة، ويُثبّت المستدعون على إصدار دلالي: source = "git::https://github.com/acme/terraform-modules.git//network?ref=v2.3.0". يضمن هذا أن تغيير وحدة في فرع فريق لن يكسر بنية فريق آخر التحتية عند init التالية.
نستخدم ملفات تعريف الارتباط لتشغيل هذا الموقع وتحليل الزيارات وعرض إعلانات مخصّصة. يمكنك قبول كل ملفات تعريف الارتباط أو رفض غير الأساسية منها.
سياسة الخصوصية