كتابة أول ملف Terraform لإنشاء سيرفر (VPS) سحابي برمجياً

دقائق القراءة: 6

كتابة أول ملف Terraform لإنشاء سيرفر (VPS) سحابي برمجياً

عندما يصل الفريق إلى مرحلة إنشاء الخوادم يدوياً من لوحة التحكم، تبدأ الأخطاء المتكررة بالظهور: اختلاف الإعدادات بين البيئات، نسيان فتح منفذ، اختيار صورة نظام خاطئة، أو حذف مورد مهم دون توثيق. هنا يظهر دور البنية التحتية ككود (IaC): لماذا يجب أن نتخلى عن إنشاء السيرفرات يدوياً؟، حيث تتحول البنية السحابية من نقرات عشوائية إلى ملفات قابلة للمراجعة والتتبع والإعادة.

أداة Terraform ليست مجرد وسيلة لإنشاء VPS، بل هي طبقة هندسية تسمح لك بوصف البنية السحابية كاملة بصيغة يمكن مراجعتها عبر Git، دمجها مع CI/CD، وتطبيقها بشكل متسق في كل مرة. وإذا كنت قد أتممت مقال تثبيت Terraform وربطه مع مزود خدمة سحابي (AWS أو DigitalOcean) عبر الـ API فهذه هي الخطوة العملية التالية.

لماذا نبدأ بإنشاء سيرفر واحد برمجياً؟

السيرفر الأول هو أفضل نموذج لفهم فلسفة Declarative Infrastructure. بدلاً من القول للأداة: “نفّذ هذه الأوامر خطوة خطوة”، أنت تصف الحالة النهائية المطلوبة، مثل اسم الخادم، المنطقة، الحجم، ونظام التشغيل، ثم تتولى الأداة حساب الفروقات وتطبيقها.

هذه الفكرة مهمة جداً لأن نفس النمط لاحقاً سيتوسع إلى شبكات خاصة VPC، أقراص تخزين، موازنات حمل Load Balancer، وقواعد جدار حماية. أي أن فهم ملف بسيط اليوم يوفر أساساً معمارياً صلباً لمشاريع أكبر غداً.

مكونات أول مشروع Terraform

أبسط مشروع عملي يتكون غالباً من ملفات قليلة، لكن كل ملف يحمل وظيفة دقيقة داخل دورة حياة البنية:

  • ملف main.tf لتعريف provider والموارد.
  • ملف variables.tf لفصل القيم القابلة للتغيير عن المنطق.
  • ملف terraform.tfvars لتمرير القيم الفعلية.
  • ملف outputs.tf لعرض معلومات مثل IP العام بعد الإنشاء.

هذا الفصل مهم لأنه يجعل المشروع قابلاً لإعادة الاستخدام. لاحقاً يمكنك تشغيل نفس القالب لإنشاء بيئة staging وبيئة production مع تغيير القيم فقط.

مثال عملي: إنشاء VPS على DigitalOcean

سنستخدم مثالاً بسيطاً لإنشاء Droplet، لأن بنيته التعليمية واضحة. الفكرة نفسها تنطبق على مزودات أخرى مثل AWS EC2 أو Vultr.

1) ملف تعريف المتغيرات

variable "do_token" {}
variable "server_name" {}
variable "region" {
  default = "fra1"
}
variable "size" {
  default = "s-1vcpu-1gb"
}
variable "image" {
  default = "ubuntu-22-04-x64"
}
variable "ssh_key_ids" {
  type = list(string)
}

هنا قمنا بتحويل القيم الحساسة والمتغيرة إلى متغيرات مستقلة. هذا يمنع تكرار الأكواد، ويسهّل حقن القيم من بيئات مختلفة أو من أنظمة أتمتة مثل مقدمة في GitHub Actions: كتابة أول مسار عمل (Workflow).

2) ملف الموارد الرئيسي

