مكان بوابات الجودة في خط الأنابيب أهم من محتوى الفحص
تضغط على commit. يبدأ الـ pipeline. تنتظر. وتنتظر. بعد خمس عشرة دقيقة، يفشل الـ pipeline بسبب ثغرة أمنية منخفضة الخطورة في مكتبة لا يستخدمها كودك حتى. تصلحها، تضغط مرة أخرى، وتنتظر خمس عشرة دقيقة أخرى.
هذه هي تكلفة وضع كل بوابة جودة في نفس النقطة من الـ pipeline. البديل محبط بنفس القدر: كل عمليات الفحص تُجرى في النهاية، قبل الإنتاج مباشرة. يمر كودك بالبناء، اختبارات الوحدة، اختبارات التكامل، ومرحلة staging. ثم يفشل لأن secret مشفر كان موجودًا في ملف إعدادات منذ أول commit. لقد أهدرت ساعات من وقت الـ pipeline على شيء كان يمكن اكتشافه في ثوانٍ.
موقع كل بوابة يحدد أمرين: مدى سرعة حصول المطورين على التغذية الراجعة، ومقدار الوقت والموارد الحاسوبية التي تهدر عند فشل شيء ما. إتقان هذا الأمر لا يتعلق بالاختيار بين السرعة والأمان. بل يتعلق بترتيب الفحوصات بحيث يعمل كلاهما معًا.
السريع والخفيف أولاً، والثقيل لاحقًا
المبدأ الأساسي بسيط: الفحوصات السريعة والخفيفة تُجرى مبكرًا في الـ pipeline. الفحوصات الثقيلة التي تحتاج إلى سياق أكبر تُجرى لاحقًا. لكن هذا لا يتعلق بتقسيم الفحوصات إلى مجموعتين. كل نوع من الفحص له مكان طبيعي يقدم فيه أقصى قيمة بأقل احتكاك.
الرسم البياني أدناه يوضح موقع كل بوابة بالنسبة لمراحل الـ pipeline:
فحص الأسرار: قبل البناء
يجب اكتشاف الأسرار قبل بناء أي شيء. بمجرد تضمين secret في صورة حاوية أو artifact، تصبح إزالته أصعب بكثير. قد تكون الصورة قد دُفعت بالفعل إلى registry، أو سُحبت بواسطة أنظمة أخرى، أو نُشرت في بيئة. حتى لو حذفت الصورة، قد يكون secret مخبأً أو مسجلاً في مكان ما.
قم بتشغيل فحص الأسرار مباشرة بعد checkout الكود، قبل أي خطوة بناء. إذا وجد الـ pipeline API key أو كلمة مرور قاعدة بيانات مكتوبة بشكل ثابت، يحصل المطور على تغذية راجعة فورية. يصلح الملف، يضغط مرة أخرى، ويعاد تشغيل الـ pipeline دون أن ينتظر بناءً كان سيهدر على أي حال.
فحص التبعيات: قبل إنشاء الأرتيفكت
فحص التبعيات يتحقق من المكتبات التي يسحبها مشروعك. يحتاج إلى ملف البيان (manifest) الخاص بالتبعيات، وهو متاح مباشرة بعد checkout. المكان الطبيعي لهذا الفحص هو بعد checkout وقبل بناء artifact.
إذا كانت مكتبة مضافة حديثًا تحتوي على ثغرة حرجة، يفشل الـ pipeline مبكرًا. لا ينتظر المطور البناء، اختبارات الوحدة، أو اختبارات التكامل. يصلح التبعية ويضغط مرة أخرى. هذا هو جوهر التغذية الراجعة المبكرة: فشل سريع على المشاكل التي يكون إصلاحها رخيصًا.
بعض أدوات فحص التبعيات سريعة بما يكفي للتشغيل قبل البناء. البعض الآخر أبطأ. إذا كان الماسح الضوئي الخاص بك يستغرق عدة دقائق، فكر في تشغيله على كل commit للفرع الرئيسي فقط، وعلى pull requests للفروع الفرعية. هذا يحافظ على سرعة التغذية الراجعة للعمل اليومي مع الاستمرار في اكتشاف المشاكل قبل وصولها إلى الإنتاج.
فحص صورة الحاوية: بعد البناء، قبل الـ Registry
فحص صورة الحاوية مختلف. لا يمكنك فحص الصورة حتى توجد. المكان الصحيح هو بعد بناء الصورة، قبل دفعها إلى registry أو استخدامها في أي بيئة.
إذا كانت الصورة تحتوي على ثغرات، يتوقف الـ pipeline هنا. الصورة لا تصل أبدًا إلى staging أو الإنتاج. هذا مهم لأنه بمجرد وجود الصورة في registry، قد تسحبها خطوط أنابيب أو فرق أخرى. إيقاف الـ pipeline عند هذه النقطة يمنع انتشار الصور الضعيفة.
المقايضة هي أن فحص الصورة يستغرق وقتًا. إذا كان فريقك يدفع العديد من commits يوميًا، فإن تشغيل فحوصات كاملة للصور على كل commit يمكن أن يبطئ الـ pipeline بشكل كبير. أحد الأساليب الشائعة هو تشغيل فحص سريع على كل commit وفحص كامل على عمليات الدمج إلى الفرع الرئيسي. نهج آخر هو تخزين نتائج الفحص مؤقتًا وإعادة الفحص فقط عندما تتغير الصورة الأساسية أو التبعيات.
فحص IaC وفحص السياسات: مكانان، غرضان
يمكن تشغيل فحص البنية التحتية ككود (IaC) وفحص السياسات في نقطتين مختلفتين، وكل منهما يخدم غرضًا مختلفًا.
أولاً، قم بتشغيلهما عند كتابة كود البنية التحتية. هذا يعطي المطورين تغذية راجعة سريعة بينما لا يزالون يعملون على التكوين. لا يحتاجون إلى انتظار تشغيل pipeline كامل لمعرفة أن قاعدة مجموعة أمان متساهلة جدًا أو أن مخزن تخزين متاح للعامة.
ثانيًا، قم بتشغيلهما مرة أخرى قبل تطبيق التكوين على بيئة. هذه هي بوابة الامتثال (compliance gate). حتى لو تجاهل المطور التحذير السابق، يفرض الـ pipeline السياسة قبل أن تحدث أي تغييرات في البنية التحتية.
البوابة الأولى هي لراحة المطور. الثانية هي ليقين الامتثال. كلاهما مطلوب، لكن لا يحتاجان إلى تشغيل نفس الفحوصات. يمكن للبوابة المبكرة تشغيل فحوصات أخف، بينما تقوم البوابة اللاحقة بتشغيل مجموعة السياسات الكاملة.
ما يجب تجنبه: بوابة واحدة كبيرة في النهاية
أسوأ نمط هو وضع جميع الفحوصات في كتلة واحدة في نهاية الـ pipeline. هذا يخلق حلقة تغذية راجعة طويلة لكل نوع من المشاكل. secret مفقود، تبعية ضعيفة، ملف IaC تم تكوينه بشكل خاطئ، وثغرة في الحاوية - كلها تُبلغ في نفس الوقت، بعد أن ينتظر المطور خلال البناء، اختبارات الوحدة، اختبارات التكامل، ومرحلة staging.
هذا النمط يجعل الـ pipeline هشًا أيضًا. فحص بطيء واحد يعيق البقية. إذا فشل فحص، يضطر المطور إلى إصلاح المشكلة وانتظار الـ pipeline بأكمله مرة أخرى، بما في ذلك جميع الخطوات التي نجحت بالفعل.
وزع البوابات عبر الـ pipeline بحيث يكون لكل مرحلة مسؤولية واضحة. المراحل المبكرة تلتقط المشاكل الرخيصة بسرعة. المراحل اللاحقة تلتقط المشاكل المكلفة قبل وصولها إلى الإنتاج.
ضع في اعتبارك تكلفة الفحص
بعض الفحوصات مكلفة. عمليات البحث الكاملة في قواعد بيانات التبعيات، التحليل العميق للحاويات، وتقييمات السياسات الشاملة يمكن أن تستغرق دقائق وتستهلك موارد حاسوبية كبيرة. تشغيل هذه على كل commit لكل فرع هو إهدار.
الحل ليس تخطي الفحوصات. بل هو وضعها بشكل استراتيجي. قم بتشغيل الفحوصات المكلفة فقط على الفرع الرئيسي أو على pull requests التي تستهدف الفرع الرئيسي. بالنسبة للفروع الفرعية، قم بتشغيل الفحوصات السريعة فقط: فحص الأسرار، فحص التبعيات السريع، والتحقق من الصياغة (syntax validation). هذا يحافظ على سرعة الـ pipeline للعمل اليومي مع الاستمرار في فرض الجودة قبل وصول الكود إلى الإنتاج.
قائمة مراجعة عملية
- فحص الأسرار يُجرى قبل البناء، مباشرة بعد checkout.
- فحص التبعيات يُجرى قبل إنشاء artifact، باستخدام ملف البيان.
- فحص صورة الحاوية يُجرى بعد البناء، قبل الدفع إلى registry.
- فحص IaC يُجرى في نقطتين: أثناء التطوير وقبل تطبيق البيئة.
- الفحوصات المكلفة تُجرى على الفرع الرئيسي أو أهداف الدمج فقط.
- الفحوصات السريعة تُجرى على كل commit لجميع الفروع.
الخلاصة
البوابة الموضوعة بشكل جيد تلتقط المشاكل مبكرًا، عندما يكون إصلاحها رخيصًا. البوابة الموضوعة بشكل سيء تلتقط المشاكل متأخرًا، بعد إهدار الوقت والموارد الحاسوبية. الهدف ليس فحص كل شيء في كل مكان. بل هو وضع كل فحص حيث يعطي أسرع تغذية راجعة للمشاكل التي صُمم لاكتشافها. عندما تتقن التنسيب، يحصل المطورون على مكاسب سريعة، ويحصل الامتثال على ضماناته، ويظل الـ pipeline سريعًا بما يكفي بحيث لا يرغب أحد في تجاوزه.