الدرس 1 من 10 · الأساسيات
البنية التحتية كشيفرة (Infrastructure as Code): لماذا، وبأي أدوات
الهدف
فهم معنى « وصف البنية التحتية بالشيفرة »، وما يغيّره ذلك في العمل اليومي لفريق ما، وتحديد موقع الأدوات الرئيسية: OpenTofu وTerraform، وAnsible، وPulumi، وCloudFormation. ستكتب بعد ذلك أول إعداد OpenTofu لك.
أهم النقاط
- تقوم البنية التحتية كشيفرة (IaC) على وصف الشبكات والخوادم والجدران النارية وقواعد البيانات وسجلات DNS في ملفات نصية مُدارة بالنسخ في Git، ثم ترك أداة تنشئها وتصونها.
- تصف المقاربة التصريحية (declarative) الحالة المرغوبة (« ثلاثة خوادم ويب »)؛ وتحسب الأداة بنفسها الإجراءات. أما المقاربة الأمرية (imperative) فتصف الخطوات (« أنشئ خادمًا، ثم خادمًا ثانيًا… »).
- نميّز بين التزويد (provisioning، أي إنشاء الموارد: OpenTofu وTerraform وCloudFormation وPulumi) وإدارة الإعدادات (configuration management، أي تثبيت البرمجيات وضبطها داخل الآلات: Ansible وPuppet وChef).
- OpenTofu نسخة مشتقّة حرّة من Terraform، أُنشئت سنة 2023 بعد تغيير رخصة Terraform؛ وتحتفظ بلغته (HCL) وبجلّ أوامره تقريبًا.
- الأداة التصريحية متساوية القوى (idempotent): إذا أُعيد تشغيلها عشر مرات، فلا تُجري تغييرات إلا إذا وُجد فرق بين الشيفرة والواقع.
المشكلة: البنية التحتية المصنوعة يدويًا
تخيّل وكالة ويب في الدار البيضاء تستضيف مواقع عشرين زبونًا. منذ خمس سنوات، أُنشئ كل خادم يدويًا في لوحة تحكم المزوّد: نقرة للآلة، وأخرى للجدار الناري، وقاعدة أُضيفت « مؤقتًا » في ليلة عطل.
النتيجة:
- لا أحد يعرف بالضبط كيف أُعدّ خادم الزبون الرئيسي؛ فالمسؤول الذي ركّبه قد غادر؛
- إنشاء بيئة اختبار مطابقة للإنتاج يستغرق يومين، ولا تكون أبدًا مطابقة حقًا؛
- بعد حادث (حذف عرضي، اختراق)، تستغرق إعادة البناء أسبوعًا؛
- التغييرات لا تُراجَع: قاعدة في الجدار الناري مفتوحة على الإنترنت كلها تمرّ دون أن ينتبه إليها أحد.
نتحدث هنا عن خوادم « ندف الثلج » (snowflake servers): كل واحد منها فريد ويستحيل استنساخه.
الحل: وصف كل شيء في ملفات
# reseau.tf — مقتطف مما ستكتبه في هذا التكوين
resource "aws_security_group" "web" {
name = "web-client-atlas"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
ما نربحه:
| قبل (يدويًا) | بعد (IaC) |
|---|---|
| التوثيق خاطئ أو غائب | الشيفرة هي التوثيق |
| تغيير = نقرة غير مرئية | تغيير = commit يراجعه زميل |
| بيئة الاختبار لا تشبه الإنتاج | الشيفرة نفسها تنشئ الاختبار والإنتاج |
| إعادة البناء تستغرق أيامًا | tofu apply يعيد إنشاء كل شيء في دقائق |
| « من فتح هذا المنفذ؟ » | git log يجيب، مع التاريخ والسبب |
تُطبّق IaC على البنية التحتية ممارسات تطوير البرمجيات: إدارة النسخ، ومراجعة الشيفرة، والاختبارات، والتكامل المستمر.
تصريحي أم أمري
لنقارن طريقتين لطلب ثلاثة خوادم ويب.
المقاربة الأمرية، سكربت:
# creer-serveurs.sh — كل تشغيل ينشئ ثلاثة خوادم إضافية
for i in 1 2 3; do
fournisseur-cli server create --name "web-$i" --type petit --image debian-12
done
إذا شغّلت هذا السكربت مرتين، يصبح لديك ستة خوادم. وإذا فشل عند الخادم الثاني، يجب التنظيف يدويًا. وللانتقال من ثلاثة إلى خمسة خوادم، يجب كتابة سكربت آخر.
المقاربة التصريحية، OpenTofu:
resource "fournisseur_server" "web" {
count = 3
name = "web-${count.index + 1}"
type = "petit"
image = "debian-12"
}
أنت تصف النتيجة. في التشغيل الأول، ينشئ OpenTofu ثلاثة خوادم. وفي التشغيل الثاني، لا يفعل شيئًا: فالواقع يطابق الشيفرة مسبقًا. وإذا كتبت count = 5، فإنه ينشئ اثنين. وإذا كتبت count = 2، فإنه يحذف واحدًا. الأداة هي التي تحسب الفرق.
ولهذا، يحتفظ OpenTofu بـ حالة (state): قائمة ما أنشأه، مع المعرّفات الحقيقية لدى المزوّد. ستدرسها بالتفصيل في الدرس 2.1.
مشهد الأدوات
| الأداة | الفئة | اللغة | الأهداف | الرخصة |
|---|---|---|---|---|
| OpenTofu | تزويد تصريحي | HCL | كل مزوّد لديه API (AWS، Azure، GCP، OVHcloud، Scaleway، Proxmox، Kubernetes، DNS…) | MPL 2.0 (حرّة)، مؤسسة Linux |
| Terraform | تزويد تصريحي | HCL | الأهداف نفسها | BUSL 1.1 منذ النسخة 1.6 (2023) |
| Ansible | إدارة الإعدادات، التنسيق (orchestration) | YAML (playbooks) | الأنظمة (Linux، Windows، الشبكة)، عبر SSH، دون وكيل (agent) | GPL v3 |
| Pulumi | تزويد تصريحي | Python، TypeScript، Go، C#… | كل مزوّد | Apache 2.0 (المحرّك) |
| CloudFormation | تزويد تصريحي | YAML أو JSON | AWS فقط | خدمة AWS |
| Bicep / ARM | تزويد تصريحي | Bicep، JSON | Azure فقط | خدمة Microsoft |
| Puppet، Chef | إدارة الإعدادات | لغات خاصة (DSL) | الأنظمة، مع وكيل | متنوّعة |
| cloud-init | الإعداد عند الإقلاع الأول | YAML | آلة افتراضية جديدة | Apache 2.0 / GPL v3 |
بعض المعالم للاختيار:
- عدة مزوّدين أو مزوّد محلي (OVHcloud، مزوّد استضافة مغربي، Proxmox): OpenTofu أو Terraform، بفضل آلاف الـ providers لديهما.
- كل شيء لدى AWS مع فريق يريد البقاء في هذا النظام البيئي: CloudFormation ممكن، لكنك ستبقى حبيس AWS.
- فريق من المطوّرين يفضّل لغة برمجة حقيقية (حلقات، اختبارات وحدوية): Pulumi.
- إعداد ما بداخل الآلات (الحزم، الملفات، الخدمات): Ansible. وكثيرًا ما نجمعه مع OpenTofu (الدرس 3.1): ينشئ OpenTofu الآلات، ويُعدّها Ansible.
OpenTofu ليس أداة لإدارة الإعدادات: فهو ينشئ الموارد ويحذفها، لكنه لا يثبّت nginx داخل آلة (يمكنه فقط تمرير سكربت إقلاع، cloud-init مثلًا).
OpenTofu وTerraform: لمحة تاريخية
- 2014: نشرت HashiCorp أداة Terraform تحت الرخصة الحرّة MPL 2.0. فأصبحت الأداة المرجعية لـ IaC متعدّد السحابات (multi-cloud).
- غشت 2023: نقلت HashiCorp منتجاتها، ومنها Terraform ابتداءً من النسخة 1.6، إلى رخصة Business Source License (BUSL 1.1). تبقى الشيفرة مقروءة، لكن بعض الاستعمالات المنافسة لـ HashiCorp لم تعد مسموحًا بها. فأطلقت شركات ومساهمون حينها نسخة مشتقّة من شيفرة MPL، سُمّيت أولًا OpenTF.
- شتنبر 2023: انضمّ المشروع إلى Linux Foundation باسم OpenTofu.
- يناير 2024: صدور OpenTofu 1.6، أول نسخة مستقرة، متوافقة مع Terraform 1.5/1.6.
- منذ ذلك الحين: يتطوّر المشروعان كلٌّ على حدة. يضيف OpenTofu وظائفه الخاصة (تشفير الحالة،
enabledداخلlifecycle، ملفات.tofu…)، ويضيف Terraform وظائفه. ومن جهة أخرى، استحوذت IBM على HashiCorp (اكتملت العملية سنة 2025).
عمليًا، في هذا التكوين:
| OpenTofu | Terraform | |
|---|---|---|
| الأمر | tofu init، tofu plan، tofu apply |
terraform init، terraform plan، terraform apply |
| اللغة | HCL، ملفات .tf (و.tofu) |
HCL، ملفات .tf |
| كتلة الإعدادات | terraform { … } (الاسم نفسه، للتوافق) |
terraform { … } |
| السجلّ العام (registry) | registry.opentofu.org |
registry.terraform.io |
| المزوّدون (providers) | نفسهم (hashicorp/aws، hashicorp/local…) |
نفسهم |
ما تتعلّمه هنا يفيد إذن أيضًا في مشروع Terraform قائم. والانتقال من مشروع Terraform حديث إلى OpenTofu يتطلّب عمومًا حفظ نسخة من الحالة، وتثبيت tofu، ثم تشغيل tofu init وtofu plan يجب ألا يُظهر أي تغيير.
سير عمل OpenTofu
écrire (*.tf) ──▶ tofu init ──▶ tofu plan ──▶ revue ──▶ tofu apply
▲ télécharge calcule les (vous, applique les
│ les providers différences un collègue) changements
└──────────────── git commit, push, merge request ◀───────────────┘
- الكتابة: تصف الموارد في ملفات
.tf. - التخطيط: يقارن
tofu planبين الشيفرة والحالة والواقع، ثم يعرض ما سيُنشأ (+)، أو يُعدَّل (~)، أو يُدمَّر (-). - التطبيق: ينفّذ
tofu applyالخطة، بعد تأكيدك.
يفصّل الدرس التالي هذه الأوامر.
ملفك الأول
نوع المورد terraform_data يوفّره OpenTofu نفسه، دون أي تنزيل: فهو لا ينشئ شيئًا لدى أي مزوّد، بل يحتفظ ببساطة بقيمة في الحالة. إنه مثالي للتعلّم.
# /root/iac/premier/main.tf
resource "terraform_data" "bonjour" {
input = "Bonjour depuis Rabat"
}
# /root/iac/premier/outputs.tf
output "message" {
value = terraform_data.bonjour.output
}
cd /root/iac/premier
tofu init # لا يوجد أي مزوّد للتنزيل هنا
tofu apply # أجب بـ « yes »
# Outputs:
# message = "Bonjour depuis Rabat"
وما لا يدخل إلى Git:
# .gitignore (في هذا الملف، يشغل التعليق السطر كله)
# المزوّدون المنزَّلون، يعيد tofu init إنشاءهم
.terraform/
# قد تحتوي الحالة على أسرار: مكانها backend بعيد
*.tfstate
# نسخها الاحتياطية (terraform.tfstate.backup)
*.tfstate.*
crash.log
# الخطط المحفوظة
*.tfplan
أما الملف .terraform.lock.hcl فـيجب تسجيله: فهو يثبّت النسخ الدقيقة للمزوّدين للفريق كله.
أخطاء متكررة
- الخلط بين النقر والشيفرة: أي تعديل يُجرى يدويًا في لوحة التحكم سيُلغى (أو سيتسبّب في خطأ) عند
tofu applyالتالي. بمجرد اعتماد IaC، يمرّ كل شيء عبر الشيفرة. - إدارة الحالة بالنسخ (
terraform.tfstate) في Git: قد تحتوي على كلمات مرور واضحة، وقد يمحو شخصان عمل بعضهما. - الاعتقاد بأن OpenTofu يُعدّ البرمجيات داخل الآلات: لذلك نستعمل Ansible أو cloud-init.
- الانطلاق دون خطة: قد يدمّر
applyدون قراءة الخطة قاعدة بيانات لأن وسيطًا ما تغيّر.
التطبيق العملي (Lab)
تحتوي حاوية المختبر على OpenTofu لكنها لا تملك اتصالًا بالشبكة: تكتب ملفات، ويعيد المصحّح قراءتها. المورد terraform_data لا يتطلّب أي تنزيل: يمكنك حتى تجربة tofu init ثم tofu apply -auto-approve داخل المجلد لرؤية المُخرَج.
- أول مورد
terraform_data؛ - مُخرَج يعرض قيمته؛
- الكتلة
terraformالتي تشترط نسخة دنيا، مع ملفات منسّقة جيدًا (tofu fmt)؛ - ملف
.gitignoreلمشروع OpenTofu.
لكتابة ملف دون محرّر: cat > main.tf <<'EOF' … EOF.
اختبار قصير
- ما الفرق بين المقاربة التصريحية والمقاربة الأمرية؟
- تنتقل من
count = 3إلىcount = 5وتعيد تشغيل OpenTofu. ماذا يحدث؟ - OpenTofu أم Ansible: أيّهما ينشئ الآلة الافتراضية، وأيّهما يثبّت nginx داخلها؟
- لماذا يوجد OpenTofu، وما الذي يحتفظ به من Terraform؟
- هل يجب تسجيل
terraform.tfstateفي Git؟ وماذا عن.terraform.lock.hcl؟
الأجوبة
- التصريحية: نصف الحالة النهائية المرغوبة وتحسب الأداة الإجراءات. الأمرية: نكتب سلسلة الإجراءات المراد تنفيذها.
- يقارن OpenTofu الشيفرة بالحالة، فيرى أن هناك نسختين (instances) ناقصتين وينشئ اثنتين، دون المساس بالثلاث الموجودة.
- ينشئ OpenTofu الآلة (التزويد)؛ ويثبّت Ansible خادم nginx ويُعدّه داخلها (إدارة الإعدادات).
- أُنشئ سنة 2023، تحت مظلة Linux Foundation، بعد انتقال Terraform إلى رخصة BUSL؛ ويحتفظ بلغة HCL، وبالأوامر (مع
tofuبدلterraform)، وبالمزوّدين. - لا بالنسبة للحالة: قد تحتوي على أسرار ويجب مشاركتها عبر backend بعيد مع القفل (locking). ونعم بالنسبة لـ
.terraform.lock.hcl، الذي يثبّت نسخ المزوّدين للفريق كله.
المراجع: توثيق OpenTofu (MPL 2.0). نص أصلي من MasterLinux.