عندما يختفي ملف حالة Terraform: استراتيجيات استرداد فعّالة

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

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

لماذا تتعطل ملفات الحالة

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

ثم هناك مشكلة القفل. يقوم Terraform بقفل ملفات الحالة لمنع عمليات متعددة من الكتابة في وقت واحد. إذا انتهت عملية دون تحرير قفلها، يبقى هذا القفل في مكانه. يفشل كل plan أو apply لاحق لأن Terraform يعتقد أن شخصاً آخر لا يزال يعمل.

تختلف درجة الخطورة، لكن المشكلة الأساسية واحدة: لقد فقدت الاتصال بين الكود الخاص بك والبنية التحتية قيد التشغيل.

أولاً: لا تعيد بناء كل شيء

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

إذا قمت بتشغيل terraform destroy وأعدت إنشاء كل شيء، فستتسبب في توقف غير ضروري ومخاطرة بفقدان البيانات. سيتم مسح قواعد البيانات. سيتم حذف وحدات التخزين الدائمة. ستتغير سجلات DNS. مسار الاسترداد يدور حول استعادة الحالة، وليس إعادة بناء البنية التحتية.

الاسترداد حسب درجة الخطورة

الحالة المقفلة: الإصلاح البسيط

إليك شجرة قرار لمساعدتك في تحديد مسار الاسترداد بسرعة بناءً على نوع مشكلة ملف الحالة:

flowchart TD A[مشكلة في ملف الحالة] --> B{مقفل؟} A --> C{محذوف مع نسخة احتياطية؟} A --> D{تالف أو مفقود بدون نسخة احتياطية؟} A --> E{فقدان كامل؟} B --> F[إلغاء القفل القسري إذا لم تكن هناك عملية نشطة أخرى] C --> G[استعادة من النسخة الاحتياطية] D --> H[استيراد الموارد واحداً تلو الآخر] E --> I[إعادة البناء من الصفر] F --> J[التحقق باستخدام terraform plan] G --> J H --> J I --> J

إذا كان ملف الحالة موجوداً لكنه مقفل، فهذا هو السيناريو الأسهل. اكتشف أي عملية تحمل القفل. إذا كانت تلك العملية لا تزال قيد التشغيل، دعها تنتهي. إذا ماتت بشكل غير متوقع، استخدم أمر force-unlock:

terraform force-unlock <lock_id>

لكن كن حذراً. Force-unlock آمن فقط إذا كنت متأكداً تماماً من عدم وجود عملية أخرى تكتب في الحالة. إذا كتبت عمليتان في وقت واحد، سينتهي بك الأمر بحالة تالفة يصعب إصلاحها أكثر من قفل بسيط.

الحالة المحذوفة مع نسخة احتياطية: السيناريو المثالي

إذا تم حذف ملف الحالة ولكن لديك نسخة احتياطية، فأنت في وضع جيد. الاسترداد مباشر: استعادة النسخة الاحتياطية إلى الموقع الأصلي.

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

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

الحالة التالفة أو المفقودة بدون نسخة احتياطية: المسار الصعب

هنا تصبح الأمور مؤلمة. ليس لديك نسخة احتياطية، وملف الحالة إما غير قابل للقراءة أو مفقود. لكن البنية التحتية الخاصة بك لا تزال تعمل. الحل هو إعادة بناء الحالة عن طريق استيراد كل مورد على حدة.

لدى Terraform أمر import يقرأ البنية التحتية الحالية ويضيفها إلى ملف الحالة الخاص بك. لكل مورد معرف في الكود الخاص بك، تقوم بتشغيل:

على سبيل المثال، لاستيراد مثيل EC2 معرف في تكوينك باسم aws_instance.web، ستقوم بتشغيل:

terraform import aws_instance.web i-1234567890abcdef0

يجب أن يتطابق عنوان المورد (aws_instance.web) تماماً مع ما لديك في ملفات .tf. إذا كان المورد داخل وحدة نمطية، استخدم مسار الوحدة، مثل module.my_module.aws_instance.web. بعد الاستيراد، قم بتشغيل terraform plan لتأكيد تطابق الحالة مع التكوين الخاص بك.

terraform import <resource_type>.<resource_name> <resource_id>

يعتمد تنسيق معرف المورد على الموفر. بالنسبة لـ AWS، قد يكون معرف مثيل أو ARN. بالنسبة لـ GCP، عادة ما يكون اسم المورد أو عنوان URL كامل.

هذه العملية مملة للبنى التحتية الكبيرة. إذا كان لديك عشرات من مثيلات EC2، قواعد بيانات RDS، موازنات الأحمال، ومجموعات الأمان، فستقوم بتشغيل أوامر الاستيراد لبعض الوقت. لكنها الطريقة الوحيدة للتوفيق بين الكود الخاص بك والواقع دون تدمير أي شيء.

الفقدان الكامل بدون مسار استرداد: الخيار النووي

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

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

قبل اتباع هذا المسار، تأكد من أن لديك:

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

قائمة مراجعة عملية لاسترداد الحالة

عندما تتعطل الحالة، اعمل من خلال قائمة المراجعة هذه بالترتيب:

  1. تأكيد الضرر - هل الحالة مقفلة أم محذوفة أم تالفة؟ افحص رسالة الخطأ بعناية.
  2. التحقق من النسخ الاحتياطية - ابحث عن التحكم في الإصدارات على الواجهة الخلفية. تحقق من مواقع النسخ الاحتياطي اليدوي.
  3. الاستعادة إذا أمكن - إذا كان لديك نسخة احتياطية، قم باستعادتها والتحقق باستخدام terraform plan.
  4. إلغاء القفل القسري إذا كان مقفلاً - فقط إذا كنت متأكداً من عدم وجود عملية نشطة أخرى.
  5. استيراد الموارد - إذا لم تكن هناك نسخة احتياطية، ابدأ باستيراد الموارد واحداً تلو الآخر.
  6. النظر في إعادة البناء - فقط إذا كان الاستيراد غير عملي وكان لديك تغطية كاملة للكود.

الوقاية خير من العلاج

أفضل وقت للتحضير لفشل الحالة هو قبل حدوثه. ثلاث ممارسات تجعل الاسترداد أسهل بكثير:

أولاً، قم بتمكين التحكم في الإصدارات على الواجهة الخلفية للحالة. سواء كان S3 أو Azure Storage أو GCS، فإن التحكم في الإصدارات يمنحك شبكة أمان للحذف العرضي أو التلف.

ثانياً، قم بأتمتة النسخ الاحتياطية. حتى مع التحكم في الإصدارات، قم بتخزين نسخ من ملف الحالة الخاص بك في موقع منفصل. وظيفة cron بسيطة أو خطوة في pipeline تنسخ ملف الحالة إلى دلو أو حساب تخزين آخر تستغرق خمس دقائق للإعداد.

ثالثاً، وثق البنية التحتية الخاصة بك. عندما تحتاج إلى استيراد الموارد، تحتاج إلى معرفة ما هو موجود وما هي المعرفات الخاصة به. جرد محدث للموارد، سواء في README أو تم إنشاؤه من API مزود السحابة الخاص بك، يوفر ساعات أثناء الاسترداد.

ما التالي

بمجرد استعادة الحالة ويمكنك تشغيل terraform plan مرة أخرى، لم ينته العمل. يجب أن يؤدي الحادث إلى مراجعة كيفية إدارة حالتك. هل هناك فجوات في استراتيجية النسخ الاحتياطي الخاصة بك؟ هل يجب إضافة المزيد من ضوابط الوصول لمنع الحذف العرضي؟ هل تحتاج إلى دليل تشغيل لاسترداد الحالة؟

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

البنية التحتية التي بنيتها لا تزال موجودة. الحالة هي مجرد خريطة. عندما تضيع الخريطة، لا تحرق المدينة. ترسم خريطة جديدة.