DevOps and Infrastructure

كتل Terraform الديناميكية و for_each: أنماط متقدمة لإدارة المجموعات ذات الطول المتغير

غالبًا ما يتضمن البنية كرمز (IaC) إدارة موارد بتكوينات لا تكون ثابتة عند وقت الترجمة. سواء كنت تقوم بتوفير مجموعات أمان AWS، أو تكوين نشرات Kubernetes، أو إعداد واجهات شبكة Azure، فإن عدد الكتل المتداخلة أو عناصر القائمة يتغير غالبًا. يؤدي تثبيت هذه التكوينات يدويًا إلى تكرار الكود وكوابيس الصيانة. هنا تبرز كتل Terraform الديناميكية وحجج for_each التمهيدية.

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

فهم اللبنات الأساسية

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

من ناحية أخرى، تتيح لك الكتل الديناميكية إنشاء كتل متداخلة (مثل ingress في مجموعة أمان) داخل مورد بشكل ديناميكي. تقوم بالتكرار فوق قائمة أو خريطة وإدخال تكوين الكتلة المقابل لكل عنصر.

النمط 1: الكتلة الديناميكية المتداخلة

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

variable "ingress_rules" {
  type = list(object({
    from_port   = number
    to_port     = number
    protocol    = string
    cidr_blocks = list(string)
  }))
  default = []
}

resource "aws_security_group" "example" {
  name = "example-sg"

  dynamic "ingress" {
    for_each = var.ingress_rules
    content {
      from_port   = ingress.value.from_port
      to_port     = ingress.value.to_port
      protocol    = ingress.value.protocol
      cidr_blocks = ingress.value.cidr_blocks
    }
  }
}

# Usage in main.tf
resource "aws_security_group" "web_sg" {
  ingress_rules = [
    {
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    },
    {
      from_port   = 22
      to_port     = 22
      protocol    = "tcp"
      cidr_blocks = ["10.0.0.0/8"]
    }
  ]
}

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

النمط 2: دمج for_each والكتل الديناميكية

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

من خلال الجمع بين for_each على المورد و الكتل الديناميكية داخل المورد، تحقق درجة عالية من المرونة.

variable "services" {
  type = map(object({
    name = string
    ports = list(object({
      containerPort = number
      protocol      = string
    }))
  }))
}

resource "aws_lb_target_group" "this" {
  for_each = var.services

  name     = each.key
  port     = 80
  protocol = "HTTP"

  # Note: Dynamic blocks inside target groups are limited, 
  # but this pattern applies to resources like aws_instance or aws_lb_listener
  
  tags = {
    Name = each.key
  }
}

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

أفضل الممارسات واعتبارات الأداء

عند إدارة المجموعات ذات الطول المتغير، ضع في اعتبارك ما يلي:

  • ثبات المفاتيح: عند استخدام for_each، تأكد من أن مفاتيحك مستقرة. سيؤدي تغيير مفتاح في الخريطة إلى جعل Terraform يدمر ويعيد إنشاء المورد بدلاً من تحديثه.
  • تبسيط المتغيرات: استخدم أنواع متغيرات منظمة (خرائط من الكائنات أو قوائم من الكائنات) للتحقق من صحة المدخلات مبكرًا. يمنع هذا الأخطاء في وقت التشغيل عندما تحاول الكتل الديناميكية الوصول إلى سمات غير معرفة.
  • القراءة: بينما هي قوية، يمكن أن يجعل التداخل المفرط للكتل الديناميكية الكود صعب القراءة. استخرج التكوينات المعقدة إلى قيم محلية أو وحدات نمطية منفصلة إذا أصبح المنطق معقدًا جدًا.

الخاتمة

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

Share: