هيكلة Terraform على نطاق واسع
هيكلة Terraform على نطاق واسع
في شركة ناشئة صغيرة، يمكنك الاكتفاء بملف main.tf واحد وملف حالة (state) مشترك. لكن حين يصل عدد المهندسين إلى 50 موزعين على 10 فرق منتجات تدير ستة حسابات AWS، ينهار هذا النهج في غضون أسابيع: تعارض في قفل الحالة، وأعطال بنطاق تدمير واسع، وحوادث مناوبة ناجمة عن فريق خاطئ يلمس الموارد الخاطئة. تُعلّمك هذه الدرس تخطيط المستودع، وفصل البيئات، واستراتيجية الحالة المتعددة الطبقات التي تعتمدها كبرى شركات التقنية للحفاظ على سلامة تغييرات البنية التحتية وإمكانية مراجعتها واستقلالية الفرق فيها.
القيد الجوهري: نطاق التدمير
كل قرار هيكلي في Terraform على نطاق واسع ينبثق من سؤال واحد: إذا حدث خطأ في هذا terraform apply، ما أقصى ضرر ممكن؟ وحدة جذرية (root module) أحادية تدير الشبكات وصلاحيات IAM وقواعد البيانات وKubernetes في ملف حالة واحد يمكنها تعطيل الإنتاج بخطأ واحد في count. العلاج هو عزل الحالة — تقسيم البنية التحتية إلى طبقات، حيث كل طبقة وحدة جذرية منفصلة بـ backend خاص بها.
terraform apply واحد. صمّم طبقاتك بحيث يؤثر فقدان أي ملف حالة على نطاق منطقي واحد فقط، مثل موارد حوسبة تطبيق واحد، لا VPC كامل.
نموذج الطبقات الثلاث
يقسّم النمط المعياري الصناعي البنية التحتية إلى ثلاث طبقات تُطبَّق من الأسفل للأعلى. كل طبقة تقرأ فقط مخرجات الطبقات الأدنى منها — لا أفقياً ولا للأعلى.
تكشف الطبقات الأدنى عن مخرجاتها — معرّفات VPC، معرّفات الشبكات الفرعية، نقاط نهاية الكلاسترات — عبر terraform_remote_state أو (الأفضل على النطاق الواسع) نمط مخزن المعاملات / SSM، بحيث لا تحتاج فرق التطبيقات إلى الوصول لملف حالة الطبقة الأساسية أبداً.
Monorepo مقابل Polyrepo
كلا النموذجين يعمل. القرار تنظيمي لا تقني.
- Monorepo — كل Terraform في مستودع واحد، مجلدات لكل طبقة وبيئة. ممتاز لسهولة الاكتشاف والتغييرات الذرية عبر الطبقات. يتطلب قواعد CODEOWNERS قوية ومشغّلات CI لكل مسار لمنع تغيير في
layer1/من تشغيل خطة لكل وحدة تطبيقية. - Polyrepo — كل طبقة (أو فريق) يمتلك مستودعه الخاص. حدود أمنية طبيعية: فرق المنتجات حرفياً لا ترى HCL الطبقة الأساسية. يصعب تتبع التبعيات عبر الطبقات. شائع في الشركات الكبيرة التي تمتلك ملكية أمنية وامتثالية منفصلة للبنية التحتية الأساسية.
تخطيط Monorepo القياسي
التخطيط أدناه محكم إنتاجياً عبر مئات بيئات AWS. كل مسار مقصود:
استراتيجيات فصل البيئات
ثمة ثلاثة مناهج لفصل البيئات في Terraform. فهم المقايضات يمنع عمليات ترحيل مكلفة لاحقاً.
- مجلد لكل بيئة (كما هو موضح أعلاه) — كل بيئة وحدة جذرية منفصلة في مجلدها بـ
backend.tfو.tfvarsالخاصين بها. هذا الأسلوب الأكثر أماناً وصراحة. لا يمكنك تطبيق إعداد staging على الإنتاج عن طريق الخطأ. التكلفة: بعض التكرار في HCL تحدّه الوحدات المشتركة. - Workspaces — وحدة جذرية واحدة، مساحات عمل متعددة، ملف حالة واحد لكل مساحة. تناسب البيئات الصغيرة المتطابقة فعلاً (dev/test). تنهار حين تتباين البيئات: أحجام instances مختلفة، شبكات فرعية مختلفة، نطاقات DNS مختلفة. تجنّب استخدامها للإنتاج/staging على نطاق واسع.
- حسابات منفصلة — المعيار الذهبي وفق AWS Well-Architected للصناعات المنظّمة. الإنتاج والـ staging والـ sandbox وأدوات الأمان تعيش في حسابات AWS منفصلة مرتبطة تحت AWS Organizations. كل حساب له وحدة layer1 جذرية خاصة به.
terraform destroy مُشغَّل ضد staging مع ملف حالة مشترك أفضى إلى حذف قواعد بيانات RDS للإنتاج في شركات متعددة. عزل الحالة غير قابل للتفاوض. مفتاح backend واحد = بيئة واحدة.
إعداد الـ Backend على نطاق واسع
على نطاق واسع، تُعدّ كل فريق بـ S3 backend مع ثلاثة متطلبات غير قابلة للتنازل: التحكم في الإصدارات، التشفير، وقفل DynamoDB. يجب أن يُشفّر مفتاح الـ backend اسم الطبقة والخدمة والبيئة ليكون ملف الحالة موصوفاً بنفسه:
يتفوق نمط SSM على terraform_remote_state للاستهلاك عبر الفرق لأنه يفصل الوصول لملف الحالة عن استهلاك القيمة. فريق الأساسيات يكتب المخرجات في SSM؛ فرق التطبيقات تقرأ من SSM. لا تحتاج فرق التطبيقات لأي صلاحيات IAM على bucket S3 الخاص بالأساسيات، ويمكن لفريق الأساسيات إعادة هيكلة بنيته الداخلية دون تغيير عقود مفاتيح SSM.
CODEOWNERS وتشغيل CI لكل مسار
لا تفرض بنية المجلدات حدود الفرق إلا إذا نفّذها نظام CI/CD أيضاً. الإعداد الجاهز للإنتاج يجمع:
.github/CODEOWNERS—layer1/يتطلب موافقة@infra-platform؛layer3-apps/payments-api/يتطلب@team-payments.- مشغّلات CI لكل مسار — GitHub Actions
on.push.pathsأو Atlantis حتى تُشغَّلterraform planفقط للوحدات الجذرية المتأثرة في كل PR. - قواعد الفرع المحمي — لا دفع مباشر لـ
main؛ نتيجة الخطة تُنشر تعليقاً على PR؛terraform applyيعمل فقط بعد الدمج على مُشغِّل CI، لا من جهاز كمبيوتر مطوّر في الإنتاج أبداً.
terraform apply من جهاز كمبيوتر مطوّر ضد الإنتاج أبداً. يجب أن تحتفظ مُشغّلات CI ببيانات اعتماد الإنتاج؛ المطورون يمتلكون فقط أدوار القراءة التي تسمح بـ terraform plan. هذه السياسة الواحدة تمنع أكثر فئات حوادث الإنتاج الناجمة عن الخطأ البشري شيوعاً.
أنماط الفشل الشائعة
في هذه المرحلة ترتكب الفرق عادةً ثلاثة أخطاء هيكلية:
- الوحدة الإلهية (God module) — وحدة واحدة تنشئ كل شيء. يأخذ استدعاء
module.app80 مدخلاً ويدير 400 مورد. إعادة هيكلته في منتصف الطريق مشروع جراحة حالة يمتد لأسابيع. تفكيك مبكراً أساسي. - معرّفات الحسابات المُضمَّنة في الوحدات المشتركة — يجب ألا تشير الوحدات المشتركة أبداً لمعرّفات حسابات محددة أو نصوص مناطق. مرّرها كمتغيرات. وحدة تحتوي على
123456789012مُضمَّن يستحيل إعادة استخدامها عبر الحسابات. - غياب قفل الحالة — مهندسان يشغّلان
terraform applyفي آنٍ واحد، يكتب الثاني فوق حالة الأول، وتفقد تتبع الموارد التي يعرفها Terraform. دائماً أعدّ جدول DynamoDB للقفل. تكلفته لا تُذكر وتمنع تلف الحالة الكارثي.
التخطيط والانضباط المُرسَيان هنا هما الأساس الذي يقوم عليه باقي هذا البرنامج التعليمي: مساحات العمل، والوحدات المتقدمة، والاختبارات، وTerragrunt — كلها تفترض أنك تمتلك بالفعل فصلاً نظيفاً للطبقات وحالة معزولة لكل بيئة.