مستوى المقال: مبتدئ. لو لسه بتتعلم Terraform وعملت أول terraform apply ناجح، المقال ده ليك. مش محتاج خبرة سابقة، بس محتاج تكون عارف يعني إيه سيرفر على السحابة.
Terraform State: العقل اللي بيخلّي Terraform يعرف إيه اللي اتعمل فعلًا
هتطلع من المقال ده عارف ليه فريقك بيكرّر نفس السيرفر مرتين، وإزاي تقفل المشكلة دي في 6 أسطر إعداد بس.
المشكلة باختصار
كتبت كود Terraform، عملت terraform apply، واتظبط سيرفر على AWS. تمام. بعد يومين زميلك سحب نفس الكود على جهازه وعمل apply. النتيجة: سيرفر تاني جديد بدل ما Terraform يقولّه "ده موجود خلاص". دلوقتي عندك سيرفرين بيدفعوا فلوس، ومحدش عارف مين بيتكلم مع مين.
السبب مش في الكود. السبب إن كل واحد فيكم عنده نسخة منفصلة من ذاكرة Terraform. الذاكرة دي اسمها ملف الـ state، ولو مش مشترك، كل تطبيق بيشتغل أعمى.
ليه Terraform بينسى؟ يعني إيه ملف state
خلّينا نبدأ بمثال بعيد عن الكود خالص.
تخيّل إنت ومراتك بتجهّزوا البيت. عملت ورقة فيها كل حاجة اشتريتها: تلاجة، غسالة، كنبة. الورقة دي في جيبك إنت لوحدك. مراتك مش شايفاها. راحت تشتري، ومعهاش الورقة، فاشترت تلاجة تانية. بقى عندكم تلاجتين. مش لأنها غلطانة — لأن الورقة، يعني الذاكرة، كانت معاك إنت بس.
الحل البديهي: تحطّوا الورقة على باب التلاجة. مكان واحد، الكل بيشوفه، الكل بيكتب فيه. كده محدش هيكرّر حاجة اتشترت.
دلوقتي بالتعريف الدقيق: ملف الـ state في Terraform هو ملف JSON اسمه terraform.tfstate. بيشتغل كجدول ربط بين الموارد اللي كتبتها في الكود — زي aws_instance.web — والـ ID الحقيقي للمورد على السحابة — زي i-0abc123. كل terraform plan بيقارن 3 حاجات: الكود اللي كتبته، الـ state، والواقع الفعلي على السحابة. لو الـ state ناقص أو محلي على جهازك بس، Terraform بيفتكر إن مفيش حاجة اتعملت، فيعمل كل حاجة من الأول.
الحل: backend مشترك في 6 أسطر
الفكرة إنك تنقل ملف الـ state من جهازك لمكان مشترك ومأمّن. ده اسمه remote backend. هنستخدم S3 على AWS لتخزين الملف، و DynamoDB كقفل — هنشرح القفل بعد شوية.
- اعمل S3 bucket مخصص للـ state، وفعّل عليه versioning عشان لو حصل خطأ ترجع لنسخة قديمة.
- اعمل جدول DynamoDB ومفتاحه الأساسي اسمه
LockIDمن نوع String. - ضيف بلوك الـ backend ده في ملف Terraform بتاعك.
- شغّل
terraform init -migrate-stateعشان ينقل الـ state المحلي للسحابة.
terraform {
backend "s3" {
bucket = "haies-terraform-state"
key = "prod/network/terraform.tfstate"
region = "eu-central-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
وبعدين على الـ terminal:
# ينقل الـ state من جهازك للـ S3
terraform init -migrate-state
# بياخد الـ state من S3، فالخطة دلوقتي بتاعة الفريق كله
terraform plan
terraform apply
كده أي حد في الفريق يشغّل apply هيقرا نفس الذاكرة. السيناريو الواقعي: فريق من 5 مهندسين كان عنده 3 حوادث في شهرين بسبب موارد متكررة، وتكلفة زيادة حوالي 40 دولار شهريًا اتصرفت على الفاضي. بعد نقل الـ state لـ S3، الرقم ده بقى صفر، وزمن مراجعة "إيه اللي اتغيّر" نزل من بحث يدوي حوالي 20 دقيقة لـ terraform plan واحد بياخد ثواني.
الـ state lock: ليه محتاج قفل على الذاكرة
نرجع لمثال الورقة على باب التلاجة. لو إنت ومراتك بتكتبوا في نفس الورقة في نفس اللحظة بالظبط، الكلام هيتلخبط، سطر فوق سطر. محتاجين قاعدة: اللي ماسك القلم بس هو اللي يكتب، والباقي يستنى دوره.
ده بالظبط الـ state lock. لما حد يشغّل terraform apply، Terraform بيحط علامة "مشغول" في جدول DynamoDB. لو زميلك حاول يعمل apply في نفس الوقت، Terraform هيقولّه "في حد بيشتغل دلوقتي، استنى" بدل ما الاتنين يكتبوا في الـ state سوا ويبوّظوه. علميًا ده اسمه mutual exclusion: مسموح بعملية كتابة واحدة بس في كل لحظة.
الـ trade-offs اللي لازم تعرفها
- اعتماد على الشبكة: كل
planوapplyدلوقتي محتاج اتصال بـ AWS. بتكسب فريق متزامن، بتخسر إنك تشتغل أوفلاين زي قبل. - الـ state فيه أسرار: ملف الـ state بيخزّن قيم زي كلمات السر والمفاتيح كنص واضح. لازم تقفل الـ S3 bucket صح، تفعّل
encrypt = true، وتمنع أي وصول عام. - تكلفة بسيطة بس مش صفر: S3 و DynamoDB بالاستخدام ده تكلفتهم غالبًا أقل من دولار شهريًا، بس لازم تحطها في الحسبان.
- القفل ممكن يعلق: لو الـ apply اتقطع فجأة، القفل ممكن يفضل شغّال ويمنع الباقي. بتفكّه بـ
terraform force-unlock، بس استخدمه بحذر بعد ما تتأكد إن مفيش حد فعلًا بيشتغل.
متى متستخدمش backend بعيد
لو بتجرّب Terraform لوحدك على مشروع تعليمي هترميه بعد ساعة، الـ state المحلي كفاية ومش محتاج تعقّد حياتك. الافتراض هنا إنك شخص واحد والبنية التحتية مؤقتة. الـ remote backend بيبقى مهم لما يبقى فيه أكتر من شخص بيلمس نفس البنية، أو لما البنية دي حقيقية وبتدفع فلوس. تحت كده، التعقيد الزيادة مش مبرّر.
الخطوة التالية
افتح أي مشروع Terraform شغّال عندك دلوقتي وشغّل terraform state list. لو لقيت موارد حقيقية والـ state لسه ملف محلي على جهازك، ده تنبيه أحمر. اعمل S3 bucket، ضيف بلوك الـ backend اللي فوق، وشغّل terraform init -migrate-state. بعدها اطلب من زميلك يعمل terraform plan من جهازه — لو طلعله "No changes"، يبقى الذاكرة بقت مشتركة فعلًا.
المصادر
- توثيق HashiCorp الرسمي — Terraform State: developer.hashicorp.com/terraform/language/state
- توثيق HashiCorp — S3 Backend: developer.hashicorp.com/terraform/language/backend/s3
- توثيق HashiCorp — State Locking: developer.hashicorp.com/terraform/language/state/locking
- توثيق HashiCorp — Sensitive Data in State: developer.hashicorp.com/terraform/language/state/sensitive-data