terraform {
  required_providers {
    digitalocean = {
      source  = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

provider "digitalocean" {
  token = var.do_token
}

resource "digitalocean_droplet" "web" {
  name     = var.server_name
  region   = var.region
  size     = var.size
  image    = var.image
  ssh_keys = var.ssh_key_ids

  tags = ["terraform", "web", "vps"]
}

في هذا الملف توجد ثلاثة عناصر جوهرية:

  1. تعريف مزود الخدمة عبر required_providers.
  2. تكوين الاتصال بالمزود باستخدام API Token.
  3. تعريف المورد الفعلي وهو السيرفر.

لاحظ أن وصف السيرفر هنا لا يحتوي على أوامر تثبيت Nginx أو إعداد المستخدمين. هذا لأن Terraform ممتاز في إنشاء الموارد، بينما التهيئة الداخلية يفضّل أن تُدار لاحقاً عبر ما هو Ansible؟ وكيف تتحكم في 100 سيرفر Linux من حاسوبك المكتبي؟.

3) ملف القيم الفعلية

do_token    = "YOUR_DIGITALOCEAN_TOKEN"
server_name = "prod-web-01"
ssh_key_ids = ["12345678"]

عملياً لا يُنصح برفع هذا الملف إلى المستودع إذا كان يحتوي أسراراً. الأفضل تمرير القيم الحساسة من متغيرات بيئة أو من أنظمة أسرار مثل إدارة الأسرار (GitHub Secrets) لحماية كلمات المرور ومفاتيح الـ API في الأتمتة.

4) إظهار عنوان السيرفر بعد الإنشاء

output "server_ip" {
  value = digitalocean_droplet.web.ipv4_address
}

هذا output مهم جداً لأنه يصبح نقطة ربط للخطوات التالية مثل تنفيذ SSH أو تمرير العنوان إلى مرحلة نشر آلي ضمن النشر المستمر (Continuous Deployment): رفع الكود الجديد إلى سيرفر Linux تلقائياً.

أوامر التشغيل الأساسية

بعد تجهيز الملفات، تكون دورة العمل اليومية مع Terraform بسيطة لكنها دقيقة:

terraform init
terraform fmt
terraform validate
terraform plan
terraform apply
  • init يقوم بتحميل الإضافات الخاصة بالمزود.
  • fmt يوحّد تنسيق الملفات.
  • validate يفحص صحة الصياغة والمنطق الأساسي.
  • plan يعرض التغييرات قبل تنفيذها.
  • apply يطبّق الحالة المطلوبة فعلياً.

في بيئات المؤسسات، يفضّل عدم تنفيذ apply مباشرة من جهاز المطور، بل عبر Pipeline مراقب بعد مراجعة التغييرات. ويمكنك فهم هذا المسار بشكل أوسع عبر ما هو الـ CI/CD؟ ولماذا نؤتمت عمليات اختبار ونشر الأكواد؟.

فهم ملف الحالة ولماذا هو خطير وحساس

أحد أهم المفاهيم التي يستهين بها المبتدئون هو ملف terraform.tfstate. هذا الملف يمثل ذاكرة الأداة، وفيه تُسجل العلاقة بين الكود والموارد الحقيقية الموجودة في السحابة.

إذا فُقد هذا الملف أو تم العبث به بشكل غير مدروس، قد لا تعرف الأداة ما الذي أنشأته سابقاً، وقد ينتج عن ذلك تضارب أو إعادة إنشاء موارد أو فقدان تتبع البنية. لهذا السبب، في المشاريع الحقيقية يتم حفظه في Remote Backend بدلاً من حفظه محلياً.

لا ترفع ملف terraform.tfstate إلى مستودع عام، لأنه قد يحتوي معرفات موارد، عناوين، وأحياناً بيانات حساسة. احفظه في مخزن بعيد مشفر مع قفل للتعديلات المتزامنة لتفادي تلف الحالة أو الكتابة فوقها من أكثر من مهندس.

من إنشاء السيرفر إلى تهيئته وتشغيل التطبيق

المرحلة الصحيحة معمارياً ليست أن تجعل Terraform يفعل كل شيء. الأفضل هو الفصل بين:

  • إنشاء البنية عبر Terraform.
  • تهيئة النظام عبر Ansible.
  • تغليف التطبيق عبر Docker.
  • أتمتة النشر والتحقق عبر CI/CD.

ولهذا ستجد أن بناء بنية قوية لا يعني فقط إنشاء VPS، بل يعني أن هذا الخادم يصبح جزءاً من سلسلة تشغيل متكاملة. فإذا كنت تنشر تطبيقات حاويات، راجع أيضاً مشكلة “الكود يعمل على جهازي فقط” وكيف يحلها Docker نهائياً؟ لفهم لماذا يجب أن تكون بيئة التطبيق نفسها موحدة وقابلة للنقل.

لا تستخدم حساب root المباشر في كل خطوات التهيئة والنشر. أنشئ مستخدماً إدارياً محدود الصلاحيات، فعّل مفاتيح SSH، وأغلق تسجيل الدخول بكلمة المرور متى أمكن. هذه الخطوات تقلل مساحة الهجوم وتحميك من اختراقات شائعة جداً.

أخطاء شائعة في أول ملف Terraform

  • كتابة القيم الحساسة داخل الملف الرئيسي بدلاً من عزلها.
  • تنفيذ تغييرات مباشرة دون مراجعة ناتج plan.
  • عدم استخدام وسوم tags مما يصعّب إدارة الموارد لاحقاً.
  • الخلط بين مسؤولية إنشاء الموارد ومسؤولية إعداد النظام الداخلي.
  • تجاهل مسألة إدارة الحالة واعتبارها مجرد ملف ثانوي.

كل خطأ من هذه الأخطاء يبدو صغيراً في بيئة اختبار، لكنه يصبح مكلفاً جداً عندما تتحول البنية إلى عدة خوادم وفرق عمل متعددة وتحديثات يومية.

الخلاصة

كتابة أول ملف Terraform لإنشاء سيرفر سحابي ليست مجرد تجربة تعليمية، بل هي انتقال فعلي من الإدارة اليدوية إلى هندسة بنية يمكن توثيقها، مراجعتها، وإعادة بنائها بثقة. هذه النقلة هي ما يميز فرق DevOps الناضجة عن البيئات العشوائية.

ابدأ بسيرفر واحد، افهم منطق state وplan وapply، ثم وسّع القالب تدريجياً ليشمل الشبكات والأقراص والسياسات الأمنية. عندها لن يكون إنشاء الخادم مهمة يدوية متعبة، بل عملية هندسية قابلة للتكرار والضبط والدمج الكامل مع منظومة النشر الحديثة.

6 comments

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *