ما المقصود بوحدات Terraform وكيف تعمل؟

والمثير للدهشة أن الكثير من المبتدئين يتخطون وحدات Terraform من أجل البساطة ، أو هكذا يعتقدون.

في وقت لاحق ، وجدوا أنفسهم يمرون بمئات الأسطر من كود التكوين.

أفترض أنك تعرف بالفعل بعض الأساسيات حول Terraform ، وقد حاولت استخدامها من قبل. إذا لم يكن كذلك ، تحقق من هذه النظرة العامة على Terraform وهذا الفيديو التعليمي قبل متابعة القراءة.

يرجى ملاحظة ما يلي: لا أستخدم أمثلة التعليمات البرمجية الحقيقية مع مزود معين مثل AWS أو Google عن قصد ، فقط من أجل البساطة.

وحدات Terraform

أنت تكتب بالفعل وحدات

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

أي ملف تكوين Terraform ( .tf) في دليل ، حتى لو كان واحدًا فقط ، يشكل وحدة نمطية.

ماذا تفعل الوحدة؟

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

لنفترض أن لدينا خادمًا افتراضيًا به بعض الميزات المستضافة في السحابة. ما مجموعة الموارد التي قد تصف ذلك الخادم؟ فمثلا:

  • الجهاز الظاهري نفسه ، الذي تم إنشاؤه من بعض الصور
  • جهاز كتلة متصل بحجم محدد لتخزين إضافي
  • عنوان IP عام ثابت يتم تعيينه لواجهة الشبكة الافتراضية للخادم
  • مجموعة من قواعد جدار الحماية ليتم إرفاقها بالخادم
  • أشياء أخرى مثل جهاز كتلة آخر ، وواجهة شبكة إضافية ، وما إلى ذلك

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

هذا مثال يوضح كيف يمكن تسمية وحدة "الخادم" الخاصة بنا.

" لاستدعاء وحدة نمطية " وسيلة لاستخدامها في ملف التكوين.

هنا نقوم بإنشاء 5 مثيلات من "الخادم" باستخدام مجموعة واحدة من التكوينات (في الوحدة النمطية):

module "server" { count = 5 source = "./module_server" some_variable = some_value }

منظمة الوحدة: الطفل والجذر

بالطبع ، قد ترغب في إنشاء أكثر من وحدة واحدة. فيما يلي بعض الأمثلة الشائعة:

  • شبكة مثل السحابة الخاصة الافتراضية (VPC)
  • استضافة المحتوى الثابت (أي الحاويات)
  • موازن التحميل والموارد ذات الصلة
  • تكوين التسجيل
  • أو أي شيء آخر تعتبره مكونًا منطقيًا متميزًا للبنية التحتية

لنفترض أن لدينا وحدتين مختلفتين: وحدة "خادم" ووحدة "شبكة". الوحدة التي تسمى "الشبكة" هي المكان الذي نحدد فيه شبكتنا الافتراضية ونهيئها ونضع الخوادم فيها:

module "server" { source = "./module_server" some_variable = some_value } module "network" { source = "./module_network" some_other_variable = some_other_value }

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

يمكن الحصول على وحدة فرعية من عدد من الأماكن:

  • المسارات المحلية
  • سجل Terraform الرسمي - إذا كنت على دراية بالسجلات الأخرى مثل Docker Registry ، فأنت تفهم الفكرة بالفعل
  • مستودع Git (مخصص أو GitHub / BitBucket)
  • عنوان HTTP URL لأرشيف .zip مع الوحدة النمطية

ولكن كيف يمكنك تمرير تفاصيل الموارد بين الوحدات؟

في مثالنا ، يجب إنشاء الخوادم في شبكة. إذن كيف يمكننا إخبار وحدة "الخادم" بإنشاء أجهزة افتراضية في شبكة تم إنشاؤها في وحدة تسمى "الشبكة"؟

هذا هو المكان الذي يأتي فيه التغليف .

تغليف الوحدة النمطية

يتكون التغليف في Terraform من مفهومين أساسيين: نطاق الوحدة النمطية والتعرض الواضح للموارد.

نطاق الوحدة

يتم عزل جميع مثيلات الموارد ، والأسماء ، وبالتالي رؤية المورد ، في نطاق الوحدة النمطية. على سبيل المثال ، الوحدة "أ" لا يمكنها رؤية الموارد الموجودة في الوحدة "ب" ولا تعرف عنها افتراضيًا.

تضمن رؤية الموارد ، التي تسمى أحيانًا عزل الموارد ، أن الموارد سيكون لها أسماء فريدة داخل مساحة اسم الوحدة النمطية. على سبيل المثال ، من خلال 5 مثيلات لوحدة "الخادم":

module.server[0].resource_type.resource_name module.server[1].resource_type.resource_name module.server[2].resource_type.resource_name ...

من ناحية أخرى ، يمكننا إنشاء مثيلين من نفس الوحدة بأسماء مختلفة:

module "server-alpha" { source = "./module_server" some_variable = some_value } module "server-beta" { source = "./module_server" some_variable = some_value }

في هذه الحالة ، ستكون تسمية أو عنوان الموارد كما يلي:

module.server-alpha.resource_type.resource_name module.server-beta.resource_type.resource_name

التعرض الصريح للموارد

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

بشكل افتراضي ، لا تعرف الوحدة النمطية "الخادم" الخاصة بنا عن الشبكة التي تم إنشاؤها في وحدة "الشبكة".

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

يجب أن تعلن الوحدة النمطية "server" عن variableاستخدامها لاحقًا كمدخل:

This explicit declaration of the output is the way to expose some resource (or information about it) outside — to the scope of the 'root' module, hence to make it available for other modules.

Next, when we call the child module "server" in the root module, we should assign the output from the "network" module to the variable of the "server" module:

network_id = module.network.network_id

Here's what the final code for calling our child modules will look like:

module "server" { count = 5 source = "./module_server" some_variable = some_value network_id = module.network.network_id } module "network" { source = "./module_network" some_other_variable = some_other_value }

This example configuration would create 5 instances of the same server, with all the necessary resources, in the network we created with as a separate module.

Wrapping up

Now you should understand what modules are and what do they do.

If you're at the beginning of your Terraform journey, here are some suggestions for the next steps.

أنا أشجعك على أخذ هذا البرنامج التعليمي القصير من HashiCorp ، مبتكري Terraform ، حول الوحدات: "تنظيم التكوين".

يوجد أيضًا دليل دراسة شامل رائع يغطي كل شيء من المفاهيم المبتدئة إلى المفاهيم المتقدمة حول Terraform: "دليل الدراسة - شهادة Terraform Associate".

هيكل الكود المعياري يجعل التكوين الخاص بك أكثر مرونة ويسهل على الآخرين فهمه. هذا الأخير مفيد بشكل خاص للفريق.

إذا أعجبك المقال ، فاتبعني على Twitter (vasylenko) حيث أشارك أحيانًا نتائجي ونصائح حول Terraform و AWS و Ansible وغيرها من التقنيات المتعلقة بـ DevOps.