أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

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

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

أتمتة اكتشاف Terraform Drift بـ GitHub Actions كل 6 ساعات

📅 ٢٠ أبريل ٢٠٢٦⏱ 5 دقائق قراءة
أتمتة اكتشاف Terraform Drift بـ GitHub Actions كل 6 ساعات

لو الـ infrastructure بتاعك متدارة بـ Terraform، أكبر مخاطرة بتتجاهلها هي الـ drift: تعديل يدوي في الكونسول بيخلي الـ state مش متطابق مع الكود. الحل مش إنك تمنع الناس، الحل إنك تكتشف الفرق خلال 6 ساعات قبل ما يتحوّل لـ outage.

الدليل الكامل لأتمتة اكتشاف Terraform Drift

المشكلة باختصار

بتعمل terraform apply الإثنين، كله تمام. يوم الأربعاء حد فتح AWS Console وعدّل Security Group بسرعة علشان يحل incident. مر أسبوع. بقى فيه فرق بين الـ state المحفوظ والواقع الفعلي على AWS. جه يوم الـ deploy الجديد، الـ plan بيقرّر "يصلح" التعديل الطارئ ده ويرجّع القاعدة القديمة — وساعتها بالظبط بيقع الموقع مرة تانية.

ده اسمه configuration drift. مش حالة نادرة، بيحصل في كل فريق أكبر من شخصين. الحل إنك تكتشفه بشكل تلقائي قبل ما حد يعمل apply.

صفوف من خوادم في data center ترمز لـ infrastructure سحابية يراقبها Terraform لاكتشاف أي تعديل يدوي

مثال قبل المفهوم: دفتر مفاتيح الشقة

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

Terraform drift هو نفس القصة بالظبط. الـ state file هو الدفتر. الكلاود هو الباب. وأي تعديل مباشر على الباب من غير ما يتحدث الدفتر اسمه drift.

تعريف علمي دقيق

الـ configuration drift في Terraform هو الفرق بين ثلاث حالات: (أ) الموارد المُعرّفة في ملفات .tf، (ب) الـ state اللي Terraform بيخزّنه في terraform.tfstate (محليًا أو remote)، (ج) الحالة الفعلية للموارد عند مزود السحابة. لما يحصل تعديل مباشر على (ج) من غير ما يمر عبر Terraform، بتظهر فجوة بين الثلاثة. Terraform بيستخدم أمر plan علشان يقارن بينهم ويطلع الفرق.

الأداة الأساسية: detailed-exitcode

المفتاح كله في flag واحد: terraform plan -detailed-exitcode. الأمر ده بيرجّع:

  • 0 — مفيش تغييرات، كل حاجة متطابقة.
  • 1 — خطأ حصل أثناء تشغيل الـ plan.
  • 2 — فيه فرق، يعني في drift أو تعديل مش متحوّل لـ apply.

بدون الـ flag ده، الـ plan بيرجّع 0 على طول حتى لو فيه 300 resource هيتغيّر، وده السبب اللي بيخلي الناس تفتكر إن CI الأخضر = infra سليمة. الكلام ده غلط.

لوحة تحليلات تعرض نتائج تشغيلات GitHub Actions المجدولة لاكتشاف drift في Terraform

الـ workflow الكامل

الـ workflow ده بيشتغل كل 6 ساعات، وبيفتح GitHub Issue تلقائيًا لو لقى drift. ملف .github/workflows/drift.yml:

YAML
name: terraform-drift
on:
  schedule:
    - cron: "0 */6 * * *"
  workflow_dispatch:

permissions:
  contents: read
  issues: write
  id-token: write

jobs:
  drift:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_READONLY_ROLE }}
          aws-region: eu-west-1

      - uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.9.8

      - name: terraform init
        run: terraform init -input=false

      - name: detect drift
        id: plan
        run: |
          set +e
          terraform plan -detailed-exitcode -lock=false -no-color -out=tfplan
          echo "exitcode=$?" >> "$GITHUB_OUTPUT"

      - name: open issue on drift
        if: steps.plan.outputs.exitcode == '2'
        uses: actions/github-script@v7
        with:
          script: |
            const title = `Drift detected on ${context.ref}`;
            const body  = "terraform plan -detailed-exitcode = 2. Review changes and reconcile.";
            const { data } = await github.rest.issues.listForRepo({
              owner: context.repo.owner,
              repo:  context.repo.repo,
              labels: "drift",
              state: "open"
            });
            if (data.length === 0) {
              await github.rest.issues.create({
                owner: context.repo.owner,
                repo:  context.repo.repo,
                title, body, labels: ["drift"]
              });
            }

      - name: fail job on real error
        if: steps.plan.outputs.exitcode == '1'
        run: exit 1

ليه IAM Role بدلاً من access keys ثابتة؟

الصلاحية هنا read-only على AWS. بنستخدم OIDC بين GitHub و AWS (عبر id-token: write) علشان نتجنب تخزين AWS_ACCESS_KEY_ID وAWS_SECRET_ACCESS_KEY كـ secrets ثابتة. لو الـ token اتسرّب، ميقدرش يتستعمل برا GitHub Actions، ومدته 15 دقيقة فقط. ده الفرق بين mitigation قوي ومفتاح مسرّب بيشتغل سنة.

أرقام حقيقية من الإنتاج

على مشروع فيه 180 resource على AWS + Cloudflare، الـ workflow بياخد في المتوسط 48 ثانية، وبيكلّف 0 دولار لأن GitHub Actions Free tier كفاية للتشغيل كل 6 ساعات (120 تشغيلة شهريًا × دقيقة ≈ 120 دقيقة). لو الـ infra أكبر ومشتغّلة على Terraform Cloud، التكلفة ممكن توصل 3–5 دولار شهريًا فقط.

Trade-offs اللي لازم تعرفها

بتكسب: كشف مبكر للتعديلات اليدوية، توثيق تاريخي لكل drift في GitHub Issues، ومعرفة إن CI الأخضر فعلًا معناه infra سليمة.

بتخسر: الـ workflow بيقرأ الـ state ومعناه لازم يكون عنده صلاحية قراءة على كل الـ resources، وده بيخلق attack surface جديد. خفّف المخاطرة بـ OIDC + role مخصص للـ drift detection فقط + audit logging على CloudTrail.

الافتراض هنا إن الـ state متخزّن remotely في S3 مع DynamoDB lock. لو الـ state محلي على كمبيوتر حد من الفريق، الـ drift detection ملوش معنى أصلًا، والأولوية إنك تنقل الـ state لـ remote backend أول.

متى لا تستخدم هذه الطريقة

لو الـ infra بتتغير كل ساعة بشكل مشروع (auto-scaling groups بتضيف instances، Lambda aliases بتتحدث من CI تاني، ECS tasks بتتبدّل)، الـ workflow ده هيفتح Issue كل تشغيلة وهيحصل noise قاتل. الحل مش إنك تلغيه، الحل إنك تستخدم lifecycle { ignore_changes = [...] } على الحقول اللي بتتغير بره Terraform عن قصد. لو مش قادر تحدد الحقول دي بدقة، ابدأ بـ refactor للكود قبل ما تفعّل drift detection، وإلا الفريق هيطفّي التنبيهات خلال أسبوع.

الخطوة التالية

افتح أي ريبو فيه Terraform شغّال دلوقتي، وضيف الـ workflow اللي فوق في .github/workflows/drift.yml. شغّله يدويًا مرة عبر زر Run workflow في تبويب Actions وشوف الـ exit code. لو طلع 2 من أول تشغيلة، إنت لقيت drift كان مختفي. لو طلع 0، عندك نظام كشف شغّال ومجاني يحميك كل 6 ساعات.

مصادر

  • HashiCorp Docs — terraform plan و detailed-exitcode
  • Firefly — Continuous Drift Detection in CI/CD with GitHub Actions
  • Terrateam — Implementing Terraform drift detection with GitHub Actions
  • OneUptime — Drift Detection in Terraform CI/CD (2026)
  • Scalr — Terraform Drift: Detect, Prevent & Fix
  • GitHub Docs — OIDC مع AWS

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة