لماذا يتصرف تطبيقك بشكل مختلف في بيئة الاختبار والإنتاج

تنشر نفس الكود في بيئة الاختبار (staging)، وتجري اختباراتك، وكل شيء ينجح. ثم تنشر في الإنتاج (production)، ويتعطل التطبيق. الكود متطابق. الفرق هو قيمة إعدادات واحدة نسيت تحديثها.

هذا السيناريو يتكرر في الفرق كل أسبوع. الكود سليم. الإعدادات ليست كذلك. وعندما تكون المشكلة سرًا مثل كلمة مرور قاعدة بيانات أو رمز API، ترتفع المخاطر أكثر. تسريب سر يمكن أن يسبب ضررًا أكبر من معظم أخطاء الكود.

ما هي الإعدادات والأسرار في الواقع

الإعدادات (Configuration) هي أي قيمة تغير سلوك تطبيقك دون تغيير كوده. عناوين الخوادم، أقصى عدد اتصالات، مستويات التسجيل، أعلام الميزات - كل هذه إعدادات. نفس قاعدة الكود تعمل بشكل مختلف في بيئة التطوير والاختبار والإنتاج لأن الإعدادات تتغير.

الأسرار (Secrets) هي فئة خاصة من الإعدادات. إنها قيم يجب أن تبقى سرية: كلمات المرور، الرموز المميزة (tokens)، مفاتيح التشفير، الشهادات. الأسرار تحتاج معالجة مختلفة لأن كشفها هو حادث أمني، وليس مجرد خطأ في الإعدادات.

النقطة الأساسية هي أن كلاً من الإعدادات والأسرار يجب إدارتها بشكل منفصل عن كود التطبيق الخاص بك. إنها تعيش في طبقة مختلفة من نظام التسليم الخاص بك.

ابدأ بقالب إعدادات

قبل أن تتمكن من إدارة الإعدادات بشكل صحيح، تحتاج إلى معرفة الإعدادات التي يحتاجها تطبيقك بالفعل. قالب الإعدادات هو ببساطة قائمة كاملة بكل قيمة إعداد يتوقعها تطبيقك، منظمة حسب البيئة.

لكل عنصر إعداد، سجل:

إليك مثال ملموس لما قد يبدو عليه هذا القالب بصيغة YAML:

# config-template.yaml
# قالب إعدادات التطبيق
# تجاوز القيم لكل بيئة في ملفات خاصة بالبيئة

app:
  name: my-app
  version: 1.0.0
  log_level: info  # تجاوز: dev=debug, staging=info, prod=warn
  max_retry: 3

database:
  host: localhost  # تجاوز: staging=db-staging.example.com, prod=db-prod.example.com
  port: 5432
  name: myapp_db
  pool_size: 10  # تجاوز: prod=50

cache:
  host: localhost  # تجاوز: staging=redis-staging.example.com, prod=redis-prod.example.com
  port: 6379
  ttl_seconds: 3600

feature_flags:
  new_checkout: false  # تجاوز: staging=true, prod=false
  dark_mode: true
  • اسم المتغير (مثل DB_HOST أو MAX_RETRY)
  • نوع القيمة (نص، رقم، قيمة منطقية)
  • أي البيئات تستخدمه
  • هل تختلف القيمة بين البيئات

بعض القيم ستكون نفسها في كل مكان. MAX_RETRY قد تكون 3 في بيئة التطوير والاختبار والإنتاج. قيم أخرى يجب أن تختلف. DB_HOST سيشير إلى قاعدة البيانات المحلية في بيئة التطوير ومجموعة قواعد بيانات الإنتاج في بيئة الإنتاج.

يجب أن يلاحظ القالب أيضًا من يمكنه تغيير كل قيمة إعداد وكيف يتم تتبع هذه التغييرات. ليس كل فرد في الفريق يجب أن يكون قادرًا على تغيير سلاسل اتصال قاعدة بيانات الإنتاج.

الأسرار تحتاج قالبها الخاص

الأسرار تتبع نفس الفكرة ولكن بقواعد أكثر صرامة. قالب الأسرار يسجل:

  • اسم السر
  • من أين يأتي (vault، parameter store، ملف مشفر)
  • أي البيئات تحتاج الوصول إليه
  • متى تم تدويره آخر مرة
  • كم هي مدة صلاحيته
  • الخطوات الدقيقة لتدويره
  • كيفية التحقق من أن التطبيق لا يزال يعمل بعد التدوير

التدوير (Rotation) هو عملية استبدال سر قديم بسر جديد وفق جدول زمني منتظم. العديد من الفرق تتخطى هذا حتى يجبرهم اختراق على التصرف. القالب يجعل التدوير عملية روتينية بدلاً من حالة طارئة.

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

دقق كل شيء

الإعدادات والأسرار تحتاج سجلات تدقيق (audit trails). سجل التدقيق يسجل من وصل أو غير قيمة إعداد أو سر، ومتى فعل ذلك، ولماذا.

قالب سجلات التدقيق يجب أن يلتقط:

  • الطابع الزمني للإجراء
  • من قام به
  • ما الإجراء الذي تم (عرض، تعديل، حذف)
  • أي إعداد أو سر تأثر

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

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

اختبر إعداداتك وأسرارك

إليك خطوة يغفل عنها معظم الفرق: الإعدادات والأسرار تحتاج إلى اختبار. أنت تختبر كودك. أنت تختبر بنيتك التحتية. لكن كم مرة تختبر أن تطبيقك يمكنه بالفعل قراءة إعداداته وأسراره بشكل صحيح في كل بيئة؟

اختبار الإعدادات يتحقق من:

  • أن جميع قيم الإعدادات المطلوبة موجودة
  • أن لها النوع الصحيح
  • أنها ضمن النطاقات المتوقعة
  • أن التطبيق يبدأ بنجاح بهذه القيم

اختبار الأسرار يتحقق من:

  • أن السر موجود ويمكن الوصول إليه
  • أن التطبيق يمكنه المصادقة باستخدام السر
  • أن التطبيق يمكنه تنفيذ عملياته الأساسية بعد المصادقة

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

قائمة مراجعة عملية

إليك قائمة مراجعة قصيرة يمكنك استخدامها عند إعداد إدارة الإعدادات والأسرار لتطبيق أو خدمة جديدة:

  • أدرج جميع قيم الإعدادات التي يحتاجها التطبيق، منظمة حسب البيئة
  • لاحظ أي القيم تختلف بين البيئات وأيها تبقى كما هي
  • حدد أي القيم هي أسرار وتحتاج معالجة خاصة
  • وثق مصدر كل سر (vault، parameter store، إلخ)
  • أنشئ جدول تدوير لكل سر
  • أعد تسجيل الدخول (audit logging) للوصول إلى الإعدادات والأسرار
  • اكتب اختبارات تتحقق من تحميل الإعدادات والأسرار في كل بيئة
  • وثق من يمكنه تغيير كل قيمة إعداد وسر

الخلاصة

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