arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 15

العربية (Arabic)

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

أداة Terraform

أمثلة عن بنية الكود

hashtag
بنى الكود في Terraform

circle-info

تُظهر هذه الأمثلة استعمال لموفر AWS ولكن يمكن تطبيق غالبية المبادئ الموضحة في الأمثلة على موفري السحابة الآخرين بالإضافة إلى أنواع أخرى من مقدمي الخدمات (DNS ، DB ، المراقبة ، إلخ)

النمط
الوصف
قابلة القراءة من الكتاب

hashtag
بنى الكود في Terragrunt

Type
Description
Readiness

البنى الصغيرة باستعمال Terraform

المصدر:

يحتوي هذا المثال على كود لهيكلة كود Terraform لبنية تحتية صغيرة، حيث لا وجود لاعتمادات خارجية

circle-check
  • ممتاز للبدء بتعلم Terraform وإعادة هيكلة الكود (refactoring)

صغير

بعض الموارد، لا وجود لاعتماديات خارجية، استعمال حساب AWS واحد، استعمال منطقة وحيدة، استعمال بيئة وحيدة

نعم

متوسط

عدة حسابات AWS وعدة بيئات، استعمال وحدات جاهزة باستخدام Terraform

نعم

كبير

العديد من حسابات AWS، العديد من المناطق، حاجة ملحة لتقليل عمليات النسخ واللصق، استعمال وحدات مخصصة، استعمال كبير للتراكيب باستخدام Terraform

جاري العمل عليه

كبير جداً

العديد من الموفرين (AWS, GCP, Azure). استعمال للعديد من الخدمات السحابية في عملية deployment باستخدام Terraform

لا

متوسط

عدة حسابات AWS وعدة بيئات، استعمال وحدات جاهزة باستخدام Terragrunt

لا

كبير

العديد من حسابات AWS، العديد من المناطق، حاجة ملحة لتقليل عمليات النسخ واللصق، استعمال وحدات مخصصة، استعمال كبير للتراكيب باستخدام Terragrunt

لا

كبير جداً

العديد من الموفرين (AWS, GCP, Azure). استعمال للعديد من الخدمات السحابية في عملية deployment باستخدام Terragrunt.

لا

