كيف تحسين المرونة باستخدام متغيرات Terraform، الاعتمادات، والشروط

مقدمة

لغة configuration Hashicorp (HCL)، التي Terraform يستخدمها، توفر أساليب وقدرات مفيدة كثيرة تواجد أيضًا في اللغات البرمجية الأخرى. ومع استخدام الدورات في كود بنية التحكم يمكنك تخفيض تكرار الكود وزيادة القابلية للقراءة، مما يسهل تغيير البنية التحكمية في المستقبل ويزيد من المرونة. يوفر HCL أيضًا بعض الأبناء البيانية الشائعة، مثل القوائم والخرائط (والتي يطلق عليها في اللغات الأخرى التواريخ والقواميس بالمرة الأولى),والشروط التي تسمح للمسار التنفيذي بالتفرقة.

ما هو من الواحد فقط ل Terraform هو قدرتك على تحديد بواسطة اليد المصادر التي تعتمد عليها. بينما ستحصل على الجدول التنفيذي الذي يبنيه عند تشغيل بنية الكود بالفعل والذي يحتوي على الروابط التي يكتشفها (والتي صحيحة في معظم الحالات),قد تجد نفسك في حاجة إلى تحكيم على علاقة الاعتماد التي تعتبر تعجز Terraform عن اكتشافها.

في هذه المقالة، سننظر في الأبناء البيانية التي يوفرها HCL، وخصائص الدورات التي يتم استخدامها للموارد (مفتاح count، for_each، وfor)، والشروط التي تسمح للمعالجة مع قيم معروفة وغير معروفة، وعلاقات الاعتماد بين الموارد.

المتطلبات

  • توكيل شخصي لـ DigitalOcean، يمكنك إنشاؤه عبر لوحة التحكم في DigitalOcean. يمكنك إيجاد التعليمات في المستندات المنتجة لـ DigitalOcean، كيفية إنشاء توكيل شخصي.
  • ترافورم متصل بجهازك المحلي ومشروع مع المزيد الخاص بـ DigitalOcean. اكمال خطوة 1 و خطوة 2 من التutorial كيفية استخدام ترافورم مع DigitalOcean، وأنت يجب أن تسمي مجلد المشروع terraform-flexibility بدلاً من loadbalance. أثناء خطوة 2، لن تحتاج إلى تضمين متغير pvt_key ومورد المفتاح الخاص بالتوكيل.

تنبيه: قد تم اختبار هذا التutorial بترافورم من DigitalOcean 1.0.2 بالتحديد.

أنواع البيانات في HCL

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

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

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

القوائم

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

variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third"]
}

في type، أخبرت بأنها قائمة ونوع عناصرها هو النص، ثم أعطيت قيمتها الdefault. في HCL، تعني القيم التي تختلف في الأقواس تشير إلى قائمة.

الخرائط<

تعني خوارزميات المعلومات هي مجموعة من الزوامير-قيم حيث يمكن الوصول إلى كل قيمة من خلال مفتاحها النوع string. وهناك طريقتين لتعريف الخوارزميات داخل علامات القوائم العجيبة: باستخدام التوقفات (:) أو نقاط التساوي (=) لتحديد القيم. في ال两种 أوليائين، يتوجب تعبئة القيمة بال citation تقدم. عند استخدام التوقفات، يتوجب تعبئة أيضًا المفتاح.

يمكن كتابة تعريف الخوارزمية التالية تحتوي على أسماء الجسيمات التي تم تسميتها لبيئات مختلفة باستخدام النقاط التساوي:

variable "droplet_env_names" {
  type = map(string)

  default = {
    development = "dev-droplet"
    staging = "staging-droplet"
    production = "prod-droplet"
  }
}

إذا بدأ مفتاحك برقم، يتوجب استخدام نمط التوقفات:

variable "droplet_env_names" {
  type = map(string)

  default = {
    "1-development": "dev-droplet"
    "2-staging": "staging-droplet"
    "3-production": "prod-droplet"
  }
}

المجموعات

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

تقديم مجموعة يشبه تقديم قائمة، الفرق يكمن في نوع المتغير:

variable "droplet_names" {
  type    = set(string)
  default = ["first", "second", "third", "fourth"]
}

وبما أنك تعلمت عن أنواع البنيات التحكمية التي يقدمها HCL ونظرت على نمطيات القوائم والخوارزميات والمجموعات، التي سنستخدمها طوال هذا التورية، سوف تنتقل إلى محاولات مرنة لتنفيذ عدة

تعديل عدد الموارد باستخدام المفتاح count

في هذا الجزء ، ستقوم بإنشاء معالم متعددين لنفس المورد باستخدام المفتاح count. المفتاح count متاح على جميع الموارد ويحدد العدد الذي يتم إنشاؤه من نفس المورد.

سترى كيف يعمل هذا المفتاح عن طريق كتابة مورد دروبلت ، الذي ستتخزين في ملف يسمى droplets.tf في الدليل المشارك الذي أنشأته كجزء من المتطلبات السابقة. قم بإنشاؤه وفتحه للتحرير بتنفيذ:

  1. nano droplets.tf

أضف السطور التالية:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = 3
  image  = "ubuntu-20-04-x64"
  name   = "web"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

هذا الكود يعرف مورد دروبلت يدعى test_droplet والذي يعمل Ubuntu 20.04 مع 1GB من الRAM ونقطة معالج.

لاحظ أن قيمة count معدلة إلى 3، وهذا يعني أن ترافيب ستحاول إنشاء ثلاث معالم من نفس المورد. عندما يتم الانتهاء من هذا، احفظ وغلق الملف.

يمكنك تخطيط المشروع لرؤية ما تقوم به الترافيب بتنفيذ:

  1. terraform plan -var "do_token=${DO_PAT}"

ستكون الخريطة تشابه هذه:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.test_droplet[0] سيتم إنشاؤه + resource "digitalocean_droplet" "test_droplet" { ... name = "web" ... } # digitalocean_droplet.test_droplet[1] سيتم إنشاؤه + resource "digitalocean_droplet" "test_droplet" { ... name = "web" ... } # digitalocean_droplet.test_droplet[2] سيتم إنشاؤه + resource "digitalocean_droplet" "test_droplet" { ... name = "web" ... } Plan: 3 to add, 0 to change, 0 to destroy. ...

يوجد تفاصيل الخليفة التي تخلق Terraform ثلاث مستندات من test_droplet، جميعها تحمل نفس الأسم web، وعلى الرغم من أن ذلك ممكن ، لكنه غير مفضل ، لذلك دعونا نغير تعريف القطعة التي تحمل أسم فريد لكل مستندة. افتح droplets.tf للتحرير:

  1. nano droplets.tf

تعديل السطر المبرز:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = 3
  image  = "ubuntu-20-04-x64"
  name   = "web.${count.index}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

حفظ وغلق الملف.

يوفر العنصر count الخاصة index ، والتي تحتوي على معدل التدوير الحالي ، يبدأ من 0. يتم تبديل المعدل الحالي في إسم القطعة التي تحمل باستخدام تدوينة السلسلة ، وهي التي تسمح لك ببناء سلسلة ديناميكية بتبديل المتغيرات. يمكنك خطة المشروع مجدداً لرؤية التغيرات:

  1. terraform plan -var "do_token=${DO_PAT}"

ستكون المخرجة مشابهة لهذه:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.test_droplet[0] will be created + resource "digitalocean_droplet" "test_droplet" { ... name = "web.0" ... } # digitalocean_droplet.test_droplet[1] will be created + resource "digitalocean_droplet" "test_droplet" { ... name = "web.1" ... } # digitalocean_droplet.test_droplet[2] will be created + resource "digitalocean_droplet" "test_droplet" { ... name = "web.2" ... } Plan: 3 to add, 0 to change, 0 to destroy. ...

هذه المرة، ستحملت الثلاث مستندات test_droplet بمعدلها في أسماءها، مما يجعلها أسهل علمه.

والآن تعرف كيفية إنشاء عدد من النسخ المتعددة من المورد باستخدام مفتاح count ، وكيفية استعمال معدل مستندة خلال التوفير. ومن ثم سوف تتعلم كيفية تحصيل أسم القطعة من قائمة.

جذب أسماء القطع النازلة من قائمة

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

ستحتاج أولاً إلى تعريف قائمة تحوي أسماء القطع النازلة. قم بإنشاء ملف يدعى variables.tf وافتحه للتحرير:

  1. nano variables.tf

أضف ال行هذه التالية:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third", "fourth"]
}

حفظ وغلق الملف. هذ البرمجيات تعرف قائمة تدعى droplet_names تحوي جملة first، second، third، و fourth.

افتح droplets.tf للتحرير:

  1. nano droplets.tf

تعديل السطور المبرزة:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = length(var.droplet_names)
  image  = "ubuntu-20-04-x64"
  name   =  var.droplet_names[count.index]
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

لزيادة المرونة، بدلاً من تعيين عدد ثابت من العناصر باليد، تأتي باسم القائمة droplet_names إلى ما يمكن أن يعود دائمًا إلى عدد العناصر في القائمة. وللاسم، تحصل على عنصر القائمة الموجود في count.index باستخدام نمط الصفقة التركيبية. حفظ وغلق الملف حينما تنتهي.

حاول مجددًا تخطيط المشروع. ستحصل على خريطة مشابهة لهذه:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: سيتم إنشاء digitalocean_droplet.test_droplet[0] + resource "digitalocean_droplet" "test_droplet" { ... + name = "first" ... } سيتم إنشاء digitalocean_droplet.test_droplet[1] + resource "digitalocean_droplet" "test_droplet" { ... + name = "second" ... } سيتم إنشاء digitalocean_droplet.test_droplet[2] + resource "digitalocean_droplet" "test_droplet" { ... + name = "third" ... } سيتم إنشاء digitalocean_droplet.test_droplet[3] + resource "digitalocean_droplet" "test_droplet" { ... + name = "fourth" ... Plan: 4 to add, 0 to change, 0 to destroy. ...

نتيجة لهذه التعديلات، سيتم إنشاء أربعة دروبليتات، تتسم بالأسماء المتبوعة بعد عناصر قائمة droplet_names.

لقد تعلمت عن count، وميزاته وصيغته، واستخدمته مع قائمة لتعديل مثيلات الموارد. سترى الآن عيوبه، وكيفية التغلب عليها.

فهم العيوب الخاصة بـ count

الآن بما أنك تعرف كيفية استخدام عدد، دعنا نستعرض عيوبه عند تعديل القائمة التي يتم استخدامها معها.

لنحاول إنشاء الدروبليتات في السحابة:

  1. terraform apply -var "do_token=${DO_PAT}"

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

Output
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

الآن دعنا ن создаем حالة دروبليت إضافية عن طريق توسيع قائمة droplet_names. افتح variables.tf للتحرير:

  1. nano variables.tf

أضف عنصرًا جديدًا في بداية القائمة:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["zero", "first", "second", "third", "fourth"]
}

عند انتهائك، احفظ الملف وأغلقه.

تخطط للمشروع:

  1. terraform plan -var "do_token=${DO_PAT}"

سوف تحصل على خريطة الخروج مثل هذه:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create ~ update in-place Terraform will perform the following actions: # digitalocean_droplet.test_droplet[0] سيتم تحديثه في المكان ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "first" -> "zero" ... } # digitalocean_droplet.test_droplet[1] سيتم تحديثه في المكان ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "second" -> "first" ... } # digitalocean_droplet.test_droplet[2] سيتم تحديثه في المكان ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "third" -> "second" ... } # digitalocean_droplet.test_droplet[3] سيتم تحديثه في المكان ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "fourth" -> "third" ... } # digitalocean_droplet.test_droplet[4] سيتم إنشائه + resource "digitalocean_droplet" "test_droplet" { ... + name = "fourth" ... } Plan: 1 to add, 4 to change, 0 to destroy. ...

يظهر الخريطة أن ترافيسفورم سيغير أسماء الأربع درابلتات الأولى وسيتم إنشاء درابلتة خامسة تدعى fourth لأنه يعتبر الأحيان قائمة مرتبطة ويتم تحديد العناصر (الدرابلتات) بأرقامهم في القائمة. هذه هي كيف يعتبر ترافيسفورم الأربع درابلتات في البدء:

Index Number 0 1 2 3
Droplet Name first second third fourth

عندما يضاف درابلتة جديدة zero إلى البداية، يبدو تمثالها الداخلي كهذا:

Index Number 0 1 2 3 4
Droplet Name zero first second third fourth

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

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

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

المرجع إلى الموارد الحالية (self)

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

المثال الرئيسي هو destroy-time provisioners التي تشتغل عندما يخطط لتدمير الموارد. السبب هو أن العنصر المطلوب قد لا يكون موجودًا (يكون قد تم تدميره) أو سيكون هناك دورة تعلق تعاوني متعددة. في هذه الحالات ، بدلًا من تعريف العنصر عبر قائمة الأعناصر، يمكنك أن تستأقل الموارد الحالية من خلال كلمة المرجع self.

لإظهار أستخدامها، سوف تقوم بإضافة مؤهل لتنذير في الوقت المناسب لتعريف test_droplet، وسيظهر رسالة حين تجري التنفيذ. افتح droplets.tf للتحرير:

  1. nano droplets.tf

قم بإضافة الأخطاء المعلّمة بالتالي:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = length(var.droplet_names)
  image  = "ubuntu-20-04-x64"
  name   =  var.droplet_names[count.index]
  region = "fra1"
  size   = "s-1vcpu-1gb"

  provisioner "local-exec" {
    when    = destroy
    command = "echo 'Droplet ${self.name} is being destroyed!'"
  }
}

حفظ وغلق الملف.

مؤهل التنفيذ المحلي يجري أمرًا على الآلة المحلية التي يتجرأ فيها Terraform. لأن ما يحدده المامور when يعتمد على destroy، سيتم تنفيذه فقط عندما يكون المورد على الوشك أن يتم تدميره. الأمر الذي يجري يعكس عبارة على الstdout، ويحلّل اسم المورد الحالي بواسطة self.name.

لأنك ستقوم بإنشاء الDroplets بطريقة مختلفة في القسم المقبل، يجب تدمير التي تم تدميرها بواسطة الأمر التالي:

  1. terraform destroy -var "do_token=${DO_PAT}"

أدخل yes حين التقاء. سوف تحصل على المؤهل local-exec يتم تنفيذه أربع مرات:

Output
... digitalocean_droplet.test_droplet[0] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet first is being destroyed!'"] digitalocean_droplet.test_droplet[1] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet second is being destroyed!'"] digitalocean_droplet.test_droplet[1] (local-exec): Droplet second is being destroyed! digitalocean_droplet.test_droplet[2] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet third is being destroyed!'"] digitalocean_droplet.test_droplet[2] (local-exec): Droplet third is being destroyed! digitalocean_droplet.test_droplet[3] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet fourth is being destroyed!'"] digitalocean_droplet.test_droplet[3] (local-exec): Droplet fourth is being destroyed! digitalocean_droplet.test_droplet[0] (local-exec): Droplet first is being destroyed! ...

في هذه الخطوة تعلمت عن أخطاء count. سوف تعلم عن بنية التكرار for_each التي تتجنبها وتعمل على مجموعة واسعة من أنواع المتغيرات.

تكرار باستخدام for_each

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

