الله وكيلكم، لا أنسى تلك الليلة ما حييت. كانت ليلة خميس، قبل إطلاق ميزة جديدة ومهمة في أحد تطبيقاتنا. الفريق كله كان على أعصابه، وأنا كنت أراجع الكود للمرة المليون. في بيئة التطوير (Development) كل شيء يعمل “زي الليرة الذهب”. في بيئة الاختبار (Staging) كذلك، كل الاختبارات الآلية والبشرية نجحت بامتياز. قلوبنا اطمأنت، وقلنا “يلا يا شباب، نتوكل على الله ونطلق على الإنتاج (Production)”.
وما هي إلا دقائق بعد النشر، حتى بدأت هواتفنا ترن كأنها جرس إنذار حريق. رسائل من خدمة العملاء، تنبيهات من نظام المراقبة، الدنيا “ولّعت”. الميزة الجديدة لا تعمل، بل وتسببت في انهيار أجزاء أخرى من النظام. كيف يا جماعة؟ كانت تعمل قبل دقائق!
قضينا الساعات الثلاث التالية في حالة من الفوضى العارمة. أنا والشباب، كل واحد فينا يصرخ من جهة: “الكود نظيف!”، “الداتا بيز سليمة!”، “ما في أي خطأ باللوجز!”. قعدنا “نلطم” ونبحث عن السبب. وبعد جحيم من البحث والتدقيق، اكتشف زميلي أحمد المشكلة. يا ويلي على هالمشكلة! كانت عبارة عن متغير بيئة (Environment Variable) بسيط، تم إضافته يدويًا على سيرفر الاختبار ونسينا تمامًا أن نضيفه على سيرفرات الإنتاج. ثلاث ساعات من التوتر والضغط وخسارة السمعة أمام العملاء بسبب سطر واحد تم نسيانه.
في تلك اللحظة، نظرت إلى الفريق وقلت: “يا زلمة، لازم يكون في طريقة أحسن من هيك. شغلنا مش لازم يكون زي اللي بيبني بيت من رمل على شط البحر، كل موجة بتيجي بتخرب شكل”. هذه الحادثة كانت القشة التي قصمت ظهر البعير، وكانت بوابتنا للدخول إلى عالم “البنية التحتية ككود” (Infrastructure as Code).
ما هو جحيم “انحراف البيئات” (Environment Drift) الذي نتحدث عنه؟
ما مررنا به في تلك الليلة له اسم تقني: انحراف البيئة (Environment Drift). ببساطة، هو التباين والاختلاف الذي يحدث تدريجيًا بين بيئات العمل المختلفة (التطوير، الاختبار، الإنتاج) عندما تتم إدارتها بشكل يدوي.
تخيل أنك تملك صورة أصلية (بيئة الإنتاج)، ثم تأخذ نسخة منها (بيئة الاختبار)، ثم نسخة من النسخة (بيئة التطوير). مع كل تعديل يدوي صغير هنا وهناك “على السريع” لإصلاح مشكلة طارئة، تبدأ هذه النسخ بالتشوه والابتعاد عن بعضها. بعد أشهر، يصبح لديك ثلاث بيئات مختلفة تمامًا، مع أنك تظن أنها متطابقة. وهذا هو سبب المقولة الشهيرة التي يسمعها كل مدير تقني: “بس يا بشمهندس، كانت شغالة عندي على جهازي!”.
أشهر أسباب الانحراف:
- الإصلاحات السريعة (Hotfixes): الدخول مباشرة على سيرفر الإنتاج لتعديل ملف إعدادات أو تثبيت مكتبة بشكل عاجل. هذه التعديلات غالبًا ما تُنسى ولا تُطبق على البيئات الأخرى.
- التحديثات غير المتزامنة: تحديث إصدار لغة البرمجة (مثل Node.js) أو قاعدة البيانات في بيئة التطوير دون تحديثها في الإنتاج.
- الأخطاء البشرية: كلنا بشر، والنسيان والخطأ جزء من طبيعتنا. الاعتماد على الذاكرة البشرية والخطوات اليدوية هو وصفة أكيدة للكارثة.
- صلاحيات الوصول المختلفة: أحيانًا يكون لدى المطورين صلاحيات أوسع على بيئات التطوير، فيقومون بتثبيت أدوات أو تغيير إعدادات لا وجود لها في بيئة الإنتاج المقيدة.
المنقذ قد وصل: تقديم البنية التحتية ككود (IaC)
البنية التحتية ككود (Infrastructure as Code – IaC) هي ممارسة لإدارة وتوفير البنية التحتية لتكنولوجيا المعلومات (مثل الخوادم، قواعد البيانات، الشبكات، موازنات التحميل) من خلال ملفات تعريفية قابلة للقراءة آليًا (أي، كود)، بدلاً من الإعداد اليدوي أو استخدام الأدوات التفاعلية.
الفكرة ثورية وبسيطة في آن واحد: عامل بنيتك التحتية بنفس الطريقة التي تعامل بها كود تطبيقك.
بدلًا من دليل خطوات من 20 صفحة لتجهيز خادم جديد، أصبح لديك ملف كود واحد يقوم بكل هذا بضغطة زر.
لماذا IaC هي الحل؟
- التناسق (Consistency): الكود هو المصدر الوحيد للحقيقة. نفس الكود يُستخدم لإنشاء جميع البيئات، مما يضمن تطابقها والقضاء على مشكلة “شغالة عندي”.
- التحكم في الإصدارات (Version Control): يمكنك الآن وضع كود بنيتك التحتية في نظام Git. هذا يعني أنك تستطيع تتبع كل تغيير، معرفة من قام به ومتى، مراجعة التغييرات عبر Pull Requests، والعودة إلى إصدار سابق بسهولة إذا حدث خطأ.
- الأتمتة (Automation): يمكنك إنشاء بيئة تطوير كاملة ومعقدة أو تدميرها بأمر واحد. هذا يسرّع عملية التطوير والاختبار بشكل لا يصدق.
- التوثيق الذاتي (Self-Documentation): ملفات الكود نفسها تصبح هي التوثيق الدقيق والحيّ لبنيتك التحتية. لا مزيد من مستندات Word و Confluence القديمة والمنسية.
Terraform في الميدان: هيا بنا “نطبّق” عمليًا
هناك العديد من أدوات IaC، مثل AWS CloudFormation، و Azure Bicep، و Pulumi. لكن الأداة التي سأركز عليها اليوم، والتي كانت لها الفضل الأكبر في رحلتنا، هي Terraform من شركة HashiCorp. جمال Terraform يكمن في أنها “محايدة سحابيًا” (Cloud-Agnostic)، أي أنها تعمل مع معظم مزودي الخدمات السحابية (AWS, Azure, GCP, DigitalOcean) وغيرها الكثير.
المفاهيم الأساسية في Terraform
- Providers: هي إضافات (plugins) تسمح لـ Terraform بالتواصل مع واجهات برمجة التطبيقات (APIs) المختلفة، مثل AWS أو Azure، لإنشاء الموارد وإدارتها.
- Resources: هي مكونات البنية التحتية التي تريد إنشاءها. يمكن أن تكون خادمًا افتراضيًا (VM)، قاعدة بيانات، شبكة افتراضية، أو حتى سجل DNS.
- State File: هو ملف (عادة بامتداد
.tfstate) يحتفظ فيه Terraform بسجل للحالة الحالية للبنية التحتية التي يديرها. هذا الملف مقدس وحساس جدًا، فهو يربط الموارد الحقيقية في السحابة بالكود الخاص بك. - Variables: تسمح لك بجعل الكود الخاص بك قابلاً لإعادة الاستخدام والتخصيص دون تعديل الكود الأساسي. هذا هو مفتاح إدارة البيئات المختلفة.
مثال عملي بسيط: إنشاء خادم ويب على AWS
لنتخيل أننا نريد إنشاء خادم ويب بسيط (EC2 instance) على AWS. بدلًا من الدخول إلى واجهة AWS والضغط على 15 زرًا مختلفًا، سنكتب الكود التالي في ملف اسمه main.tf:
# main.tf
# 1. تحديد المزود (Provider) الذي سنستخدمه، وهو AWS
provider "aws" {
region = "us-east-1" # اختر المنطقة الأقرب لك
}
# 2. تحديد المورد (Resource) الذي نريد إنشاءه
# في هذه الحالة، خادم EC2
resource "aws_instance" "web_server" {
# Amazon Machine Image - نظام التشغيل الأساسي
ami = "ami-0c55b159cbfafe1f0" # هذا مثال لـ Amazon Linux 2 AMI
# نوع وحجم الخادم
instance_type = "t2.micro" # هذا النوع ضمن الطبقة المجانية لـ AWS
# وسوم (Tags) لتنظيم الموارد
tags = {
Name = "MyWebServer-From-Terraform"
Env = "development"
}
}
الآن، كل ما علينا فعله هو فتح الطرفية (Terminal) في نفس المجلد وتنفيذ ثلاثة أوامر:
terraform init: هذا الأمر يقوم بتحميل الـ provider الخاص بـ AWS وتجهيز بيئة العمل. تنفذه مرة واحدة في البداية.terraform plan: هذا الأمر يقرأ الكود ويقارنه بملف الحالة (State file) ليخبرك بما سيقوم بفعله (على سبيل المثال: “سأقوم بإنشاء خادم جديد بالمواصفات كذا وكذا”). هذه خطوة مراجعة آمنة جدًا.terraform apply: بعد مراجعة الخطة والموافقة عليها، هذا الأمر يقوم بتنفيذها فعليًا وإنشاء الخادم على AWS.
بوم! خلال دقيقة أو دقيقتين، أصبح لديك خادم جاهز، تم إنشاؤه عبر كود يمكن حفظه ومراجعته وتكراره.
كيف يحل هذا مشكلة الانحراف بين البيئات؟
الآن يأتي السحر الحقيقي. كيف نستخدم نفس الكود لبيئة التطوير والإنتاج؟ باستخدام المتغيرات (Variables)!
سنعدل الكود قليلًا ليصبح أكثر مرونة:
# variables.tf
variable "instance_type" {
description = "The type of the EC2 instance"
type = string
default = "t2.micro"
}
variable "env" {
description = "The environment name"
type = string
}
# main.tf (بعد التعديل)
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type # استخدام المتغير هنا
tags = {
Name = "WebServer-${var.env}" # استخدام المتغير هنا
Env = var.env
}
}
الآن، يمكننا إنشاء ملفين مختلفين للقيم:
ملف dev.tfvars لبيئة التطوير:
instance_type = "t2.micro"
env = "development"
وملف prod.tfvars لبيئة الإنتاج:
instance_type = "t3.large"
env = "production"
عندما نريد إنشاء بيئة التطوير، ننفذ الأمر:
terraform apply -var-file="dev.tfvars"
وعندما نريد إنشاء بيئة الإنتاج، ننفذ الأمر:
terraform apply -var-file="prod.tfvars"
لاحظتم؟ نفس الكود الأساسي، لكن بمواصفات مختلفة لكل بيئة. لقد ضمنا أن الإعدادات الأساسية (مثل نوع نظام التشغيل، إعدادات الشبكة، قواعد الجدار الناري) متطابقة 100%، بينما تختلف فقط الأمور التي نريدها أن تختلف (مثل حجم الخادم). لقد قتلنا “الانحراف” في مهده.
نصائح من “عِدّة” أبو عمر 🛠️
بعد سنوات من العمل مع IaC، تعلمت بعض الدروس بالطريقة الصعبة. اسمحوا لي أن أشارككم بعضها:
- ابدأ صغيرًا: لا تحاول تحويل كل بنيتك التحتية الحالية إلى كود دفعة واحدة. اختر خدمة جديدة أو مكونًا صغيرًا وابدأ به. ابنِ ثقتك وفهمك للأداة تدريجيًا.
- ملف الحالة (State File) مقدس: هذا أهم ملف في Terraform. إياك والعبث به يدويًا! استخدم دائمًا “الخلفية البعيدة” (Remote Backend) مثل AWS S3 bucket مع تفعيل القفل (Locking) لحفظ هذا الملف. هذا يمنع شخصين من تشغيل
applyفي نفس الوقت ويحفظ الملف من الضياع.- اجعل كودك معياريًا (Modular): تمامًا مثل البرمجة، لا تكرر نفسك (DRY). قم بتقسيم الكود إلى “وحدات” (Modules) قابلة لإعادة الاستخدام. مثلاً، وحدة لإنشاء خادم ويب، وحدة لإنشاء قاعدة بيانات. هذا يجعل الكود أنظف وأسهل في الصيانة.
- الأتمتة الكاملة هي الهدف (CI/CD): القوة الحقيقية لـ IaC تظهر عندما تدمجها في مسار التكامل والنشر المستمر (CI/CD). تخيل أن كل Pull Request على كود البنية التحتية يقوم بتشغيل
terraform planتلقائيًا، ويضع نتيجة الخطة كتعليق ليراجعها الفريق. وعند دمج الـ PR، يتم تشغيلterraform applyتلقائيًا. هذا هو عالم DevOps الحقيقي.- امنع التغييرات اليدوية تمامًا: بعد تبني IaC، يجب أن تكون هناك قاعدة صارمة: “ممنوع اللمس”. أي تغيير في البنية التحتية يجب أن يتم عبر الكود. إذا قام أحدهم بتغيير يدوي، سيكتشفه
terraform planفي المرة القادمة وسيحاول إعادة الوضع لما هو معرف في الكود. اعتبر هذا ميزة وليس خطأ.
الخلاصة: من الفوضى إلى النظام 🚀
رحلتنا من ليالي الرعب والبحث اليائس عن أخطاء غامضة إلى عالم من النظام والتحكم والهدوء كانت بفضل تبنينا لثقافة البنية التحتية ككود. لم تكن مجرد أداة جديدة تعلمناها، بل كانت نقلة نوعية في طريقة تفكيرنا وعملنا كفريق هندسي.
قد تبدو البداية صعبة، وهناك منحنى تعلم بالتأكيد. لكن صدقوني، الاستثمار في تعلم IaC اليوم هو توفير لآلاف ساعات الصداع والقلق غدًا. هو استثمار في نوم هانئ قبل إطلاق أي ميزة جديدة، وفي الثقة بأن ما يعمل في بيئة الاختبار سيعمل تمامًا كما هو في بيئة الإنتاج.
ثقوا في أخوكم أبو عمر، وابدأوا هذه الرحلة. لن تندموا أبدًا.