Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
تصف وثائق Terraform الرسمية جميع مصطلحات تعريف البنى التحتية بالتفصيل. اقرأها بعناية لفهم بقية هذا القسم.
يشرح هذا القسم المفاهيم الأساسية المستخدمة في الكتاب
المورد هو aws_vpc، aws_db_instance الخ...، ينتمي المورد إلى موفر معين (provider) ويقبل الوسيطات (arguments) ويولد المخرجات (outputs) وله دورات حياة (lifecycles). يمكن إنشاء مورد واسترجاع معلوماته وتحديثه وحذفه.
وحدة الموارد هي مجموعة من الموارد المرتبطة ببعضها والتي تقوم مع بعضها بتنفيذ وظيفة معينة (لنأخذ كمثال، تقوم هذه الوحدة ببناء VPC، subnets, NAT gateway والعديد من الموارد التي نستعملها للتشبيك)، تعتمد وحدة الموارد على الموفر، ويتم تعريفها أما في الموفر أو في الهياكل عالية المستوى (على سبيل المثال ، في وحدة البنية التحتية).
وحدة البنية التحتية هي مجموعة وحدات موارد والتي قد لا تتربط منطقياً ولكنها توجد في مشروع أو نظام يخدم نفس الهدف. تعرف هذه الوحدة الـتهيئة (configuration) للموفرين (providers)، والتي تقوم بتمريرها إلى وحدات الموارد والموارد المؤلفة لهذه الوحدة. عادةً ما يقتصر العمل في وحدة بنية تحتية واحدة لكل كيان منفصل (على سبيل المثال ، AWS Region ، Google Project).
كمثال فإن وحدة البنية التحتية تستعمل وحدات الموارد مثل و لإدارة البنية التحتية اللازمة لتشغيل on .
كمثال أخر فإن وحدة البنية التحتية يتم استعمالها لإدارة البنية التحتية كما تقوم باستعمال أداة Docker لإدارة Docker images في وحدة واحدة.
التركيب هو مجموعة من وحدات البنية التحتية والتي يمكن أن تمدد على العديد من المناطق المنفصلة (AWS Regions, AWS Accounts) . يتم استعمال التركيب لوصف كامل البنية التحتية لمؤسسة أو مشروع.
كما يبين الشكل يتألف تركيب البنية التحتية (infrastructure composition) من مجموعة وحدات بنية تحتية (infrastructure module) والتي تتكون من وحدات موارد (resources module) والتي تنجز عدة موارد محددة
يوفر مصدر البيانات مورداً قابلاً للقراءة فقط (read-only) ويعتمد على نمط الموفر (provider) الذي نتعامل معه، يتم استعماله من قبل كل من وحدة البنية التحتية ووحدة الموارد.
يعتبر مصدر البيانات terraform_remote_stateأداة لربط الوحدات عالية المستوى والتراكيب المختلفة مع بعضها
يسمح مصدر البيانات بالبرامج الخارجية بالعمل كمصدر للبيانات ليتم التعامل معها في مكان أخر من ملفات التهئية الخاصة بأداة Terraform، يمكن أن نجد مثالاً في حيث يتم الحصول على اسم الملف من خلال استدعاء كود Python خارجي
يحصل مصدر البيانات على معلوماته من خلال إرسال طلب HTTP GET لرابط معين ويصدر الجواب الذي حصلنا عليه ويعتبر هذه المصدر مفيداً في حال عدم وجود موفر Terraform.
يجب تخزين لكل من وحدات البنية التحتية والتراكيب عن بعد حيث يمكن استرجاعه من قبل كل الأشخاص العاملين عليه ويجب أن تتم إدارته بشكل يضمن السرية والتنظيم (e.g. specify ACL, versioning, logging).
يوجد توصيف مجزي لمفهوم الموفر في وثائق Terraform الرسمية، ولا يوجد لازمة لتكرارها هنا، وبرأي أن ليس لها علاقة بكتابة وحدات Terraform جيدة.
بينما يمكننا اعتبار أن الموارد هي عبارة عن ذرات فإن "وحدات الموارد" تعتبر الجزئيات. "وحدة الموارد" هي أصغر وحدة يمكننا مشاركتها وإنشاء إصدرات منها، لديها قائمة محددة من الوسيطات، وتنجز وظيفة معينة. إذا أخذنا الوحدة كمثال فإننا سنجد أنها تقوم بإنشاء الموارد aws_security_group و aws_security_group_rule بالاعتماد على الدخل، يمكن استعمال هذه الوحدة مع وحدات أخرى لإنشاء وحدة بنية تحتية.
حتى نتمكن من الوصول إلى بيانات فإننا نستعمل مخرجات الوحدات (outputs) بالإضافة إلى مصادر البيانات (data sources)
حتى نتمكن من تبادل البيانات من تركيب إلى تركيب أخر يجب علينا استعمال مصدر البيانات terraform_remote_state،()
وأخيراً يمكننا تمثيل المفاهيم المشروحة سابقاً بهذا الشكل
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)
}
}
}بعض الموارد، لا وجود لاعتماديات خارجية، استعمال حساب AWS واحد، استعمال منطقة وحيدة، استعمال بيئة وحيدة
نعم
عدة حسابات AWS وعدة بيئات، استعمال وحدات جاهزة باستخدام Terraform
نعم
العديد من حسابات AWS، العديد من المناطق، حاجة ملحة لتقليل عمليات النسخ واللصق، استعمال وحدات مخصصة، استعمال كبير للتراكيب باستخدام Terraform
جاري العمل عليه
كبير جداً
العديد من الموفرين (AWS, GCP, Azure). استعمال للعديد من الخدمات السحابية في عملية deployment باستخدام Terraform
لا
متوسط
عدة حسابات AWS وعدة بيئات، استعمال وحدات جاهزة باستخدام Terragrunt
لا
كبير
العديد من حسابات AWS، العديد من المناطق، حاجة ملحة لتقليل عمليات النسخ واللصق، استعمال وحدات مخصصة، استعمال كبير للتراكيب باستخدام Terragrunt
لا
كبير جداً
العديد من الموفرين (AWS, GCP, Azure). استعمال للعديد من الخدمات السحابية في عملية deployment باستخدام Terragrunt.
لا
الهدف من هذا التوثيق هو توصيف أفضل الممارسات لاستعمال أداة Terraform وتوفير توصيات للتعامل مع المشكلات الأكثر شيوعاً التي يواجهها مستخدمو هذه الأداة.
يعد الـ مشروع جديد نسبياً (مثل معظم أدوات الـ DevOps )، صدر في عام 2014.
تعد أداة Terraform قوية (إن لم تكن الأقوى الآن) وواحدة من أكثر الأدوات استعمالاً لتوصيف البنى التحتية المعلوماتية باستعمال الكود (Infrastructure as code). تسمح هذه الأداة للمطورين بالقيام بالكثير من الوظائف ولا تمنعهم من فعل الأشياء بطرق يصعب دعمها أو التواصل معها.
بعض المعلومات في هذا الكتاب قد تبدو وكأنها لا تصنف كأفضل الممارسات. أعلم هذا. ولمساعدة القراء على التفريق بين ما يعد أفضل ممارسة أو ما هو مجرد طريقة أخرى لفعل الأشياء، فإني سأقوم باستعمال التلميحات (hints) في بعض الأحيان وتوفير الأيقونات لتحديد مستوى النضج في كل قسم فرعي يتعلق بأفضل الممارسات.
تم البدء بكتابة هذا الكتاب في مدريد في سنة 2018 وهو متوفر مجاناً على الرابط -
تم التعديل على هذا الكتاب بعد عدة سنين لإضافة أفضل الممارسات المتوفرة لإصدار Terraform 1.0 ، هذا الكتاب يجب أن يحتوي أفضل الممارسات والتوصيات الغير القابلة للجدل ليتم استعمالها من قبل مستخدمي الـ Terraform
المصدر:
يحتوي هذا المثال على كود لهيكلة كود Terraform لبنية تحتية صغيرة، حيث لا وجود لاعتمادات خارجية
ممتاز للبدء بتعلم Terraform وإعادة هيكلة الكود (refactoring)
ممتاز لبناء الوحدات الصغيرة
جيد لاستعمال الوحدات الصغيرة (eg, terraform-aws-atlantis)
جيد عند وجود عدد صغير من الموارد (أقل من 20-30)
وجود ملف حالة وحيد Single state file من أجل كل الموارد سيجعل أداة Terraform بطيئة كلما زاد عدد الموارد المعرفة (خذ بعين الاعتبار استعمال الوسيط target- للحد من الموارد التي تتعامل معها عند طلب الأداة)
Please contact me if you want to become a sponsor.
— Terraform Compliance Simplified. Make your Terraform modules compliance-ready.
اتصل بي إذا كنت تود المساعدة بالترجمة إلى لغات أخرى
أرغب دائمًا في الحصول على تعليقات وتحديثات لهذا الكتاب بينما ينضج المجتمع ويتم تنفيذ الأفكار الجديدة والتحقق منها بمرور الوقت.
إذا كنت مهتمًا بموضوعات معينة فالرجاء طرح مشكلتك open an issue أو إبداء الإعجاب بالمشكلة التي تريد تغطيتها أكثر من غيرها. إذا كنت تشعر أن لديك محتوى وتريد المساهمة، فاكتب مسودة وأرسل Pull request (لا تقلق بشأن كتابة نص جيد في هذه المرحلة!)
هذا الكتاب من إعداد Anton Babenko بمساعدة مساهمين ومترجمين مختلفين.
هذا العمل مرخص بموجب ترخيص Apache 2. انظر LICENSE للحصول على التفاصيل الكاملة.
لا يمكن للمؤلفين والمساهمين في هذا المحتوى ضمان صحة المعلومات الموجودة هنا. يرجى التأكد من أنك تفهم أن المعلومات المقدمة هنا يتم توفيرها بحرية ، وأنه لا يوجد أي نوع من الاتفاقية أو العقد بينك وبين أي أشخاص مرتبطين بهذا المحتوى أو المشروع. لا يتحمل المؤلفون والمساهمون ، وبموجب هذا ، أي مسؤولية تجاه أي طرف عن أي خسارة أو ضرر أو اضطراب ناتج عن أخطاء أو سهو في المعلومات الواردة في هذا المحتوى أو المرتبطة به أو المرتبطة به ، سواء كانت هذه الأخطاء أو الإغفالات ناتجة عن إهمال أو حادث أو أي سبب آخر.
حقوق النشر © 2018-2023 Anton Babenko.
يوجد أيضاً ورشة عمل للناس التي تريد أن تتمرن على الأشياء التي تعلمناها في هذا المرجع
هنا يوجد المحتوى - https://github.com/antonbabenko/terraform-best-practices-workshop
المصدر:
يحتوي هذا المثال على كود لهيكلة كود Terraform لبنية تحتية متوسطة والتي تستعمل:
حسابين AWS
بيئتين مختلفتين (prod and stage لا وجود لشيء مشترك بينهما). كل بيئة موجودة في حساب AWS مختلف
كل بيئة تستعمل إصدارات مختلفة للوحدات الجاهزة (alb) مصدرها Terraform Registry
كل بيئة تستعمل الإصدار نفسه للوحدات الداخلية modules/network مصدره المجلد المحلي
ممتاز للمشاريع التي تحتاج إلى فصل منطقي لبيئاتها (باستعمال حسابات AWS مختلفة)
جيد عندما لا يوجد حاجة لتعديل الموارد المشتركة بين حسابات AWS المختلفة (بيئة واحدة = حساب AWS واحد = ملف حالة وحيد)
جيد عندما لا يوجد حاجة لتنسيق التعديلات بين البيئات المختلفة
جيد عند الاختلاف المتعمد للموارد بين البيئات والذي لا يمكن تعريف حالة عامة له (كوجود بعض الموارد في بيئة وغيابها في بيئة أخرى)
مع نمو المشروع ، سيكون من الصعب الحفاظ على تحديث هذه البيئات مع بعضها البعض. خذ بعين الاعتبار استخدام وحدات البنية التحتية (الجاهزة أو الداخلية) للمهام المتكررة.


إن هو إطار عمل لإدارة وصيانة pre-commit hooks متعددة اللغات، مكتوبة بلغة بايثون وهي أداة قوية للقيام ببعض المهام بشكل أتوماتيكي على جهاز المطور قبل الدفع بالكود إلى git repository. تستعمل عادةً لتشغيل linters ولتنسيق الكود ( انظر إلى )
مع ملفات Terraform يمكننا استعمال pre-commitلتنسيق الكود والتحقق منه بالإضافة إلى تعديل التوثيق
تحقق من ومن الذي يقوم باستعماله
إن هي أداة تقوم بتوليد التوثيق من وحدات Terraform وتولد أشكال مختلفة، يمكنك أن تشغلها يدوياً (بدون pre-commit hooks) أو تستعمل إطار عمل لجعل التوثيق يتكون أتوماتيكياً.
@todo: Document module versions, release, GH actions
Blog post by :
الأسئلة المتعلقة ببنية كود Terraform هي الأكثر شيوعًا في المجتمع. في الكثير من الأحيان فكر الجميع في أفضل بنية كود ممكن الحصول عليها للمشروع.
هذا نوع من الأسئلة التي يمكن الإجابة عليها بالعديد من الطرق ومن الصعب جداً تقديم نصيحة تنفع لجميع الحالات، لذلك لنبدأ بفهم ما نتعامل معه.
ما هو مدى تعقيد مشروعك؟
عدد الموارد المرتبطة ببعضها
عدد الموفرين (انظر الملاحظة أدناه عن "logical providers")
كم مرة تحتاج إلى تغيير في البنية التحتية؟
من مرة في الشهر/الأسبوع/اليوم؟
إلى تغيير مستمر (عند كل commit جديدة)
مصادر تغيير الكود، هل تسمح لمخدم CI بتعديل repository عند بناء artifact جديدة؟
يسمح فقط للمطورين بإضافة تغييرات إلى repository الخاصة بالبنية التحتية
يسمح لأي أحد باقتراح تغيير من خلال فتح PR (متضمناً المهام الأتوماتيكية التي يقوم بها مخدم CI)
ما هي المنصة أو الخدمة التي تستعملها لعملية deployment؟
AWS CodeDeploy, Kubernetes, OpenShift (يحتاج كل حل إلى معاملة مختلفة)
كيف يتم فرز البيئات المختلفة؟
من خلال بيئة العمل(environment)، المنطقة (region)، المشروع (project)
عند بداية التعامل مع Terraform أو عندما تريد أن تكتب مثالاً فإن وضع كل الكود في ملف main.tf تعتبر فكرة جيدة، ولكن في كل الحالات الأخرى يجب تقسيم الكود منطقياً إلى ملفات مختلفة كالتالي:
ملف main.tf, والذي يستدعي الوحدات المختلفة (modules), والوسطاء المحلية (locals)، ومصادر البيانات (data) لتوليد كافة الموارد (resources)
ملف variables.tf، الذي يحتوي على تعريف للوسطاء (variables) المراد استعمالها فيmain.tf
ملفoutputs.tf
لا يجب استعمال terraform.tfvarsفي أي مكان ما عدا .
إنه من الأسهل والأسرع التعامل مع عدد قليل من الموارد
إن كل من تعليمتي terraform planوterraform apply تقوم باستدعاء cloud API للتحقق من حالة الموارد
إذا كانت كل بنيتك التحتية في تركيب واحد ستأخذ هذه التعليمات وقتاً طويلاً للتنفيذ
في هذا المشروع قمنا بفرز المشروعات بحسب تعقيدها من البنى الصغيرة إلى الكبيرة جداً، لا يعتبر هذا التجميع ملزماً، لذا ابحث عن طرق أخرى أيضاً.
وجود بنية تحتية صغيرة يعني وجود عدد صغير من الاعتماديات (dependencies) والموارد، كلما كبر المشروع فإن أهمية ربط البنى المختلفة وتمرير المتحولات في التركيب تصبح واضحة اكثر.
يوجد على الأقل 5 أدوات تنسيقات مستقلة التي يمكن للمطور أن يستعملها:
يكفي للمطور أن يستعمل Terraform
استعمال أداة Terragrunt، وهي أداة orchestration تستعمل لتنسيق كل البنية التحتية والاعتماديات، تعمل هذه الأداة مع مختلف الوحدات (modules) والتراكيب (compositions) لذلك تخفف من تكرار الكود (إعادة اختراع العجلة)
استعمال scripts خاصة بالشركة (In-house scripts)، تم استعمالها كبداية لعمليات التنسيق قبل صدور Terragrunt
استعمال أداة Ansible أو أي أداة أتمتة (Autoamtion tools) . يتم استعمالها في حال تم تبني Terraform بعد استعمال Ansible، أو في حال استعمال Ansible UI.
في هذا الكتاب نقوم فقط بعرض الحلين الأولين (Terraform only and Terragrunt.)
شاهد أمثلة عن أو في الفصل القادم
main.tfملفversions.tf ، الذي يحتوي متطلبات الإصدار الخاصة بـ Terraform و الموفرين
مدى الضرر يكون أصغر في حال تعريف موارد قليلة
عزل الموارد غير المرتبطة ببعضها في تراكيب مختلفة يقلل الخطر في حال حدوث مشكلة ما
استعمل ملف الحالة المخرن عن بعد
حاسبك الشخصي لا يمثل عكس لحقيقة البنية التحتية
إدارة tfstate في git أمر كارثي
لاحقاً عند توسع البنية في اتجاهات عدة (عدد الموارد وعدد dependencies)، سيكون استعمال هذا الملف أسهل للتحكم بهذه البنية
تمرن على بنية وطرق تسمية متسقة
مثل الكود العادي، فإن كود Terraform يجب أن يكون مقروءاً، الاتساق سيساعد عندما تريد التحقق من تعديلات تمت إضافتها من 6 أشهر ماضية
من الممكن أن تنقل موارد لم يتم تعريفها سابقاً إلى ملف Terraform State، لكن وجود كود غير متسق سيصعب الأمر
قم ببناء وحدة (modules) بسيطة قدر الإمكان
لا تقم باستعمال قيم ثابتة (hardcoded) إذا كنت تستطيع تمريرها كمتحول أو الحصول عليها من مصدر بيانات
استعمل مصادر البيانات و terraform_remote_state كغراء بين وحدات البنية التحتية في التركيب
أستعمال أداة Crossplane و الأدوات الملهمة من قبل Kubernetes. من المنطقي أحياناً استعمال Kubernetes لتنسيق Terraform. لمزيد من المعلومات شاهد هذا الفيديو Crossplane vs Terraform
https://twitter.com/antonbabenko/lists/terraform-experts - قائمة بالناس الذين عملوا مع الأداة بشكل كبير ومن الممكن أن تتعلم الكثير منهم (إذا سألت)
https://github.com/shuaibiyy/awesome-terraform - قائمة مختارة من مصارد تعلم الأداة
http://bit.ly/terraform-youtube - "جرعتك الأسبوعية من الأداة"
بث مباشر من قبل مؤلف هذه الكتاب. مراجعات، مقابلات، Q&A، جلسات تكويد وكل شيء عن الأداة
- "الرسائل الأسبوعية عن الأداة"
أخبار مختلفة عن عالم الأداة (مشاريع جديدة، إعلانات، نقاشات) ترسل إليك من قبل مؤلف الكتاب.
المصدر: https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/large-terraform
يحتوي هذا المثال على كود لهيكلة كود Terraform لبنية تحتية كبيرة والتي تستعمل:
حسابين AWS
منطقتين
بيئتين مختلفتين (prod and stage لا وجود لشيء مشترك بينهما). كل بيئة موجودة في حساب AWS مختلف وتوزع الموارد على المنطقتين
كل بيئة تستعمل إصدارات مختلفة للوحدات الجاهزة (alb) مصدرها
كل بيئة تستعمل الإصدار نفسه للوحدات الداخلية modules/network مصدره المجلد المحلي
ممتاز للمشاريع التي تحتاج إلى فصل منطقي لبيئاتها (باستعمال حسابات AWS مختلفة)
جيد عندما لا يوجد حاجة لتعديل الموارد المشتركة بين حسابات AWS المختلفة (بيئة واحدة = حساب AWS واحد = ملف حالة وحيد)
مع نمو المشروع ، سيكون من الصعب الحفاظ على تحديث هذه البيئات مع بعضها البعض. خذ بعين الاعتبار استخدام وحدات البنية التحتية (الجاهزة أو الداخلية) للمهام المتكررة.
جيد عند الاختلاف المتعمد للموارد بين البيئات والذي لا يمكن تعريف حالة عامة له (كوجود بعض الموارد في بيئة وغيابها في بيئة أخرى)
من الطرق المساعدة لإخبار Terraform أنه يجب حذف بعض الموارد حتى عندما لا يوجد اعتمادية مباشرة عليها
https://raw.githubusercontent.com/antonbabenko/terraform-best-practices/master/snippets/locals.tf
الوسيط index_documentهو وسيط إجباري يجب تحديده، إذا كانتvar.websiteليستmapفارغة
الوسيط error_documentهو وسيط اختياري من الممكن عدم ذكره
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)
}
}
}website = {
index_document = "index.html"
}استعمل _ (underscore) بدلاً من - (dash) في كل مكان (أسماء الموراد، أسماء مصادر البيانات، أسماء المتحولات، أسماء المخرجات الخ..)
فضل استعمال الأحرف الصغيرة (lowercase) والأرقام فقط (حتى لو كان نظام UTF-8 مدعوماً)
لا تكرر نوع المورد في اسم المورد (ليس جزئيًا أو كليًا):
resource "aws_route_table" "public" {}
count / for_eachفي الكودtagsفي الكودcountفي الكودلا تعيد اختراع العجلة في وحدات الموارد: استخدم الاسمnameوالوصفdescriptionوالقيمة الافتراضية defaultللمتحولات كما هو محدد في قسم "Argument Reference" للمورد الذي تعمل معه.
عملية التحقق (Validation) من المتحولات محدود نوعًا ما (على سبيل المثال ، لا يمكن الوصول إلى متحولات أخرى أو إجراء عمليات بحث). خطط وفقًا لذلك لأنه في كثير من الحالات تكون هذه الميزة غير مجدية.
استخدم صيغة الجمع في اسم متحول عند يكون نمطه
اجعل المخرجات متسقة ومفهومة خارج سياقها ( عندما يتم استعمال وحدة من قبل مستخدم يجب على المخرجات أن تكون واضح ما هو نمط وما صفات القيمة التي ترجعها)
يجب على اسم الخرج أن يصف القيمة التي يرجعها وأن تكون أقل حرية مما تريد عادة.
الشكل الجيد لاسم الخرج يكون كالتالي {attribute}_{type}_{name} حيث:
إن {name} هو اسم المورد أو اسم مصدر البيانات بدون اسم الموفر. كمثال للمورد aws_subnet يكون الاسم هو
تعيد على الأكثر Security group ID وحيد
عند وجود عدة مصادر من نفس النمط، يجب حذفthisمن الخرج:
إذا كانت قيمة الخرج عبارة عن list فإنه يجب أن نستعمل اسم جمع :
resource "aws_route_table" "public_route_table" {}resource "aws_route_table" "public_aws_route_table" {}
يجب تسمية المورد باسمthisإذا لم يكن هناك اسم وصفي وعام متاح، أو إذا كانت وحدة الموارد تنشئ موردًا واحدًا من هذا النوع (كمثال في AWS VPC module يوجد فقط مورد وحيد من النوع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أو أي تعابير أخرى
listmapقم بترتيب الأقسام في المتحول كالتالي:descriptionثمtypeثمdefaultوأخيراًvalidation
دائماً قم بإضافة قسمdescription إلى كل المتحولات حتى لو كنت تظن أنه واضح (ستحتاجه في المستقبل)
فضل استعمال الأنواع البسيطة (number, string, list(...), map(...), any) على الأنواع الأخرى مثلobject،إلا إذا كنت تحتاج قيود صارمة على كل key
استعمل الأنماط المحددة مثلmap(string) في حال كانت كل العناصر الموجودة داخلها من نفس النمط أو كان يمكن تحويلها إلى هذا النمط (مثلاً النمطnumberممكن تحويله إلى النمطstring)
استعمل النمط anyلتعطيل التحقق من النوع بدءاً من عمق معين أو عندما يجب دعم أنواع متعددة
القيمة {} هي عبارة عن map في بعض الأحيان وobject في أحيان أخرى. استعمل ()tomap لجعلها من النمط map دائماً.
subnetaws_vpcvpc إن {type}هو نمط الخرج الئي نتعامل معه
إن{attribute}هو الصفة المخرجة
إذا كان الخرج يعيد قيمة مع استعمال interpolation functions وعدة موارد فيجب على {name} و{type} أن تكون معممة قدر الإمكان (this يجب حذفها)انظر الأمثلة
إذا كانت قيمة الخرج عبارة عن list فإنه يجب أن نستعمل اسم جمع انظر الأمثلة
دائماً قم بإضافة قسمdescription إلى كل المخرجات حتى لو كنت تظن أنه واضح
تجنب وضع وسيط sensitiveإلا إذا كنت تملك تحكم كامل باستعمال هذا الخرج في كل الأماكن في كل الوحدات
فضل استعمال ()try (متوفرة منذ الإصدار 0.13) على استعمال element(concat(...))(التي كانت تستعمل قبل 0.13)
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
}resource "aws_route_table" "public" {
vpc_id = "vpc-12345678"
count = 2
# ... remaining arguments omitted
}resource "aws_nat_gateway" "this" {
count = 2
allocation_id = "..."
subnet_id = "..."
tags = {
Name = "..."
}
depends_on = [aws_internet_gateway.this]
lifecycle {
create_before_destroy = true
}
} resource "aws_nat_gateway" "this" {
count = 2
tags = "..."
depends_on = [aws_internet_gateway.this]
lifecycle {
create_before_destroy = true
}
allocation_id = "..."
subnet_id = "..."
}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
}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, "")
}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)
output "rds_cluster_instance_endpoints" {
description = "A list of all cluster instance endpoints"
value = aws_rds_cluster_instance.this.*.endpoint
}FTP (Frequent Terraform Problems اكثر المشاكل التي تعاني منها الأداة)
أداة Terragrunt -أداة تنسيق
أداة
أداة - إدارة الإصدارات
أداة أتمتة العمل مع PR
أداة مجموعة من git-hooks خاصة بأداة Terraform التي يتم استعمالها مع إطار العمل
يجب تحديد إصدار الوحدة التي نتعامل معها. يجب تعريف الموفرات خارج الوحدات وفقط في التراكيب، يجب أيضاً تحديد إصدار الموفرات وإصدار Terraform أالذي نتعامل معه.
لا يوجدا أداة إدارة Dependency، لكن يوجد بعض النصائح التي تجعل هذه المشكلة أقل إشكالاً. كمثال يمكن استعمال أداة لأتمتة تحديث الارتباطات. تقوم هذه الأداة بإنشاء PR للحفاظ على الارتباطات بشكل أمن ومحدث. تدعم هذه الأداة ملفات Terraform.