for_each هو 매개변수 يتوفر على كل مورد، ولكن على عكس count الذي يتطلب عددًا من الحالات لإنشائها، يقبل for_each خريطة أو مجموعة. يتم تنقل كل عنصر من المجموعة المقدمة مرة واحدة ويتم إنشاء حالة له. يجعل for_each الأساس والقيمة متاحين تحت كلمة الرمز each كصفات (الزوج من الأساس والقيمة كـ each.key و each.value على التوالي). عند تقديم مجموعة، ستكون الأساس والقيمة متشابهة.

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

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

دعونا نحول مورد الرقم الأولي من count إلى for_each ونرى كيف يعمل في الممارسة. افتح droplets.tf لتحريره عن طريق تشغيل:

  1. nano droplets.tf

قم بتعديل الأسطر المبرزة:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  for_each = toset(var.droplet_names)
  image    = "ubuntu-20-04-x64"
  name     = each.value
  region   = "fra1"
  size     = "s-1vcpu-1gb"
}

يمكنك إزالة موفر الاستجابة local-exec. عند الانتهاء، احفظ الملف وأغلقه.

تم إستبدال السطر الأول بـ count و تم طلب for_each بتقديم droplet_names كقائمة باستخدام ما يسمى ب toset الذي يتم تحويل المعطي آليا. و للأسم للقاعدة تحددت each.value و التي تحتوي قيمة العنصر الحالي من قاعدة الأسماء التي تم تحويلها إلى مجموعة. و هذا المجموعة من الأسماء التي ستُخْرجُ

تخطط للمشروع بتشغيل:

  1. terraform plan -var "do_token=${DO_PAT}"

ستتم تفاصيل الخطوات التي ستتخذها Terraform:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.test_droplet["first"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "first" ... } # digitalocean_droplet.test_droplet["fourth"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "fourth" ... } # digitalocean_droplet.test_droplet["second"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "second" ... } # digitalocean_droplet.test_droplet["third"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "third" ... } # digitalocean_droplet.test_droplet["zero"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "zero" ... } Plan: 5 to add, 0 to change, 0 to destroy. ...

بخلاف استخدام count فإن Terraform الآن يعتبر كل منشأ بشكل فردي و ليس كعناصر من قائمة مرتبطة. و كل منشأ مرتبط بعنصر من المجموعة المعطية كما يُعْرِض في الرسم البياني بجهة كل مورد الذي سيُنشأ.

تطبيق الخطة في السحابة عن طريق التشغيل:

  1. terraform apply -var "do_token=${DO_PAT}"

أدخل yes عندما يطرح السؤال. و بمجرد انتهاء العملية ستأخذ عنصراً واحداً من droplet_names لإظهار أن المنشآء الآخر لن يتأثر. و قم بتحرير variables.tf:

  1. nano variables.tf

modifique la lista para que se parezca a esto:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third", "fourth"]
}

Guarde y cierre el archivo.

Planifique el proyecto de nuevo, y recibirá la siguiente salida:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # digitalocean_droplet.test_droplet["cero"] será destruido - resource "digitalocean_droplet" "test_droplet" { ... - name = "zero" -> null ... } Plan: 0 to add, 0 to change, 1 to destroy. ...

Esta vez, Terraform destruirá solo la instancia eliminada (cero), y no tocará ninguna de las otras instancias, lo cual es el comportamiento correcto.

En este paso, ha aprendido sobre for_each, cómo utilizarlo, y sus ventajas sobre count. A continuación, aprenderá sobre el bucle for, su sintaxis y uso, y cuándo se puede utilizar para automatizar ciertas tareas.

Usar bucle for para iterar

El bucle for funciona en colecciones y crea una nueva colección aplicando una transformación a cada elemento del entrada. El tipo exacto de la salida depende de si el bucle está rodeado de corchetes ([]) o llaves ({}), que proporcionan una lista o un mapa, respectivamente. Como tal, es adecuado para consultar recursos y generar salidas estructuradas para su procesamiento posterior.

La sintaxis general del bucle for es:

for element in collection:
transform(element)
if condition

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

سوف تعمل على عدد قليل من الأمثلة باستخدام الخاصية الخارجية. سوف تتخزن فيها في ملف تمرير الاسم outputs.tf. أنشئه للتحرير بتنفيذ الأمر التالي:

  1. nano outputs.tf

أضف السطور التالية لإخراج أزواج من أسماء الأجسام المتنقلة وأي عناوينها التالية:

terraform-flexibility/outputs.tf
output "ip_addresses" {
  value = {
    for instance in digitalocean_droplet.test_droplet:
    instance.name => instance.ipv4_address
  }
}

هذا البرمجيات تحدد خاصية تسمى ip_addresses، وتحدد دورة for تتكرر فوق تواجد المصادر المختارة لمورد test_droplet التي قمت بتخصيصها في الخطوات السابقة. لأن الدورة محاطة بتعايير، ستكون ما يحصل عليه من الخاصية خريطة. خطوة التحويل للخرائط تشبه المرافق القائمة على المجموعات في البرمجيات الأخرى، وهنا تخلق قاعدة مفاتيح-قيم عن طريق تواصل تسمية المصادر كمفتاح مع عنوان الـIP الخاص بها كقيمة.

حفظ وغلق الملف ثم تحديدًا تحديد الحالة الموجودة في Terraform بتنفيذ:

  1. terraform refresh -var "do_token=${DO_PAT}"

أمر Terraform refresh يحدد الحالة الموجودة في الأحوال المحلية مع الحالة الحقيقية للبنية التحتية في السحابة.

ومن ثم، قم بتفقد محتويات الخاصية الخارجية:

Output
ip_addresses
= { "first" = "ip_address" "fourth" = "ip_address" "second" = "ip_address" "third" = "ip_address" }

تظهر ترافورم المحتويات من الip_addresses الخاصة بالخريطة التي تنشأ من دورة الfor. (قد تكون ترتيب إدخالاتك مختلف لديك). الدورة تعمل بشكل سلس لأي عدد من الإدخالات — ما يعني أنه يمكنك أن تضيف عنصر جديد إلى قائمة droplet_names والجديد سيتم إنشاؤه دون أي تعامل يدوي extra، سيظهر أيضًا في هذه الخريطة تلقائيًا.

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

terraform-flexibility/outputs.tf
output "ip_addresses" {
  value = [
    for instance in digitalocean_droplet.test_droplet:
    instance.ipv4_address
  ]
}

في هذه المرحلة المحورية تحدد البيانات العنصر العنوان التعريفي. ستقدم الخريطة التالية:

Output
ip_addresses
= [ "ip_address", "ip_address", "ip_address", "ip_address", ]

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

terraform-flexibility/outputs.tf
output "ip_addresses" {
  value = [
    for instance in digitalocean_droplet.test_droplet:
    instance.ipv4_address
    if instance.region == "fra1"
  ]
}

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

لأنك ستقوم بإنشاء الموارد بطريقة مختلفة في القسم القادم، يجب أن تدمر الموارد المتوفرة الآن بتنفيذ الأمر التالي:

  1. terraform destroy -var "do_token=${DO_PAT}"

أدخل yes عندما يتم طرح السؤال لإنهاء العملية.

لقد تم إنتقاء الfor لولو، والبنية السينتايكية له وأمثلة على استخدامه في الخروجيات. سوف تتعلم المشاعر الشرطية وكيف يمكن استخدامهم مع count.

الإشارات والشروط المتعددة

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

البنية السينتايكية لمعالجي الشرطيات الثلاثية الحاليين هي:

condition ? value_if_true : value_if_false

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

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

في حالة استخدام المتغير الثلاثي المعني للحصول على عنصر واحد من قاعدة أو مجموعة، يمكنك استخدام المétodo one المعني. إذا كانت المجموعة المعطاة فارغة، فإنه يعود ب null. إلا إذا كانت لديها عنصر واحد فقط، ويلanza خطأ إذا كان هناك عدد من العناصر المتعدد.

دعونا نضيف متغيرًا يدعى create_droplet، والذي سيسيطر على إنشاء دوبلت أو لا. أولًا، افتح variables.tf للتعديل:

  1. nano variables.tf

أضف الأخطاء المبرزة:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third", "fourth"]
}

variable "create_droplet" {
  type = bool
  default = true
}

هذ البرمجيات تحدد create_droplet متغيرًا من النوع bool. حفظ وغلق الملف.

من ثم، لتعديل اعلان الدوبلت، افتح droplets.tf للتعديل بتشغيل:

  1. nano droplets.tf

أعد ملفك مثل التالي:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = var.create_droplet ? 1 : 0
  image  = "ubuntu-20-04-x64"
  name   =  "test_droplet"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

في count، تستخدم معالج ثلاثي الخيار للعودة إلى 1 إذا كانت create_droplet متغيرًا صحيحًا، أو 0 إذا كان خطأً، وسينتج ذلك عدد صفر من الدوبلتات التي ستتم توفيرها. حفظ وغلق الملف عندما تنتهي.

خطط لتنفيذ خطة المشروع بمتغيرًا يكون مع false بتشغيل:

  1. terraform plan -var "do_token=${DO_PAT}" -var "create_droplet=false"

ستحصل على المخرج التالي:

Output
Changes to Outputs: + ip_addresses = {} You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.

لأن create_droplet تم تمريره بقيمة false، سيكون عدد count المناطق 0، ولن يتم إنشاء دوبلتات، لذا لن يكون هناك أي أعدادات IP للخروج.

لقد راقبت كيفية استخدام متغير الفرضية الثلاثية مع مفتاح count لتمكينك على مستوى عالٍ من الاختيارات في معرفت إذا كان عليك تخزين الموارد المرغوب فيها. سوف تتعلم المزيد عن تعيين الاعتمادات الموردية بوضوح لمواردك الخاصة.

تعيين الاعتمادات الموردية بوضوح

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

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

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

هذا مثال عن

resource "digitalocean_droplet" "droplet" {
  image  = "ubuntu-20-04-x64"
  name   = "web"
  region = "fra1"
  size   = "s-1vcpu-1gb"

  depends_on = [
    # موارد...
  ]
}

يقبل قائمة من المراجعات إلى موارد أخرى، ولا يقبل تعبيرات تعساء.

depends_on يجب أن يستخدم بتوافق، وفقط عندما يتناسب جميع الخيارات الأخرى. وإستخدامه يعني أن ما تحاول تعريفه يختلف خارج مجالات نظام كشف الاعتمادات الautomated التي يقوم بها Terraform؛ قد يعني أن الموارد تعتمد بوضوح على أكثر من الموارد التي تحتاج إليها.

لقد تعلمت الآن عن تعريف بوابة الاعتمادات الإضافية للموارد باستخدام مفتاح depends_on، وفي أي وقت يجب أن يستخدم.

الخلاصة

في هذا المقال، نظرنا إلى ميزات HCL التي تحسن المرونة والقابلية المتناولة لكدماتك، مثل count ل especifying عدد من معاملات الموارد التي تتم توزيعها و for_each كطريقة متقدمة للدورة حول أنماط قاعدة بيانات وتخصيص المعملات. وباستخدامهم بطريقة صحيحة، يتم تخفيض تكرار الكدمات وتكاليف إدارة البنية التي تم توزيعها.

أيضًا تعلمت عن الشروط والمؤشرات الثنائية، وكيف يمكن استخدامهم لل控制 إذا كان سيتم توزيع الموارد. بينما يكون نظام تحليل الاعتمادات الautomated في Terraform قادرًا جدًا، قد يكون هناك حالات تحتاج إلى تعريف يدويًا للاعتمادات المواردية باستخدام مفتاح depends_on.

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

Source:
https://www.digitalocean.com/community/tutorials/how-to-improve-flexibility-using-terraform-variables-dependencies-and-conditionals