Terraform Drift: اكشف تغييرات السحابة قبل apply
هتطلع من المقال بخطوة عملية تكشف أي تغيير يدوي حصل في السحابة قبل ما يتحول لمفاجأة وقت deploy.
مستوى القارئ: متوسط
المشكلة باختصار
الـ Terraform state مش دايمًا مرآة كاملة للواقع. لو حد عدّل Security Group من AWS Console، أو غيّر حجم instance أثناء incident، الكود عندك يفضل شكله سليم. اللي بيحصل فعلاً إن أول terraform apply بعد كده يكتشف الفرق متأخر.
في فريق عنده 40 خدمة و3 بيئات، مراجعة شهرية واحدة ممكن تسيب drift لمدة 720 ساعة. فحص يومي يقلل نافذة الاكتشاف إلى 24 ساعة. ولو شغّلته على كل Pull Request، ممكن تشوف المشكلة خلال أقل من ساعة من تغيير الكود.
مثال بسيط قبل التعريف العلمي
ركز في المثال ده. عندك rule في Terraform بتسمح لـ 443 فقط. أثناء incident، حد فتح 22 مؤقتًا من AWS Console عشان يدخل على VM. المشكلة مش في فتحه وقت الطوارئ. المشكلة إنه نسي يرجّعها.
بعد أسبوع، deploy جديد يعمل terraform plan. Terraform يشوف إن الواقع مختلف عن الكود، ويقترح حذف rule الخاصة بـ 22. ده كويس، لكن الاكتشاف جاء وقت تغيير إنتاج. أفضل طريقة إنك تعرف drift ده في نفس اليوم، برسالة واضحة، بدون ما تعمل apply تلقائي.
تعريفًا: Terraform drift هو اختلاف بين التكوين المكتوب في ملفات .tf، والـ state، وحالة الموارد الحقيقية عند مزود السحابة. حسب توثيق Terraform، أمر plan يقرأ حالة الموارد الموجودة ويقارنها بالتكوين الحالي قبل اقتراح أي تغييرات.
الحل: GitHub Actions يعمل plan كتنبيه فقط
استخدم Workflow مجدول. الهدف هنا مش الإصلاح التلقائي. الهدف إن الـ CI يقول لك: فيه فرق محتاج مراجعة. الافتراض إن عندك remote backend مضبوط، وصلاحيات قراءة كافية لمزود السحابة، وTerraform version مثبت في المشروع.
name: terraform-drift-check
on:
schedule:
- cron: "15 5 * * *"
workflow_dispatch:
permissions:
contents: read
pull-requests: write
jobs:
drift:
runs-on: ubuntu-latest
defaults:
run:
working-directory: infra
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.8.5
- name: Init
run: terraform init -input=false
- name: Plan drift
id: plan
continue-on-error: true
run: terraform plan -no-color -detailed-exitcode -out=tfplan
- name: Fail only on Terraform error
if: steps.plan.outcome == 'failure' && steps.plan.outputs.exitcode == '1'
run: exit 1
- name: Report drift
if: steps.plan.outcome == 'failure'
run: |
echo "Terraform drift detected. Review the plan before apply."
terraform show -no-color tfplan | sed -n '1,120p'
ملاحظة مهمة: -detailed-exitcode يخلي Terraform يرجع 0 لو مفيش تغييرات، 1 لو فيه خطأ، و2 لو فيه diff. ده مناسب جدًا للأتمتة، لأنك تفرق بين drift حقيقي وخطأ في credentials أو provider.
القياس قبل وبعد
لو المراجعة يدوية مرة كل شهر، متوسط زمن اكتشاف drift ممكن يوصل 720 ساعة. مع فحص يومي الساعة 5:15 صباحًا، الرقم ينزل إلى 24 ساعة كحد أقصى. ومع تشغيل workflow يدوي قبل release كبير، هتقلل المفاجآت وقت apply.
الـ trade-off هنا واضح. بتكسب اكتشاف أسرع وتاريخ تشغيل داخل GitHub Actions. بتخسر دقائق CI يومية، واحتمال ضوضاء لو في تغييرات مقصودة خارج Terraform أثناء incidents. لذلك خليه alert فقط في البداية، وبعد شهر من الاستقرار قرر هل تضيف comment على PR أو Slack notification.
أخطاء شائعة في الإعداد
- تشغيل
terraform applyتلقائيًا لإصلاح drift. الطريقة دي بتفشل وقت incidents لأنها قد ترجع تغييرًا مقصودًا قبل مراجعة بشرية. - استخدام
-refresh=falseفي فحص drift. هذا يلغي أهم جزء: قراءة الواقع من مزود السحابة. - تشغيل الفحص على كل دقيقة. GitHub Actions يدعم cron، لكن الفحص المتكرر جدًا يرفع الضوضاء واستهلاك API بدون مكسب حقيقي لمعظم الفرق.
- ترك plan كامل في logs عامة. بعض الموارد قد تظهر قيم حساسة، فراجع سياسة السرية قبل مشاركة المخرجات.
متى لا تستخدم هذه الطريقة
لا تستخدمها لو البنية التحتية كلها مؤقتة وبتتهد يوميًا. لا تبدأ بها لو Terraform state نفسه غير منظم أو local على جهاز شخص واحد. ولا تعتمد عليها كبديل لـ policy-as-code لو مشكلتك الأساسية إن المطورين يضيفوا موارد مخالفة من الكود نفسه.
لو عندك بيئة صغيرة جدًا فيها مشروع واحد وموارد قليلة، فحص أسبوعي يدوي ممكن يكون كافي. أما لو عندك أكثر من بيئة إنتاجية أو أكثر من شخص عنده صلاحية Console، الفحص اليومي غالبًا يستحق التكلفة.
مصادر
- توثيق Terraform لأمر
planوخيارات-detailed-exitcodeو-refresh=false: HashiCorp Terraform plan command. - شرح Terraform الرسمي لفكرة الخطة قبل التطبيق واستخدام plan داخل CI/CD: Create a Terraform plan.
- توثيق GitHub Actions للـ scheduled workflows وصيغة cron: GitHub Actions scheduled events.
الخطوة التالية
افتح repo البنية التحتية عندك، وضيف workflow الفحص اليومي على بيئة staging فقط لمدة أسبوع. لو ظهر drift، راجع هل التغيير كان incident مقصود أم تعديل يدوي لازم يتحول لكود.