ممتاز لبناء الوحدات الصغيرة

  • جيد لاستعمال الوحدات الصغيرة (eg, terraform-aws-atlantisarrow-up-right)

  • جيد عند وجود عدد صغير من الموارد (أقل من 20-30)

  • circle-exclamation

    وجود ملف حالة وحيد Single state file من أجل كل الموارد سيجعل أداة Terraform بطيئة كلما زاد عدد الموارد المعرفة (خذ بعين الاعتبار استعمال الوسيط target- للحد من الموارد التي تتعامل معها عند طلب الأداة)

    https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/small-terraformarrow-up-right

    أداة Terragrunt

    مرحباً

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

    يعد الـ Terraformarrow-up-rightمشروع جديد نسبياً (مثل معظم أدوات الـ DevOps )، صدر في عام 2014.

    تعد أداة Terraform قوية (إن لم تكن الأقوى الآن) وواحدة من أكثر الأدوات استعمالاً لتوصيف البنى التحتية المعلوماتية باستعمال الكود (Infrastructure as code). تسمح هذه الأداة للمطورين بالقيام بالكثير من الوظائف ولا تمنعهم من فعل الأشياء بطرق يصعب دعمها أو التواصل معها.

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

    تم البدء بكتابة هذا الكتاب في مدريد في سنة 2018 وهو متوفر مجاناً على الرابط -

    https://www.terraform-best-practices.com/arrow-up-right

    تم التعديل على هذا الكتاب بعد عدة سنين لإضافة أفضل الممارسات المتوفرة لإصدار Terraform 1.0 ، هذا الكتاب يجب أن يحتوي أفضل الممارسات والتوصيات الغير القابلة للجدل ليتم استعمالها من قبل مستخدمي الـ Terraform

    hashtag
    الرعاة

    Please if you want to become a sponsor.

    hashtag
    الترجمات

    اتصل بي إذا كنت تود المساعدة بالترجمة إلى لغات أخرى

    hashtag
    المساهمات

    أرغب دائمًا في الحصول على تعليقات وتحديثات لهذا الكتاب بينما ينضج المجتمع ويتم تنفيذ الأفكار الجديدة والتحقق منها بمرور الوقت.

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

    hashtag
    المؤلفون

    هذا الكتاب من إعداد بمساعدة مساهمين ومترجمين مختلفين.

    hashtag
    الترخيص

    هذا العمل مرخص بموجب ترخيص Apache 2. انظر LICENSE للحصول على التفاصيل الكاملة.

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

    حقوق النشر © 2018-2023 Anton Babenko.

    بنية الكود

    الأسئلة المتعلقة ببنية كود Terraform هي الأكثر شيوعًا في المجتمع. في الكثير من الأحيان فكر الجميع في أفضل بنية كود ممكن الحصول عليها للمشروع.

    hashtag
    كيف يجب هيكلة مشروع Terraform؟

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

    • ما هو مدى تعقيد مشروعك؟

      • عدد الموارد المرتبطة ببعضها

      • عدد الموفرين (انظر الملاحظة أدناه عن "logical providers")

    • كم مرة تحتاج إلى تغيير في البنية التحتية؟

      • من مرة في الشهر/الأسبوع/اليوم؟

      • إلى تغيير مستمر (عند كل commit جديدة)

    • مصادر تغيير الكود، هل تسمح لمخدم CI بتعديل repository عند بناء artifact جديدة؟

      • يسمح فقط للمطورين بإضافة تغييرات إلى repository الخاصة بالبنية التحتية

      • يسمح لأي أحد باقتراح تغيير من خلال فتح PR (متضمناً المهام الأتوماتيكية التي يقوم بها مخدم CI)

    • ما هي المنصة أو الخدمة التي تستعملها لعملية deployment؟

      • AWS CodeDeploy, Kubernetes, OpenShift (يحتاج كل حل إلى معاملة مختلفة)

    • كيف يتم فرز البيئات المختلفة؟

      • من خلال بيئة العمل(environment)، المنطقة (region)، المشروع (project)

    circle-info

    Logical providers

    هي الموفرات التي تعمل كلياً ضمن Terraform ولا تتعامل غالباً مع أي خدمة خارجية، لذا يمكن أن نعتبرها أدوات بتعقيد O(1). أكثر هذه الموفرات شهرة هي , , , , .

    hashtag
    مقدمة إلى هيكلة مشروع Terraform

    عند بداية التعامل مع Terraform أو عندما تريد أن تكتب مثالاً فإن وضع كل الكود في ملف main.tf تعتبر فكرة جيدة، ولكن في كل الحالات الأخرى يجب تقسيم الكود منطقياً إلى ملفات مختلفة كالتالي:

    • ملف main.tf, والذي يستدعي الوحدات المختلفة (modules), والوسطاء المحلية (locals)، ومصادر البيانات (data) لتوليد كافة الموارد (resources)

    • ملف variables.tf، الذي يحتوي على تعريف للوسطاء (variables) المراد استعمالها فيmain.tf

    لا يجب استعمال terraform.tfvarsفي أي مكان ما عدا .

    hashtag
    كيف يجب أن نفكر عند هيكلة مشروع Terraform

    circle-info

    الرجاء التأكد من فهم المفاهيم الرئيسية , , لأهميتها لفهم الأمثلة التالية

    hashtag
    التوصيات العامة لهيكلة الكود

    • إنه من الأسهل والأسرع التعامل مع عدد قليل من الموارد

      • إن كل من تعليمتي terraform planوterraform apply تقوم باستدعاء cloud API للتحقق من حالة الموارد

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

    hashtag
    تنسيق وحدات وتركيبات البنى التحتية

    وجود بنية تحتية صغيرة يعني وجود عدد صغير من الاعتماديات (dependencies) والموارد، كلما كبر المشروع فإن أهمية ربط البنى المختلفة وتمرير المتحولات في التركيب تصبح واضحة اكثر.

    يوجد على الأقل 5 أدوات تنسيقات مستقلة التي يمكن للمطور أن يستعملها:

    1. يكفي للمطور أن يستعمل Terraform

    2. استعمال أداة Terragrunt، وهي أداة orchestration تستعمل لتنسيق كل البنية التحتية والاعتماديات، تعمل هذه الأداة مع مختلف الوحدات (modules) والتراكيب (compositions) لذلك تخفف من تكرار الكود (إعادة اختراع العجلة)

    3. استعمال scripts خاصة بالشركة (In-house scripts)، تم استعمالها كبداية لعمليات التنسيق قبل صدور Terragrunt

    في هذا الكتاب نقوم فقط بعرض الحلين الأولين (Terraform only and Terragrunt.)

    شاهد أمثلة عن أو في الفصل القادم

    المفاهيم الأساسية

    تصف جميع مصطلحات تعريف البنى التحتية بالتفصيل. اقرأها بعناية لفهم بقية هذا القسم.

    يشرح هذا القسم المفاهيم الأساسية المستخدمة في الكتاب

    hashtag
    المورد (Resource)

    المورد هو aws_vpc، aws_db_instance الخ...، ينتمي المورد إلى موفر معين (provider) ويقبل الوسيطات (arguments) ويولد المخرجات (outputs) وله دورات حياة (lifecycles). يمكن إنشاء مورد واسترجاع معلوماته وتحديثه وحذفه.

    ملفoutputs.tf، الذي يعرف خرج الموارد المولدة من قبلmain.tf
  • ملفversions.tf ، الذي يحتوي متطلبات الإصدار الخاصة بـ Terraform و الموفرين

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

    • عزل الموارد غير المرتبطة ببعضها في تراكيب مختلفة يقلل الخطر في حال حدوث مشكلة ما

  • استعمل ملف الحالة المخرن عن بعد

    • حاسبك الشخصي لا يمثل عكس لحقيقة البنية التحتية

    • إدارة tfstate في git أمر كارثي

    • لاحقاً عند توسع البنية في اتجاهات عدة (عدد الموارد وعدد dependencies)، سيكون استعمال هذا الملف أسهل للتحكم بهذه البنية

  • تمرن على بنية وطرق تسمية متسقة

    • مثل الكود العادي، فإن كود Terraform يجب أن يكون مقروءاً، الاتساق سيساعد عندما تريد التحقق من تعديلات تمت إضافتها من 6 أشهر ماضية

    • من الممكن أن تنقل موارد لم يتم تعريفها سابقاً إلى ملف Terraform State، لكن وجود كود غير متسق سيصعب الأمر

  • قم ببناء وحدة (modules) بسيطة قدر الإمكان

  • لا تقم باستعمال قيم ثابتة (hardcoded) إذا كنت تستطيع تمريرها كمتحول أو الحصول عليها من مصدر بيانات

  • استعمل مصادر البيانات و terraform_remote_state كغراء بين وحدات البنية التحتية في التركيب

  • استعمال أداة Ansible أو أي أداة أتمتة (Autoamtion tools) . يتم استعمالها في حال تم تبني Terraform بعد استعمال Ansible، أو في حال استعمال Ansible UI.

  • أستعمال أداة Crossplanearrow-up-right و الأدوات الملهمة من قبل Kubernetes. من المنطقي أحياناً استعمال Kubernetes لتنسيق Terraform. لمزيد من المعلومات شاهد هذا الفيديو Crossplane vs Terraformarrow-up-right

  • randomarrow-up-right
    localarrow-up-right
    terraformarrow-up-right
    nullarrow-up-right
    timearrow-up-right
    compositionarrow-up-right
    resource module
    infrastructure module
    composition
    Terraform
    Terragrunt
    hashtag
    وحدة الموارد (Resource module)

    وحدة الموارد هي مجموعة من الموارد المرتبطة ببعضها والتي تقوم مع بعضها بتنفيذ وظيفة معينة (لنأخذ AWS VPC Terraform modulearrow-up-right كمثال، تقوم هذه الوحدة ببناء VPC، subnets, NAT gateway والعديد من الموارد التي نستعملها للتشبيك)، تعتمد وحدة الموارد على الموفر، ويتم تعريفها أما في الموفر أو في الهياكل عالية المستوى (على سبيل المثال ، في وحدة البنية التحتية).

    hashtag
    وحدة البنية التحتية (Infrastructure module)

    وحدة البنية التحتية هي مجموعة وحدات موارد والتي قد لا تتربط منطقياً ولكنها توجد في مشروع أو نظام يخدم نفس الهدف. تعرف هذه الوحدة الـتهيئة (configuration) للموفرين (providers)، والتي تقوم بتمريرها إلى وحدات الموارد والموارد المؤلفة لهذه الوحدة. عادةً ما يقتصر العمل في وحدة بنية تحتية واحدة لكل كيان منفصل (على سبيل المثال ، AWS Region ، Google Project).

    كمثال فإن وحدة البنية التحتية terraform-aws-atlantisarrow-up-right تستعمل وحدات الموارد مثل terraform-aws-vpcarrow-up-right و terraform-aws-security-grouparrow-up-right لإدارة البنية التحتية اللازمة لتشغيل Atlantisarrow-up-right on AWS Fargatearrow-up-right.

    كمثال أخر فإن وحدة البنية التحتية terraform-aws-cloudqueryarrow-up-right يتم استعمالها لإدارة البنية التحتية كما تقوم باستعمال أداة Docker لإدارة Docker images في وحدة واحدة.

    hashtag
    التركيب (Composition)

    التركيب هو مجموعة من وحدات البنية التحتية والتي يمكن أن تمدد على العديد من المناطق المنفصلة (AWS Regions, AWS Accounts) . يتم استعمال التركيب لوصف كامل البنية التحتية لمؤسسة أو مشروع.

    كما يبين الشكل يتألف تركيب البنية التحتية (infrastructure composition) من مجموعة وحدات بنية تحتية (infrastructure module) والتي تتكون من وحدات موارد (resources module) والتي تنجز عدة موارد محددة

    Simple infrastructure composition

    hashtag
    مصدر البيانات (Data source)

    يوفر مصدر البيانات مورداً قابلاً للقراءة فقط (read-only) ويعتمد على نمط الموفر (provider) الذي نتعامل معه، يتم استعماله من قبل كل من وحدة البنية التحتية ووحدة الموارد.

    يعتبر مصدر البيانات terraform_remote_stateأداة لربط الوحدات عالية المستوى والتراكيب المختلفة مع بعضها

    يسمح مصدر البيانات externalarrow-up-right بالبرامج الخارجية بالعمل كمصدر للبيانات ليتم التعامل معها في مكان أخر من ملفات التهئية الخاصة بأداة Terraform، يمكن أن نجد مثالاً في terraform-aws-lambda modulearrow-up-right حيث يتم الحصول على اسم الملف من خلال استدعاء كود Python خارجي

    يحصل مصدر البيانات httparrow-up-right على معلوماته من خلال إرسال طلب HTTP GET لرابط معين ويصدر الجواب الذي حصلنا عليه ويعتبر هذه المصدر مفيداً في حال عدم وجود موفر Terraform.

    hashtag
    ملف الحالة المخرن عن بعد (Remote state)

    يجب تخزين Terraform statearrow-up-right لكل من وحدات البنية التحتية والتراكيب عن بعد حيث يمكن استرجاعه من قبل كل الأشخاص العاملين عليه ويجب أن تتم إدارته بشكل يضمن السرية والتنظيم (e.g. specify ACL, versioning, logging).

    hashtag
    الموفر (Provider, provisioner)

    يوجد توصيف مجزي لمفهوم الموفر في وثائق Terraform الرسمية، ولا يوجد لازمة لتكرارها هنا، وبرأي أن ليس لها علاقة بكتابة وحدات Terraform جيدة.

    hashtag
    أين الصعوبة؟

    بينما يمكننا اعتبار أن الموارد هي عبارة عن ذرات فإن "وحدات الموارد" تعتبر الجزئيات. "وحدة الموارد" هي أصغر وحدة يمكننا مشاركتها وإنشاء إصدرات منها، لديها قائمة محددة من الوسيطات، وتنجز وظيفة معينة. إذا أخذنا الوحدة terraform-aws-security-grouparrow-up-right كمثال فإننا سنجد أنها تقوم بإنشاء الموارد aws_security_group و aws_security_group_rule بالاعتماد على الدخل، يمكن استعمال هذه الوحدة مع وحدات أخرى لإنشاء وحدة بنية تحتية.

    حتى نتمكن من الوصول إلى بيانات فإننا نستعمل مخرجات الوحدات (outputs) بالإضافة إلى مصادر البيانات (data sources)

    حتى نتمكن من تبادل البيانات من تركيب إلى تركيب أخر يجب علينا استعمال مصدر البيانات terraform_remote_state،(كما يوجد العديد من الطرق لتبادل البياناتarrow-up-right)

    وأخيراً يمكننا تمثيل المفاهيم المشروحة سابقاً بهذا الشكل

    وثائق Terraform الرسميةarrow-up-right

    arrow-up-right

    Compliance.tfarrow-up-right — Terraform Compliance Simplified. Make your Terraform modules compliance-ready.

    contact mearrow-up-right
    Bosanski (Bosnian)chevron-right
    Português (Brazilian Portuguese)chevron-right
    Englishchevron-right
    Français (French)chevron-right
    ქართული (Georgian)chevron-right
    Deutsch (German)chevron-right
    ελληνικά (Greek)chevron-right
    עברית (Hebrew)chevron-right
    हिंदी (Hindi)chevron-right
    Bahasa Indonesia (Indonesian)chevron-right
    Italiano (Italian)chevron-right
    日本語 (Japanese)chevron-right
    ಕನ್ನಡ (Kannada)chevron-right
    한국어 (Korean)chevron-right
    Polski (Polish)chevron-right
    Română (Romanian)chevron-right
    简体中文 (Simplified Chinese)chevron-right
    Español (Spanish)chevron-right
    Türkçe (Turkish)chevron-right
    Українська (Ukrainian)chevron-right
    اردو (Urdu)chevron-right
    open an issuearrow-up-right
    Anton Babenkoarrow-up-right

    الأسئلة الأكثر تكراراً

    FTP (Frequent Terraform Problems اكثر المشاكل التي تعاني منها الأداة)

    hashtag
    ما هي الأدوات التي يجب معرفتها واستخدامها؟

    • أداة -أداة تنسيق

    المراجع

    circle-info

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

    - قائمة بالناس الذين عملوا مع الأداة بشكل كبير ومن الممكن أن تتعلم الكثير منهم (إذا سألت)

    - قائمة مختارة من مصارد تعلم الأداة

    - "جرعتك الأسبوعية من الأداة"

    ورشة عمل

    يوجد أيضاً ورشة عمل للناس التي تريد أن تتمرن على الأشياء التي تعلمناها في هذا المرجع

    هنا يوجد المحتوى -

    composition-1 {
      infrastructure-module-1 {
        data-source-1 => d1
    
        resource-module-1 {
          data-source-2 => d2
          resource-1 (d1, d2)
          resource-2 (d2)
        }
    
        resource-module-2 {
          data-source-3 => d3
          resource-3 (d1, d3)
          resource-4 (d3)
        }
      }
    
    }

    أداة tflintarrow-up-right

  • أداة tfenvarrow-up-right - إدارة الإصدارات

  • أداة Atlantisarrow-up-right أتمتة العمل مع PR

  • أداة pre-commit-terraformarrow-up-right مجموعة من git-hooks خاصة بأداة Terraform التي يتم استعمالها مع إطار العمل pre-commit frameworkarrow-up-right

  • hashtag
    ما هي الحلول لمشكلة dependency hellarrow-up-right مع الوحدات؟

    يجب تحديد إصدار الوحدة التي نتعامل معها. يجب تعريف الموفرات خارج الوحدات وفقط في التراكيب، يجب أيضاً تحديد إصدار الموفرات وإصدار Terraform أالذي نتعامل معه.

    لا يوجدا أداة إدارة Dependency، لكن يوجد بعض النصائح التي تجعل هذه المشكلة أقل إشكالاً. كمثال يمكن استعمال أداة Dependabotarrow-up-right لأتمتة تحديث الارتباطات. تقوم هذه الأداة بإنشاء PR للحفاظ على الارتباطات بشكل أمن ومحدث. تدعم هذه الأداة ملفات Terraform.

    Terragruntarrow-up-right
    بث مباشر من قبل مؤلف هذه الكتاب. مراجعات، مقابلات، Q&A، جلسات تكويد وكل شيء عن الأداة

    https://weekly.tfarrow-up-right - "الرسائل الأسبوعية عن الأداة"

    أخبار مختلفة عن عالم الأداة (مشاريع جديدة، إعلانات، نقاشات) ترسل إليك من قبل مؤلف الكتاب.

    awesome-terraformarrow-up-right
    https://twitter.com/antonbabenko/lists/terraform-expertsarrow-up-right
    https://github.com/shuaibiyy/awesome-terraformarrow-up-right
    http://bit.ly/terraform-youtubearrow-up-right
    https://github.com/antonbabenko/terraform-best-practices-workshoparrow-up-right

    كتابة ملفات أداة Terraform

    hashtag
    استعمل locals لتحديد الاعتماديات الصريحة بين الموارد

    من الطرق المساعدة لإخبار Terraform أنه يجب حذف بعض الموارد حتى عندما لا يوجد اعتمادية مباشرة عليها

    https://raw.githubusercontent.com/antonbabenko/terraform-best-practices/master/snippets/locals.tfarrow-up-right

    hashtag
    إصدار Terraform 0.12 - الوسيطات الإجبارية والاختيارية

    1. الوسيط index_documentهو وسيط إجباري يجب تحديده، إذا كانتvar.websiteليستmapفارغة

    2. الوسيط error_documentهو وسيط اختياري من الممكن عدم ذكره

    تنسيق الكود

    circle-info
    • يجب أن تحتوي أمثلة ووحدات Terraformعلى توثيق لشرح الخصائص التي تقدمها وكيفية استعمالها

    • كل الروابط في ملف README.md يجب أن تكون مطلقة لجعل موقع Terraform Registry يعرضها بشكل صحيح

    البنى المتوسطة باستعمال Terraform

    المصدر:

    يحتوي هذا المثال على كود لهيكلة كود Terraform لبنية تحتية متوسطة والتي تستعمل:

    • حسابين AWS

    • بيئتين مختلفتين (prod

    البنى الكبيرة باستعمال Terraform

    المصدر:

    يحتوي هذا المثال على كود لهيكلة كود Terraform لبنية تحتية كبيرة والتي تستعمل:

    • حسابين AWS

    • منطقتين

    يمكن أن يحتوي التوثيق على رسومات تم إنشاؤها باستخدام mermaidarrow-up-right أو مخططات تم إنشاؤها باستخدام cloudcraft.coarrow-up-right.

  • قم باستعمال Terraform pre-commit hooksarrow-up-right للتأكد من أن الكود صالح، ومنسق بشكل صحيح، وموثق تلقائيًا قبل دفعه إلى Git واستعراضه من قبل البشر.

  • hashtag
    التوثيق

    hashtag
    التوثيق مولداً تلقائياً

    إن pre-commitarrow-up-right هو إطار عمل لإدارة وصيانة pre-commit hooks متعددة اللغات، مكتوبة بلغة بايثون وهي أداة قوية للقيام ببعض المهام بشكل أتوماتيكي على جهاز المطور قبل الدفع بالكود إلى git repository. تستعمل عادةً لتشغيل linters ولتنسيق الكود ( انظر إلى supported hooksarrow-up-right)

    مع ملفات Terraform يمكننا استعمال pre-commitلتنسيق الكود والتحقق منه بالإضافة إلى تعديل التوثيق

    تحقق من pre-commit-terraform repositoryarrow-up-right ومن terraform-aws-vpcarrow-up-right الذي يقوم باستعماله

    hashtag
    أداة terraform-docs

    إن terraform-docsarrow-up-right هي أداة تقوم بتوليد التوثيق من وحدات Terraform وتولد أشكال مختلفة، يمكنك أن تشغلها يدوياً (بدون pre-commit hooks) أو تستعمل إطار عمل pre-commit-terraform hooksarrow-up-right لجعل التوثيق يتكون أتوماتيكياً.

    @todo: Document module versions, release, GH actions

    hashtag
    الموراد

    1. pre-commit framework homepagearrow-up-right

    2. Collection of git hooks for Terraform to be used with pre-commit frameworkarrow-up-right

    3. Blog post by Dean Wilsonarrow-up-right: pre-commit hooks and terraform - a safety net for your repositoriesarrow-up-right

    and
    stage
    لا وجود لشيء مشترك بينهما). كل بيئة موجودة في حساب AWS مختلف
  • كل بيئة تستعمل إصدارات مختلفة للوحدات الجاهزة (alb) مصدرها Terraform Registryarrow-up-right

  • كل بيئة تستعمل الإصدار نفسه للوحدات الداخلية modules/network مصدره المجلد المحلي

  • circle-check
    • ممتاز للمشاريع التي تحتاج إلى فصل منطقي لبيئاتها (باستعمال حسابات AWS مختلفة)

    • جيد عندما لا يوجد حاجة لتعديل الموارد المشتركة بين حسابات AWS المختلفة (بيئة واحدة = حساب AWS واحد = ملف حالة وحيد)

    • جيد عندما لا يوجد حاجة لتنسيق التعديلات بين البيئات المختلفة

    • جيد عند الاختلاف المتعمد للموارد بين البيئات والذي لا يمكن تعريف حالة عامة له (كوجود بعض الموارد في بيئة وغيابها في بيئة أخرى)

    circle-exclamation

    مع نمو المشروع ، سيكون من الصعب الحفاظ على تحديث هذه البيئات مع بعضها البعض. خذ بعين الاعتبار استخدام وحدات البنية التحتية (الجاهزة أو الداخلية) للمهام المتكررة.

    hashtag

    https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/medium-terraformarrow-up-right

    بيئتين مختلفتين (prod and stage لا وجود لشيء مشترك بينهما). كل بيئة موجودة في حساب AWS مختلف وتوزع الموارد على المنطقتين

  • كل بيئة تستعمل إصدارات مختلفة للوحدات الجاهزة (alb) مصدرها Terraform Registryarrow-up-right

  • كل بيئة تستعمل الإصدار نفسه للوحدات الداخلية modules/network مصدره المجلد المحلي

  • circle-info

    في المشاريع الكبيرة مثل المشروع أعلاه تظهر أهمية استعمال أداة Terragrunt. انظر إلى Code Structures examples with Terragrunt.

    circle-check
    • ممتاز للمشاريع التي تحتاج إلى فصل منطقي لبيئاتها (باستعمال حسابات AWS مختلفة)

    • جيد عندما لا يوجد حاجة لتعديل الموارد المشتركة بين حسابات AWS المختلفة (بيئة واحدة = حساب AWS واحد = ملف حالة وحيد)

    • جيد عندما لا يوجد حاجة لتنسيق التعديلات بين البيئات المختلفة

    • جيد عند الاختلاف المتعمد للموارد بين البيئات والذي لا يمكن تعريف حالة عامة له (كوجود بعض الموارد في بيئة وغيابها في بيئة أخرى)

    circle-exclamation

    مع نمو المشروع ، سيكون من الصعب الحفاظ على تحديث هذه البيئات مع بعضها البعض. خذ بعين الاعتبار استخدام وحدات البنية التحتية (الجاهزة أو الداخلية) للمهام المتكررة.

    hashtag

    https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/large-terraformarrow-up-right
    main.tf
    variable "website" {
      type    = map(string)
      default = {}
    }
    
    resource "aws_s3_bucket" "this" {
      # omitted...
    
      dynamic "website" {
        for_each = length(keys(var.website)) == 0 ? [] : [var.website]
    
        content {
          index_document = website.value.index_document
          error_document = lookup(website.value, "error_document", null)
        }
      }
    }
    terraform.tfvars
    website = {
      index_document = "index.html"
    }

    قواعد التسمية

    hashtag
    القواعد العامة

    circle-info

    يجب ألا يكون هناك سبب لعدم اتباع هذه القواعد على الأقل :)

    circle-info

    كن حذراً أن الموارد الحقيقية التي يتم تعريفها في Terraform غالباً ما يكون لها قيود على الأسماء المسموح بها. بعض الموارد كمثال لا تقبل الخطوط (dashes)، أو يجب أن يكون بعضها Camel-cased، القواعد في هذا الكتاب تشير إلى الأسماء المستخدمة في Terraform.

    1. استعمل _ (underscore) بدلاً من - (dash) في كل مكان (أسماء الموراد، أسماء مصادر البيانات، أسماء المتحولات، أسماء المخرجات الخ..)

    2. فضل استعمال الأحرف الصغيرة (lowercase) والأرقام فقط (حتى لو كان نظام UTF-8 مدعوماً)

    hashtag
    أسماء الموراد ومصادر البيانات

    1. لا تكرر نوع المورد في اسم المورد (ليس جزئيًا أو كليًا):

      circle-check

      resource "aws_route_table" "public" {}

      triangle-exclamation

    hashtag
    أمثلة كود لأسماء المصادر

    hashtag
    استعمال count / for_eachفي الكود

    circle-check
    triangle-exclamation

    hashtag
    وضعية tagsفي الكود

    circle-check
    triangle-exclamation

    hashtag
    استعمال الشروط في countفي الكود

    circle-check

    hashtag
    أسماء المتحولات

    1. لا تعيد اختراع العجلة في وحدات الموارد: استخدم الاسمnameوالوصفdescriptionوالقيمة الافتراضية defaultللمتحولات كما هو محدد في قسم "Argument Reference" للمورد الذي تعمل معه.

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

    hashtag
    أسماء المخرجات

    اجعل المخرجات متسقة ومفهومة خارج سياقها ( عندما يتم استعمال وحدة من قبل مستخدم يجب على المخرجات أن تكون واضح ما هو نمط وما صفات القيمة التي ترجعها)

    1. يجب على اسم الخرج أن يصف القيمة التي يرجعها وأن تكون أقل حرية مما تريد عادة.

    2. الشكل الجيد لاسم الخرج يكون كالتالي {attribute}_{type}_{name} حيث:

      1. إن {name}

    hashtag
    أمثلة كود لأسماء المخرجات

    تعيد على الأكثر Security group ID وحيد

    circle-check

    عند وجود عدة مصادر من نفس النمط، يجب حذفthisمن الخرج:

    triangle-exclamation

    إذا كانت قيمة الخرج عبارة عن list فإنه يجب أن نستعمل اسم جمع :

    circle-check

    resource "aws_route_table" "public_route_table" {}
    triangle-exclamation

    resource "aws_route_table" "public_aws_route_table" {}

  • يجب تسمية المورد باسمthisإذا لم يكن هناك اسم وصفي وعام متاح، أو إذا كانت وحدة الموارد تنشئ موردًا واحدًا من هذا النوع (كمثال في يوجد فقط مورد وحيد من النوعaws_nat_gateway وعدة موارد من النوع aws_route_table لذلك يجب تسمية المورد من نوعaws_nat_gateway باسم thisويجب أن نستعمل أسماء وصفية اكثر من أجل موارد النوع aws_route_table مثلprivate, public, database)

  • استخدم دائمًا الأسماء المفردة للتسمية.

  • استعمل - (dash) داخل قيم الوسيطات وفي الأماكن التي ستتعرض فيها القيمة للبشر (على سبيل المثال ، اسم DNS لخادم افتراضي RDS).

  • استعمل الوسيطان count / for_each داخل المورد أو داخل مصدر البيانات كأول وسيط وقم بإضافة سطر فارغ بعده

  • استعمل الوسيطtags إذا كان مدعوماً من قبل المورد كأخر وسيط متبوع بالوسيطاتdepends_on, lifecycleإذا احتجت إليها، كل منها مفصول عن الأخر بسطر فارغ.

  • عند استعمال شروط للوسيطان count / for_eachففضل استعمال القيم المنطقية عوضاً عنlengthأو أي تعابير أخرى

  • استخدم صيغة الجمع في اسم متحول عند يكون نمطهlistأوmap.
  • قم بترتيب الأقسام في المتحول كالتالي:descriptionثمtypeثمdefaultوأخيراًvalidation

  • دائماً قم بإضافة قسمdescription إلى كل المتحولات حتى لو كنت تظن أنه واضح (ستحتاجه في المستقبل)

  • فضل استعمال الأنواع البسيطة (number, string, list(...), map(...), any) على الأنواع الأخرى مثلobject،إلا إذا كنت تحتاج قيود صارمة على كل key

  • استعمل الأنماط المحددة مثلmap(string) في حال كانت كل العناصر الموجودة داخلها من نفس النمط أو كان يمكن تحويلها إلى هذا النمط (مثلاً النمطnumberممكن تحويله إلى النمطstring)

  • استعمل النمط anyلتعطيل التحقق من النوع بدءاً من عمق معين أو عندما يجب دعم أنواع متعددة

  • القيمة {} هي عبارة عن map في بعض الأحيان وobject في أحيان أخرى. استعمل ()tomap لجعلها من النمط map دائماً.

  • هو اسم المورد أو اسم مصدر البيانات بدون اسم الموفر. كمثال للمورد
    aws_subnet
    يكون الاسم هو
    subnet
    وللمورد
    aws_vpc
    يكون
    vpc
  • إن {type}هو نمط الخرج الئي نتعامل معه

  • إن{attribute}هو الصفة المخرجة

  • .

  • إذا كان الخرج يعيد قيمة مع استعمال interpolation functions وعدة موارد فيجب على {name} و{type} أن تكون معممة قدر الإمكان (this يجب حذفها)

  • إذا كانت قيمة الخرج عبارة عن list فإنه يجب أن نستعمل اسم جمع

  • دائماً قم بإضافة قسمdescription إلى كل المخرجات حتى لو كنت تظن أنه واضح

  • تجنب وضع وسيط sensitiveإلا إذا كنت تملك تحكم كامل باستعمال هذا الخرج في كل الأماكن في كل الوحدات

  • فضل استعمال ()try (متوفرة منذ الإصدار 0.13) على استعمال element(concat(...))(التي كانت تستعمل قبل 0.13)

  • main.tf
    resource "aws_route_table" "public" {
      count = 2
    
      vpc_id = "vpc-12345678"
      # ... remaining arguments omitted
    }
    
    resource "aws_route_table" "private" {
      for_each = toset(["one", "two"])
    
      vpc_id = "vpc-12345678"
      # ... remaining arguments omitted
    }
    main.tf
    resource "aws_route_table" "public" {
      vpc_id = "vpc-12345678"
      count  = 2
    
      # ... remaining arguments omitted
    }
    main.tf
    resource "aws_nat_gateway" "this" {
      count = 2
    
      allocation_id = "..."
      subnet_id     = "..."
    
      tags = {
        Name = "..."
      }
    
      depends_on = [aws_internet_gateway.this]
    
      lifecycle {
        create_before_destroy = true
      }
    }   
    main.tf
    resource "aws_nat_gateway" "this" {
      count = 2
    
      tags = "..."
    
      depends_on = [aws_internet_gateway.this]
    
      lifecycle {
        create_before_destroy = true
      }
    
      allocation_id = "..."
      subnet_id     = "..."
    }
    outputs.tf
    resource "aws_nat_gateway" "that" {    # Best
      count = var.create_public_subnets ? 1 : 0
    }
    
    resource "aws_nat_gateway" "this" {    # Good
      count = length(var.public_subnets) > 0 ? 1 : 0
    }
    outputs.tf
    output "security_group_id" {
      description = "The ID of the security group"
      value       = try(aws_security_group.this[0].id, aws_security_group.name_prefix[0].id, "")
    }
    outputs.tf
    output "this_security_group_id" {
      description = "The ID of the security group"
      value       = element(concat(coalescelist(aws_security_group.this.*.id, aws_security_group.web.*.id), [""]), 0)
      
    outputs.tf
    output "rds_cluster_instance_endpoints" {
      description = "A list of all cluster instance endpoints"
      value       = aws_rds_cluster_instance.this.*.endpoint
    }
    AWS VPC modulearrow-up-right
    انظر الأمثلة
    انظر الأمثلة
    انظر الأمثلة