المستوى: متوسط — مناسب لو انت بتستخدم Terraform مع فريق وعندك backend على S3، وعايز تفهم قفل الحالة صح.
Terraform State Locking: ليه مهندسَين بيشتغلوا سوا ممكن يدمّروا بنيتك التحتية
لو مهندسَين في فريقك شغّلوا terraform apply في نفس اللحظة، ملف الحالة ممكن يتكتب نُصّه من الأول ونُصّه من التاني. النتيجة: موارد اتبنت مرتين، أو موارد موجودة فعلًا واختفت من الحالة فـ Terraform حاول يبنيها تاني. قفل الحالة بيمنع ده بسطر واحد في الإعداد. المقال ده هيوريك السطر، وليه بيشتغل، وإمتى تسيبه.
المشكلة باختصار
Terraform بيحتفظ بملف اسمه terraform.tfstate فيه خريطة بين اللي كتبته في الكود واللي اتبنى فعلًا في السحابة. الملف ده هو مصدر الحقيقة. لو اتنين كتبوا فيه في نفس الوقت، بيحصل اللي بيتسمى lost update: تعديل واحد بيدهس التاني، والحالة تبقى ناقصة أو متضاربة. المشكلة دي مش نظرية؛ بتحصل بالظبط لما الفريق يكبر وكل واحد بيـ apply من اللابتوب بتاعه أو من الـ CI في نفس الوقت.
مثال بسيط الأول: الكرّاسة والقلم الواحد
تخيّل كرّاسة واحدة بتسجّل فيها كل حاجة عن مخزن، ومعاها قلم واحد بس. القاعدة: مش هينفع حد يكتب في الكرّاسة إلا وهو ماسك القلم. لو انت ماسك القلم، زميلك يستنّى لحد ما تخلّص وتسيبه. كده الكتابة بتحصل بالتناوب، والكرّاسة تفضل مظبوطة.
دلوقتي شيل القلم. الاتنين يكتبوا مع بعض على نفس السطر. سطر فوق سطر، وكلام ناقص. ده بالظبط اللي بيحصل لملف الحالة من غير قفل. القفل هو القلم الواحد: مهما كان عدد اللي عايزين يكتبوا، واحد بس بيمسك القلم في اللحظة، والباقي في الطابور.
يعني إيه "القفل" علميًا، وليه بيتكسر من غيره
عمليات الكتابة في Terraform (زي apply وplan بتحديث) بتاخد قفلًا على الحالة قبل ما تبدأ، وبتسيبه بعد ما تخلّص. القفل ده لازم يكون مركزيًا، يعني كل اللي بيشتغلوا على نفس الحالة يشوفوه. لو الحالة مخزّنة محليًا على جهازك، مفيش طريقة زميلك يعرف إنك ماسك القفل. عشان كده الفريق بيحط الحالة في remote backend زي S3، والقفل بيتدار هناك.
الافتراض هنا: انت عندك backend على S3 وفريق أكتر من واحد بيعمل apply. لو ده مش وضعك، القفل مش أولوية (هنرجع لدي في قسم "متى لا تحتاجه").
الحل: قفل الحالة على S3 بسطر واحد
قبل Terraform 1.10 كنت محتاج جدول DynamoDB منفصل عشان القفل. من الإصدار 1.10 بقى فيه قفل أصلي على S3 نفسها من غير أي خدمة زيادة، بتفعّله بخيار واحد اسمه use_lockfile. Terraform بيعمل ملف صغير اسمه <key>.tflock جوه نفس الـ bucket، ويستخدم conditional write (هيدر If-None-Match) عشان يضمن إن الملف يتكتب بس لو مش موجود — ودي عملية ذرّية بتحسم مين مسك القفل الأول.