مستوى المقال: مبتدئ. لو لسه بتتعلم 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
}
}