كيف تقرأ هذه الصفحة. عشر خطوات، أمر واحد في كل مرة. لكل منها : الأمر الذي تكتبه، والمخرجات الدقيقة لجهاز الدورة (Terraform 1.12.2)، وما يجب النظر إليه فيها. اكتب كل أمر بنفسك (لا نسخ ولصق) : بكتابة
initوplanوapplyوstateترسخ الكلمات. كتل « لفهم أفضل » اختيارية ؛ افتحها إذا تركت لك خطوة شكًا. أوامرterraform …متطابقة على Windows وLinux وmacOS ؛ وعندما يعتمد أمر على النظام (إنشاء ملف، قراءته، سرد محتوى)، تُعطى النسختان، إحداهما تحت الأخرى. إذا لم يكن Terraform مثبَّتًا أو لم تكن العُدّة مستنسخة، فارجع إلى المشروع 01، قسم باختصار (العُدّة :https://github.com/hrhouma2/aiopsatlas-terraform-labo-fr).
جعلك المشروع 01 تنفّذ ثلاثة عشر أمرًا على main.tf من خمسة عشر سطرًا، مع كتلة terraform وكتلة provider وكتلة resource. رأيت الجمل تمرّ، لكن خمسة عشر سطرًا كثيرة أصلًا لمعرفة ما هو ضروري فعلًا. هنا، تنطلق من الصفر بـ ثلاثة أسطر مفيدة : كتلة resource واحدة، بلا شيء حولها. سترى Terraform يرفض العمل بدون init، ثم تجعله يكتب كشفه، وينفّذه، وتقرأ ما دوّنه في سجله. في النهاية، تعرف ما هي الكتلة والخطة وstate لأنك صنعتها بنفسك، واحدة بعد الأخرى.
استعد المهندس المعماري من الدرس 01. الكتلة resource سطر في مخطط المهندس : « هنا، ملف، بهذا الاسم وهذا المحتوى ». الخطة (الأمر) هي الكشف : ما سيفعله Terraform ليشبه الواقع الرسم. State هو السجل : ما بناه Terraform فعليًا، تحت أي معرّف، وبأي قيم. ثلاثة كائنات، ثلاثة أوامر لرؤيتها : تُقرأ الكتلة في main.tf، والكشف بـ terraform plan، والسجل بـ terraform state show.
| Terraform | ما هو | في هذه الورشة |
|---|---|---|
كتلة resource "type" "nom" | شيء يجب إدارته، موصوف في ملف .tf | resource "local_file" "bonjour" |
| نوع المورد | ما هو، يوفّره مزوّد | local_file (ملف على القرص) |
| الاسم المحلي | كيف تسمّيه في شيفرتك | bonjour |
| العنوان | النوع . الاسم، للحديث عنه في مكان آخر | local_file.bonjour |
| الوسيط (argument) | قيمة تكتبها في الكتلة | filename، content |
| الخاصية (attribute) | قيمة يحسبها المزوّد | id، content_md5 |
| الخطة | الكشف : ما ينقص بين الشيفرة والواقع | Plan: 1 to add, 0 to change, 0 to destroy. |
| state | السجل : ما بناه Terraform | terraform.tfstate، يُقرأ بـ state list وstate show |
طرفية (PowerShell على Windows ؛ bash أو zsh على Linux وmacOS وWSL 2 أو Git Bash)، مفتوحة في جذر العُدّة lab-terraform، الذي يحتوي على labo.ps1 وlabo.sh. وVS Code لكتابة الملف. تُكتب أوامر terraform … بالطريقة نفسها تمامًا في كل مكان ؛ فقط أوامر إنشاء ملف أو قراءته أو سرده تتغيّر، وتُعطى في النسختين كل مرة.
Windows (PowerShell) :
.\labo.ps1 nouveau atelier-1
cd travail\atelier-1Linux وmacOS وWSL 2 وGit Bash :
./labo.sh nouveau atelier-1
cd travail/atelier-1Dossier travail/atelier-1 créé (ignoré par Git). Tapez :
cd travail/atelier-1ما يطلبه الأمر : أنشئ لي مجلد عمل فارغًا، travail/atelier-1، سيتجاهله Git (على Windows يكتب السكربت travail\atelier-1، بالشرطة المائلة العكسية). (رسالة العُدّة تعني : « أُنشئ المجلد travail/atelier-1 (يتجاهله Git). اكتب : »)
ما يجب النظر إليه : المجلد فارغ. لا شيء مشروع Terraform بعد : main.tf، ثم init، هما ما سيجعلانه كذلك.
في VS Code (code . من داخل المجلد)، أنشئ ملفًا main.tf واكتب بالضبط :
resource "local_file" "bonjour" {
filename = "${path.module}/bonjour.txt"
content = "Bonjour Terraform"
}ما يطلبه الملف : « يا Terraform، أدِر لي ملفًا على القرص (local_file)، أسمّيه bonjour ؛ اسمه bonjour.txt، في هذا المجلد، ويحتوي على Bonjour Terraform. »
ما يجب النظر إليه : لا توجد كتلة terraform، ولا كتلة provider. المورد فقط. سيستنتج Terraform كل الباقي من كلمة local_file. تحقق من أن الملف موجود فعلًا ومسمّى بشكل صحيح :
Windows (PowerShell) :
Get-ChildItem
Get-Content .\main.tfLinux وmacOS وWSL 2 وGit Bash :
ls -la
cat main.tfمدخل واحد، main.tf، وأسطر الملف الأربعة. إذا رأيت main.tf.txt، فأعد تسميته.
"local_file" ثم "bonjour" : النوع، ثم الاسم. النوع يفرضه المزوّد (local_file موجود ؛ local_fichier غير موجود، وستحصل على Error: Invalid resource type). الاسم لك : bonjour، message، mon_fichier. معًا، يشكّلان العنوان local_file.bonjour الذي ستجده في الخطة وفي state.filename وcontent وسيطان : قيم تعطيها أنت. بالنسبة لـ local_file، content إلزامي (بدونه : Error: Invalid Attribute Combination)، وfilename كذلك.${path.module} يعني « المجلد الذي يوجد فيه ملف .tf هذا » ؛ سيعرضه Terraform ./bonjour.txt. بدونه، كان filename = "bonjour.txt" سيعمل أيضًا هنا ؛ يشرح المشروع 01 لماذا نعتاد على كتابته.= متحاذية (filename =، content =) : هذا أسلوب terraform fmt. لا يغيّر شيئًا في المعنى.terraform planError: Inconsistent dependency lock file
The following dependency selections recorded in the lock file are
inconsistent with the current configuration:
- provider registry.terraform.io/hashicorp/local: required by this configuration but no version is selected
To make the initial dependency selections that will initialize the dependency
lock file, run:
terraform initما يطلبه الأمر : « قل لي ماذا ستفعل ليشبه الواقع شيفرتي. »
ما يجب النظر إليه : يرفض Terraform، ويشرح. قرأ local_file، واستنتج منه أنه يحتاج إلى المزوّد registry.terraform.io/hashicorp/local، ويلاحظ أنه لا يملكه (no version is selected). السطر الأخير هو الحل : terraform init. هذا الخطأ الذي يصادفه كل مبتدئ مرة ؛ الآن تعرف قراءته.
terraform initInitializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/local...
- Installing hashicorp/local v2.9.1...
- Installed hashicorp/local v2.9.1 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
…ما يطلبه الأمر : « نزّل المزوّدين الذين تطلبهم شيفرتي وحضّر هذا المجلد. »
ما يجب النظر إليه : Finding latest version of hashicorp/local... : بدون كتلة required_providers، يأخذ Terraform أحدث إصدار (v2.9.1 على جهاز الدورة ؛ عندك، ربما أحدث). في المشروع 01، كان السطر نفسه يقول Finding hashicorp/local versions matching "~> 2.5"... لأن الشيفرة كانت تثبّت قيدًا. ثم الجملة المنتظرة : Terraform has been successfully initialized!
اسرد المجلد، مع الملفات المخفية :
Windows (PowerShell) :
Get-ChildItem -ForceLinux وmacOS وWSL 2 وGit Bash :
ls -laثلاثة مدخلات : .terraform (مجلد، المزوّد المنزَّل)، و.terraform.lock.hcl (الإصدار المختار، مدوَّنًا) وmain.tf الخاص بك. لا bonjour.txt بعد، ولا terraform.tfstate بعد : لم يبنِ init شيئًا.
init لا يمسّ مواردك أبدًا. يمكنك إعادة تشغيله كما تشاء. إنه يحضّر المجلد فقط..terraform/ ثقيل ويُعاد تنزيله (حوالي 18 ميغابايت هنا) : لا يدخل في Git أبدًا. .terraform.lock.hcl خفيف وقيّم : يدخل في Git، ليحصل زميلك على الإصدار نفسه من المزوّد.v2.9.1 ؛ وبعد ستة أشهر، v3.0.0 بسلوك مختلف. تتجنّب كتلة required_providers في المشروع 01 (version = "~> 2.5") المفاجأة. لورشة من عشرين دقيقة، نستغني عنها.terraform planTerraform 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:
# local_file.bonjour will be created
+ resource "local_file" "bonjour" {
+ content = "Bonjour Terraform"
+ content_base64sha256 = (known after apply)
+ content_base64sha512 = (known after apply)
+ content_md5 = (known after apply)
+ content_sha1 = (known after apply)
+ content_sha256 = (known after apply)
+ content_sha512 = (known after apply)
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "./bonjour.txt"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
─────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.ما يطلبه الأمر : الطلب نفسه كما في الخطوة 3. هذه المرة يملك Terraform مزوّده، ويجيب.
ما يجب النظر إليه، سطرًا سطرًا، لأنها المخرجات التي ستقرأها أكثر من أي شيء آخر طوال حياتك مع Terraform :
| السطر | ما يقوله |
|---|---|
+ create | مفتاح الكشف : رمز واحد مستخدم، +، إنشاء. |
# local_file.bonjour will be created | عنوان موردك ومصيره. لم يحدث بعد : will be. |
+ resource "local_file" "bonjour" { | كتلتك، منسوخة مع + أمامها : كل شيء جديد. |
+ content = "Bonjour Terraform" | وسيط كتبته أنت. يعرف Terraform قيمته. |
+ content_md5 = (known after apply) | خاصية لم تكتبها وسيحسبها المزوّد بعد إنشاء الملف : بصمته. لا يستطيع Terraform معرفتها قبل ذلك. |
+ directory_permission = "0777" | خاصية لم تكتبها وللمزوّد قيمة افتراضية لها. |
+ filename = "./bonjour.txt" | ${path.module}/bonjour.txt الخاص بك، محلولًا : . هو المجلد الحالي. |
+ id = (known after apply) | معرّف المورد، معروف فقط بعد الإنشاء. |
Plan: 1 to add, 0 to change, 0 to destroy. | السطر الذي يُقرأ أولًا. شيء واحد للإضافة، لا شيء للتغيير، لا شيء للتدمير. |
لم يُنشأ شيء. تحقق : bonjour.txt ما زال غير موجود في المجلد.
local_file، لا ما أعطيته إياه فقط. تعلّم التعرّف على وسائطك وتصفّح الخصائص سريعًا، ما عدا سطر Plan:.(known after apply) هي الجملة الأهم للفهم من أجل ما يلي : عندما يستخدم مورد B الـ id الخاص بمورد A لم يُنشأ بعد، يعرض B (known after apply) لهذه القيمة، ويعرف Terraform أنه يجب إنشاء A أولًا. هذا رسم التبعيات من الدرس 02، مشاهَدًا من الخطة.Note: You didn't use the -out option : هذا الكشف غير مسجَّل في ملف ؛ سيعيد apply حساب كشف مطابق. يُستخدم -out عندما يجب على pipeline تطبيق الخطة التي أُعيدت قراءتها بالضبط، لاحقًا في الدورة.terraform applyTerraform 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:
# local_file.bonjour will be created
+ resource "local_file" "bonjour" {
+ content = "Bonjour Terraform"
…
+ filename = "./bonjour.txt"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
local_file.bonjour: Creating...
local_file.bonjour: Creation complete after 0s [id=fd9aee5556589b4d797e6d49f8ec894e29e57713]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.ما يطلبه الأمر : « أعد حساب الكشف، أرِني إياه، انتظر موافقتي، ثم نفّذه. »
ما يجب النظر إليه : الخطة نفسها كما في الخطوة 5، ثم السؤال. اكتب yes، كاملة، ثم Enter. بعد ذلك Creating...، Creation complete after 0s [id=fd9aee55…] : الـ id الذي كان (known after apply) معروف الآن. والجملة المنتظرة : Apply complete! Resources: 1 added, 0 changed, 0 destroyed. الأعداد الثلاثة هي أعداد الخطة.
إذا كتبت y بدلًا من yes، يجيب Terraform بـ Apply cancelled. ولا يفعل شيئًا. جرّب مرة، لتكون قد رأيتها ؛ ثم أعد التشغيل بـ yes.
Windows (PowerShell) :
Get-Content .\bonjour.txt
Get-ChildItem -ForceLinux وmacOS وWSL 2 وGit Bash :
cat bonjour.txt
ls -laBonjour Terraformtotal 14
drwxr-xr-x 1 rehou 197609 0 sept. 15 14:55 .
drwxr-xr-x 1 rehou 197609 0 sept. 15 14:55 ..
drwxr-xr-x 1 rehou 197609 0 sept. 15 14:55 .terraform
-rw-r--r-- 1 rehou 197609 1228 sept. 15 14:55 .terraform.lock.hcl
-rw-r--r-- 1 rehou 197609 17 sept. 15 14:55 bonjour.txt
-rw-r--r-- 1 rehou 197609 111 sept. 15 14:55 main.tf
-rw-r--r-- 1 rehou 197609 1634 sept. 15 14:55 terraform.tfstate(سرد ls -la من جهاز الدورة ؛ يعرض Get-ChildItem -Force الأسماء الخمسة نفسها، بأعمدة أخرى.)
ما تطلبه الأوامر : « أرِني محتوى bonjour.txt، ثم كل ما في المجلد، بما في ذلك الملفات المخفية. »
ما يجب النظر إليه : Bonjour Terraform، 17 بايتًا، بالضبط content الخاص بك، بلا سطر جديد في النهاية (تحت bash، قد يظهر موجّه الأوامر ملتصقًا بالنص : هذا طبيعي). وجديدان في المجلد منذ الخطوة 4 : bonjour.txt، المورد، وterraform.tfstate، state. apply هو من أنشأ الاثنين، في الوقت نفسه : الملف على القرص، والملاحظة « أنشأته » في السجل.
terraform state listlocal_file.bonjourما يطلبه الأمر : « اسرد كل ما تديره في هذا المجلد. »
ما يجب النظر إليه : سطر واحد، مورد واحد، مُعيَّن بعنوانه local_file.bonjour، العنوان نفسه كما في الخطة. هذا دليل على أن Terraform ربط كتلتك بالملف الحقيقي. قبل الخطوة 6، كان الأمر نفسه سيجيب No state file was found! : لم يكن هناك سجل بعد.
terraform state show local_file.bonjour# local_file.bonjour:
resource "local_file" "bonjour" {
content = "Bonjour Terraform"
content_base64sha256 = "SvXkP5Iqo1rJKHgTVJnjanxfsNVGhb+r52mzUqZJYyg="
content_base64sha512 = "r3+PevYNJRFsHMz4H4U1DK+lg89nhO9SLJZMAqqtzPKiIv3ilrmbx5sYh2JCW9o5EF0NXanYmuxMvI2QN4Z1Ag=="
content_md5 = "ff3a967c227a58691a3d34a931d3eeb5"
content_sha1 = "fd9aee5556589b4d797e6d49f8ec894e29e57713"
content_sha256 = "4af5e43f922aa35ac92878135499e36a7c5fb0d54685bfabe769b352a6496328"
content_sha512 = "af7f8f7af60d25116c1cccf81f85350cafa583cf6784ef522c964c02aaadccf2a222fde296b99bc79b188762425bda39105d0d5da9d89aec4cbc8d9037867502"
directory_permission = "0777"
file_permission = "0777"
filename = "./bonjour.txt"
id = "fd9aee5556589b4d797e6d49f8ec894e29e57713"
}ما يطلبه الأمر : « أرِني كل ما تعرفه عن local_file.bonjour. »
ما يجب النظر إليه : الشكل نفسه كخطة الخطوة 5، لكن دون أي + ودون أي (known after apply) : كل شيء معروف، كل شيء مدوَّن. الـ id هو بصمة SHA-1 للمحتوى (fd9aee55…)، مطابقة لـ content_sha1 ولـ [id=…] الذي عرضه apply. وسيطاك (filename، content) موجودان، مع الخصائص التسع التي حسبها المزوّد. هذا هو مخرجك المطلوب : احتفظ به.
terraform.tfstate، في مجلدك. افتحه في VS Code لقراءته : قائمة "resources" بعنصر واحد، وفيها بالضبط القيم التي يعرضها state show. لا تعدّله أبدًا يدويًا : فاصلة منزاحة ولن يتعرّف Terraform بعدها على ما بناه.terraform.tfstate، يبقى bonjour.txt على القرص، لكن Terraform لن يعرف بعدها أنه ملكه : في plan التالي، سيقترح إنشاءه من جديد. State هو ذاكرة Terraform الوحيدة.terraform planlocal_file.bonjour: Refreshing state... [id=fd9aee5556589b4d797e6d49f8ec894e29e57713]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.ما يطلبه الأمر : الطلب نفسه كما في الخطوتَين 3 و5.
ما يجب النظر إليه : جديدان مقارنة بالخطوة 5. Refreshing state... [id=…] : قبل المقارنة، ذهب Terraform ليعيد قراءة الملف الحقيقي للتحقق من أنه ما زال مطابقًا للسجل. ثم No changes. Your infrastructure matches the configuration. : الشيفرة والسجل والواقع تقول الشيء نفسه، والكشف فارغ. هذا هو التكافؤ الذاتي من الدرس 01، في الطرفية : إعادة التشغيل لا تفعل شيئًا إضافيًا.
لا تدمّر شيئًا. تنطلق الورشة الأساسية 2 بالضبط من هذا المجلد، بهذا الملف وهذا state. إذا لم تتابعها فورًا، فاترك المجلد كما هو : لا شيء يُفوتَر، لا شيء يتحرك. (إذا أردت فعلًا محو كل شيء الآن : terraform destroy، yes، وستعيد الورشة 1 قبل الورشة 2.)
اصعد إلى جذر العُدّة وشغّل العدّاد :
Windows (PowerShell) :
cd ..\..
.\labo.ps1 etatLinux وmacOS وWSL 2 وGit Bash :
cd ../..
./labo.sh etattravail atelier-1 : 1 ressource dans le state
Ressources encore gérées : 1 (0 attendu à la fin d'une séance).الإجابة المنتظرة : 1 ressource dans le state (مورد واحد في state). عبارة (0 attendu à la fin d'une séance) (0 متوقع في نهاية الجلسة) هي تذكير العُدّة ؛ هنا من الطبيعي أن تكون عند 1، لأن الورشة 2 ستدمّر هذا المورد.
main.tf من كتلة واحدة، بلا terraform {} ولا provider {}، وكان ذلك كافيًا.Error: Inconsistent dependency lock file وتعرف أن الحل في السطر الأخير.init المجلد .terraform/ والملف .terraform.lock.hcl، ولا شيء آخر.+ create، will be created، (known after apply)، Plan: 1 to add, 0 to change, 0 to destroy.apply كلمة yes، وأنشأ bonjour.txt وterraform.tfstate.state list القيمة local_file.bonjour ؛ ويُرجع state show الكتلة الكاملة مع id من أربعين حرفًا.plan ثانٍ No changes.terraform state show local_file.bonjour (الخطوة 9) كمخرج مطلوب.terraform : Le terme «terraform» n'est pas reconnu… أو bash: terraform: command not found → Terraform غير مثبَّت أو ليس في PATH. المشروع 01، الملحق A.1 أو B.1..\labo.ps1 أو ./labo.sh : الملف غير موجود → لست في جذر العُدّة. انتقل بـ cd إلى مجلد lab-terraform (الذي يحتوي على labo.ps1 وlabo.sh وprojets).Le dossier travail\atelier-1 existe déjà. Tapez : (المجلد موجود أصلًا) → سبق أن شغّلت nouveau atelier-1. نفّذ cd المشار إليه ؛ إذا كان المجلد يحتوي على تجربة قديمة، فاحذفه وأعد تشغيل nouveau.Error: Invalid resource type … does not support resource type "local_fichier" → النوع هو local_file، بالإنجليزية، بشرطة سفلية.Error: Unsupported argument … Did you mean "content"? → خطأ مطبعي في اسم وسيط ؛ يقترح Terraform الصحيح.Error: Unclosed configuration block → القوس الختامي } في السطر الأخير ناقص.Error: Unterminated template string → علامة اقتباس " ناقصة في نهاية قيمة.terraform plan بـ Error: No configuration files → الملف لا يُسمّى main.tf (غالبًا main.tf.txt)، أو لست في travail/atelier-1. تحقق بـ Get-ChildItem أو ls -la.Apply cancelled. → كتبت شيئًا غير yes. أعد التشغيل، واكتب yes كاملة.terraform state list بـ No state file was found! → لم ينجح أي apply في هذا المجلد. استأنف من الخطوة 6.terraform state show بـ No instance found for the given address! → العنوان مكتوب خطأ ؛ يعطيك terraform state list العنوان الصحيح (local_file.bonjour).