ข้ามไปยังเนื้อหา

อภิธานศัพท์

ศัพท์ของคอร์สนี้ครอบคลุมสามชั้น: Terraform core (resource, provider, state, module, plan/apply/destroy) ที่ทำงานเหมือนกันทุก cloud; Terragrunt (unit, dependency, root config, stack) ที่ทำให้หลาย environment ยังคง DRY; และส่วนที่เฉพาะ Azure (blob-lease locking ของ azurerm backend, Azure Verified Modules, Key Vault) ที่จะเข้าใจได้ก็ต่อเมื่อรู้ว่ากำลังอ่าน provider ไหนอยู่ เวลาอ่านบทเรียนแล้วเจอคำที่ไม่คุ้น หรือไม่แน่ใจว่ายังใช้ได้อยู่กับ Terraform 1.16 / Terragrunt 1.1 ไหม ให้กลับมาดูที่นี่

Termความหมายบทเรียน
applyterraform apply รัน action ทั้งหมดในแผนต่อ infrastructure จริง — เป็นคำสั่งเดียวใน core workflow ที่ create, update หรือ destroy อะไรจริง ๆ; ถ้าไม่มี plan file ที่เซฟไว้ มันจะสร้างให้ก่อนแล้วถาม confirmThe Terraform Workflow
Azure Verified Modules (AVM)module catalog ที่ Microsoft support อย่างเป็นทางการ publish เข้า Terraform Registry ในชื่อ Azure/avm-res-<provider>-<resource>/azurerm (เช่น Azure/avm-res-keyvault-vault/azurerm) — ตัวแทนของ module จาก community อย่าง Azure/vnet ที่ archived ไปแล้ว ทดสอบและดูแลโดย Microsoft เองโดยตรงแทนที่จะเป็น communityModule Versioning and Registries
Azure/vnet (archived)module จาก community registry ที่เคยเป็นวิธี default ในการสร้าง VNet — ตอนนี้ archived แล้วหันไปใช้ Azure Verified Modules แทน บทเรียนหรือโปรเจกต์จริงที่ pin มันไว้วันนี้คือ pin module ที่ไม่ได้รับ fix แล้วModule Versioning and Registries
azurerm vs azapiazurerm คือ provider ที่ mature และ curate ครอบคลุม resource ส่วนใหญ่ของ Azure ด้วย schema ที่ออกแบบมาให้ใช้ง่าย; azapi map เข้ากับ Azure Resource Manager REST API เกือบตรง ๆ แทน ทำให้เข้าถึง resource ใหม่หรือ preview ได้ก่อนที่ azurerm จะรองรับแบบเต็มตัวHCL, Providers, and Resources
backendplugin ที่ตัดสินว่า state ของ Terraform เก็บ ที่ไหน และ operation ที่ทำกับมันถูก lock ยังไง — config ครั้งเดียวใน block terraform { backend "azurerm" {} }; เปลี่ยน argument ใน block ต้องรัน terraform init ใหม่ (ใส่ -migrate-state ถ้าจะย้าย state เดิม)Remote Backends and Locking
Termความหมายบทเรียน
catalog / scaffoldterragrunt catalog เปิดดู module repository ชุดที่ config ไว้ แล้ว scaffold unit ใหม่จากมันแบบ interactive — เขียน terragrunt.hcl กับ inputs เริ่มต้นให้เลย แทนที่จะต้องเขียน unit เองตั้งแต่ต้นทุกครั้งTerragrunt HCL and the Root Config
checkovstatic-analysis scanner (Bridgecrew/Palo Alto) ที่รันกับ Terraform source ก่อน จะ plan เช็ค policy ที่ built-in มาให้ (storage container ที่เปิดให้เข้าถึงแบบ public, managed disk ที่ไม่เข้ารหัส, NSG ที่เปิดกว้างเกินไป, …) — รันผ่าน checkov -d . หรือ GitHub Action ของมัน ซึ่งต้อง pin ไว้ที่ ref ใดหนึ่ง ไม่ใช้ @master เพราะมันเปลี่ยน policy แบบ breaking ได้ทุกครั้งที่ pushPolicy as Code and Static Analysis
configuration_aliasesประกาศไว้ใน required_providers block ของ module ระบุชื่อ provider alias (เช่น azurerm.westeurope, azurerm.eastus) ที่ module คาดว่าผู้เรียกจะส่งเข้ามาผ่าน argument providers = {} — ถ้าไม่มีตัวนี้ provider ที่ alias ไว้จะข้าม module boundary ไปไม่ได้เลยModule Composition and Sources
countวิธีเก่าแบบใช้ index เพื่อแปลง resource/module block เดียวให้กลายเป็นสำเนาที่เกือบเหมือนกัน N ชุด (resource.name[0], [1], …) — เปราะบางเวลาสลับลำดับ เพราะเอา element กลางออกจาก list จะเลื่อน index ของทุกตัวที่ตามมา ทำให้ resource พวกนั้นถูก destroy แล้วสร้างใหม่Count and For Each
create_before_destroymeta-argument lifecycle { create_before_destroy = true } สลับลำดับ replace จาก destroy-ก่อน-แล้ว-ค่อย-create เป็น create-ก่อน — ต้องใช้เมื่อ resource เก่าต้องยังให้บริการ traffic อยู่ หรือยังต้องมีอยู่เพราะอย่างอื่นยัง reference มันจนกว่า resource ใหม่จะพร้อมHCL, Providers, and Resources
Termความหมายบทเรียน
data sourceการ lookup แบบ read-only (data "azurerm_image" "..." {}) ที่ดึงข้อมูลเกี่ยวกับ resource ที่ Terraform ไม่ได้จัดการ — ไม่ว่าจะเป็นของที่มีอยู่แล้ว (VNet ที่แชร์กัน) หรือค่าที่ provider คำนวณให้ (image ID ที่ตรงกับ filter) — และ Terraform จะไม่มีวัน create, update หรือ destroy มันได้เองHCL, Providers, and Resources
-detailed-exitcodeflag บน terraform plan ที่เปลี่ยน exit code จาก 0/1 ธรรมดา เป็น 0 (ไม่มีอะไรเปลี่ยน), 1 (error) หรือ 2 (มีการเปลี่ยนแปลง) — สิ่งที่ CI pipeline เช็คจริง ๆ เพื่อตัดสินว่า plan ต้องมีขั้นตอน approve จากคนหรือข้ามไปได้เลยCI/CD for Infrastructure
dependency / dependenciesblock dependency ของ Terragrunt อ่าน outputs ของอีก unit มาเป็น input (หลังจากรัน plan/apply ของมันเองก่อน); block dependencies (พหูพจน์) แค่การันตีลำดับกับ unit หนึ่งตัวหรือมากกว่าโดยไม่ดึง output ออกมาDependencies Between Units
destroyterraform destroy (หรือ apply -destroy) plan แล้ว execute การลบ resource ทุกตัวที่ track อยู่ใน state ตอนนี้ — pipeline plan/apply เดียวกับการเปลี่ยนแปลงปกติ แค่ทุก action ถูกตั้งเป็น deleteThe Terraform Workflow
driftความต่างระหว่างสิ่งที่อยู่ใน state กับสิ่งที่มีอยู่จริงใน Azure — เกิดจากการเปลี่ยนผ่าน console เอง, เครื่องมืออื่น หรือ process นอกระบบ — มีแค่ terraform plan/refresh เท่านั้นที่เห็นมัน เพราะ Terraform ไม่เคย poll ต่อเนื่องด้วยตัวเองDrift Detection and Import
dynamic blockสร้าง nested block ซ้ำ (เช่น ingress {} หลายอันในหนึ่ง security group) จาก list หรือ map ตอน runtime — เทียบเท่า for_each แต่ใช้กับ nested block บน resource เพราะ nested block ของ resource เองใส่ for_each ตรง ๆ ไม่ได้Count and For Each
Termความหมายบทเรียน
ephemeralresource แบบ ephemeral "..." {} หรือ variable/output ที่เป็น ephemeral = true (Terraform 1.10+) มีอยู่แค่ระหว่าง plan/apply ครั้งเดียว — ไม่ถูกเขียนลง state หรือ plan file เลย — กลไกที่ credential อายุสั้นหรือ password ที่ generate มาไหลผ่านได้โดยไม่ลงดิสก์เลยSensitive Data and Team Workflows
error_hookhook ของ Terragrunt (ข้างใน terraform { error_hook "..." {} }) ที่รันเฉพาะตอนคำสั่ง Terraform ที่ wrap ไว้ fail โดย match กับ error output ด้วย regex ใน on_errors — ใช้ทำ cleanup หรือแจ้งเตือนที่ before_hook/after_hook ธรรมดาทำไม่ได้Terragrunt HCL and the Root Config
features {}block ที่ต้องมีข้างใน config ของ azurerm provider (จะเว้นว่างหรือใส่ sub-block ปรับพฤติกรรม resource เฉพาะตัวก็ได้ เช่น resource_group { prevent_deletion_if_contains_resources }) — terraform init/plan ปฏิเสธที่จะรันเลยถ้าไม่มีมัน แม้จะเว้นว่างไว้ก็ตามHCL, Providers, and Resources
--filterflag ปัจจุบันของ Terragrunt สำหรับจำกัดว่า run --all จะทำกับ unit ไหนบ้าง (ตาม path, ทิศทาง dependency หรือ query ที่เซฟไว้) — ตัวแทนของคู่เก่าที่ตอนนี้ถูกเอาออกแล้วอย่าง --terragrunt-include-dir/--terragrunt-exclude-dirRunning Many Units at Once
find_in_parent_foldersfunction find_in_parent_folders() ใน block include เดินขึ้นจาก directory ของ unit เพื่อหาไฟล์ที่ระบุชื่อไว้ (ปกติคือ root.hcl) — กลไกที่ทำให้ทุก unit include root config เดียวกันได้โดยไม่ต้อง hardcode relative path ที่จะพังเวลา unit ย้ายที่DRY Configuration with include
find / listterragrunt find กับ terragrunt list ค้นหา unit ใต้ tree ปัจจุบัน (จะเอาออกมาเป็น JSON หรือกรองตาม dependency ก็ได้) — คำสั่ง discovery แบบ read-only ที่อยู่เบื้องหลัง --filter และเบื้องหลัง tooling ของ editor/CI ที่ต้อง enumerate unit โดยไม่ต้องรันอะไรเลยRunning Many Units at Once
for_eachแปลง resource/module block เดียวให้กลายเป็นหนึ่ง instance ต่อหนึ่ง entry ของ map หรือ set ของ string โดย key ด้วย key ของ map นั้น (resource.name["prod"]) แทนที่จะเป็น index ตัวเลข — เอา entry ออกกระทบแค่ instance นั้นตัวเดียว ต่างจาก countCount and For Each
force-unlockterraform force-unlock <lock-id> เอา state lock ที่ค้างอยู่ออกด้วย ID โดยไม่ต้องรัน plan/apply — ทางออกฉุกเฉินสำหรับ lock ที่ค้างจาก process ที่ crash หรือ CI job ที่ถูกฆ่า และเป็นคำสั่งเดียวที่ถ้าใช้กับ lock ที่ยังถูกถืออยู่จริง ๆ จะทำ state พังได้Remote Backends and Locking
Termความหมายบทเรียน
generateblock generate "..." {} ของ Terragrunt เขียนไฟล์ (provider block, backend block, version constraint) ลงใน working directory ของ unit ก่อน Terraform จะรัน — กลไกที่ทำให้ทุก unit แชร์ provider/backend boilerplate เดียวกันที่ define ไว้ครั้งเดียวใน root.hclTerragrunt HCL and the Root Config
HCP Terraformแพลตฟอร์ม remote-execution ที่ HashiCorp จัดการให้ (เดิมชื่อ Terraform Cloud): รัน plan/apply บน worker ของตัวเอง, เก็บ state และกั้น apply ไว้หลัง approval กับ Sentinel policy — ทางเลือกแบบ managed แทนการ self-host azurerm backend บวก CI pipeline เองCI/CD for Infrastructure
ignore_changesข้างใน lifecycle {}, ignore_changes = [tags] (หรือ list ของ attribute ที่ระบุ) บอก Terraform ให้เลิก report — และเลิก revert — drift เฉพาะ attribute พวกนั้น ใช้บ่อยตอนที่ process อื่น (autoscaling, Lambda ที่ tag ให้) เป็นเจ้าของมันอยู่แล้วจริง ๆDrift Detection and Import
import blockblock import { to = ..., id = ... } แบบ declarative (Terraform 1.5+) เอา resource ที่มีอยู่แล้วเข้ามาอยู่ใต้การจัดการโดยใส่มันไว้ใน plan/apply ปกติ แทนคำสั่ง terraform import แบบเดิมที่เป็น imperative — review ได้ใน PR ก่อนจะมีอะไรเปลี่ยนจริงDrift Detection and Import
includeblock include "root" { path = find_in_parent_folders() } ของ Terragrunt ดึง config จากไฟล์ .hcl อื่นเข้ามาใน unit ปัจจุบัน รวม generate/remote_state/inputs ของมันเข้าด้วย — กลไก DRY หลัก คู่กับ dependency สำหรับ tree ที่มีหลาย unitDRY Configuration with include
Infracostประเมิน cost ต่อเดือนที่เปลี่ยนไปถ้า plan นี้เกิดขึ้นจริง โดยจับคู่ resource ที่วางแผนจะเปลี่ยนกับข้อมูลราคาของ cloud — รันกับ output ของ terraform show -json มักถูกโพสต์เป็น PR comment คู่กับ policy-as-code gatePolicy as Code and Static Analysis
Termความหมายบทเรียน
Key Vault (azurerm_key_vault)ที่เก็บ secret/key/certificate ที่ Azure จัดการให้; azurerm_key_vault_secret คือ resource ที่บทเรียนใช้เขียนค่าเข้าไป — การเข้าถึงคุมด้วย access policy แบบเก่า หรือถ้าเป็น vault ใหม่คุมด้วย Azure RBAC role assignment บนตัว vault เองSecrets and Credential Management
lifecyclemeta-argument block lifecycle {} ที่มีให้ทุก resource เก็บ create_before_destroy, prevent_destroy, ignore_changes และ replace_triggered_by — จุดเดียวที่ Terraform ให้ override พฤติกรรม replace/destroy default ต่อ resource ได้HCL, Providers, and Resources
localblock locals {} ตั้งชื่อ expression ครั้งเดียวเพื่อเอามาใช้ซ้ำทั่ว module โดยไม่ต้องเขียนซ้ำ — ไม่ใช่ input หรือ output เลย เป็นแค่ค่าที่ computed ภายในเท่านั้นOutputs and Locals
lockrecord ที่ backend เขียนก่อนเริ่ม operation ที่แก้ state กันไม่ให้ plan/apply ที่รันพร้อมกันตัวที่สองมาอ่าน/เขียน state เดียวกันในเวลาเดียวกัน — lock ของ azurerm backend คือ blob lease ที่ขอบน state blob เอง — เปิดใช้ให้โดย default ไม่ต้องสร้าง lock resource แยกเลย ต่างจากประวัติของ S3 backend ที่เคยต้องพึ่ง DynamoDB tableRemote Backends and Locking
Termความหมายบทเรียน
Managed Identity (system vs user-assigned)identity ของ Azure AD ที่แนบกับ resource (VM, Function App) ให้มัน authenticate กับ Azure service อื่นได้โดยไม่ต้องเก็บ credential ใด ๆ เลย — แบบ system-assigned ถูกสร้างและลบไปพร้อม resource; แบบ user-assigned เป็น resource แยกตัวเองที่แชร์กันหลาย resource ได้Secrets and Credential Management
mock_outputsข้างใน block dependency ของ Terragrunt, mock_outputs ใส่ค่าปลอมให้ output ของ dependency นั้นเพื่อให้คำสั่งอย่าง validate/plan รันได้แม้ dependency จะยังไม่เคยถูก apply มาก่อน — ถูกจำกัดไว้ default ให้ใช้กับ plan เท่านั้นผ่าน mock_outputs_allowed_terraform_commands เพื่อไม่ให้ apply จริงรันเข้ากับข้อมูลปลอมแบบเงียบ ๆDependencies Between Units
mock_providerconstruct ของ terraform test (1.7+) ที่แทน provider จริงด้วย mock ที่คืนค่า placeholder ที่ compute ให้ หรือ override ที่ระบุตรง ๆ — กลไกที่ทำให้ test รัน plan/apply ได้โดยไม่ต้องมี credential จริงหรือยิง API จริงเลยTesting Modules
moduleกลุ่มไฟล์ .tf ที่ reuse ได้ ครบในตัวเอง รับ input เป็น variable และ expose output ออกมา — เรียกจากที่อื่นด้วย block module "name" { source = ... } เป็นหน่วยของการ compose และ reuse ที่อยู่เหนือ resource เดียวWriting a Reusable Module
moved blockblock moved { from = ..., to = ... } แบบ declarative (Terraform 1.1+) บันทึกการ rename หรือย้าย resource/module ใน state ให้เป็นการ refactor ไม่ใช่ destroy+create — review ได้ใน plan และปล่อยไว้ใน config ได้เรื่อย ๆ อย่างปลอดภัยสำหรับใครก็ตามที่ apply จาก state เก่ากว่าDrift Detection and Import
null_resource (legacy)วิธีก่อน 1.4 ในการแนบพฤติกรรม provisioner/triggers โดยไม่มี infrastructure จริงรองรับ — ถูกแทนที่ด้วย terraform_data ที่ทำงานแบบเดียวกันในฐานะส่วนหนึ่งของ Terraform core โดยตรง แทนที่จะต้องพึ่ง provider แยกต่างหากTesting Modules
Termความหมายบทเรียน
OIDCOpenID Connect: CI pipeline แลก token identity ที่ platform ออกให้ อายุสั้น กับ credential ของ cloud แบบชั่วคราว ผ่าน trust relationship ที่ config ไว้ครั้งเดียว — กลไกที่เอา cloud access key อายุยืนออกจาก CI secret ไปเลยSecrets and Credential Management
outputexpose ค่าจาก module (หรือ root module ซึ่ง terraform output จะอ่านมัน) ให้กับสิ่งที่เรียกมันมา — block dependency ของ Terragrunt อ่าน output ของ unit แบบนี้เป๊ะ ๆOutputs and Locals
override_resourceconstruct ของ terraform test ที่แทนที่ค่าที่ plan ไว้ของ resource ตัวใดตัวหนึ่ง (แทนที่จะเป็น provider ทั้งตัวแบบ mock_provider) — ใช้ตอนที่มีแค่ resource เดียวใน plan ที่ส่วนใหญ่เป็นของจริงต้องการค่าแทนตัวTesting Modules
Termความหมายบทเรียน
planterraform plan คำนวณและแสดง action ที่ต้องทำเพื่อไปถึง desired state โดยไม่รันอะไรเลย — เป็น read-only ต่อ infrastructure จริง แม้จะอ่าน state ปัจจุบันและ (ถ้าไม่ใส่ -refresh=false) refresh มันด้วยThe Terraform Workflow
plugin cacheTF_PLUGIN_CACHE_DIR (หรือ plugin_cache_dir ใน CLI config) ชี้ให้ทุก terraform init ใช้ directory เดียวที่เก็บ provider binary ที่ดาวน์โหลดมาแล้วร่วมกัน แทนที่จะดาวน์โหลด provider version เดิมซ้ำเข้า .terraform/providers ของทุกโปรเจกต์เอง — ประหยัดเวลาและ bandwidth ได้จริง แต่ไม่เคยปลอดภัยถ้าให้ init สองอันรันพร้อมกันโดยไม่มีการป้องกันInstalling Terraform and Project Structure
precondition / postconditionblock condition {} ของ precondition เช็คสมมติฐาน ก่อน resource/data source/output จะถูก evaluate (เช่น “AMI ตัวนี้ต้องอยู่ใน account”); postcondition เช็คผลลัพธ์ หลัง — ทั้งคู่ทำให้ plan/apply fail พร้อม message ที่กำหนดเองทันทีที่ expression เป็นเท็จ แทนที่จะไปโผล่เป็น error ที่งงตรงปลายทางExpressions, Functions, and Conditionals
prevent_destroymeta-argument lifecycle { prevent_destroy = true } ทำให้ Terraform ปฏิเสธที่จะ plan การ destroy resource นั้นเลย — plan error ออกมาแทนที่จะป้องกันแบบเงียบ ๆ ดังนั้นการ refactor ด้วย moved/removed รอบ ๆ มันก็ยังต้องระวังอยู่HCL, Providers, and Resources
providerplugin ที่แปล HCL resource/data-source block ให้กลายเป็น API call จริงเข้าระบบใดระบบหนึ่ง — aws, azurerm, google และอีกหลายร้อยตัว แต่ละตัว version และติดตั้งแยกจาก Terraform core เองHCL, Providers, and Resources
provider aliasconfig ที่สองหรือสามของ provider เดียวกัน ตั้งชื่อผ่าน alias = "..." ใน block provider {} แล้ว reference บน resource ด้วย provider = azurerm.westeurope — วิธีที่ config เดียวจัดการ resource ข้ามเช่นสองภูมิภาคของ Azure ใน apply เดียวHCL, Providers, and Resources
provider protocolสัญญา RPC ที่ version ไว้ (protocol v6 ตั้งแต่ Terraform 1.4+/provider ปัจจุบัน) ระหว่าง Terraform core กับ provider plugin ใด ๆ — เหตุผลที่ provider binary ที่ build มากับ protocol 6 โหลดเข้า CLI ที่พูดได้แค่ protocol 5 ไม่ได้ ไม่เกี่ยวกับ semantic version ของ provider เองModule Versioning and Registries
Termความหมายบทเรียน
refreshอ่าน state จริงของทุก resource ที่จัดการอยู่จาก provider ใหม่ แล้ว reconcile เข้า state file ของ Terraform — เกิดขึ้นอัตโนมัติเป็นส่วนหนึ่งของ plan/apply เว้นแต่ใส่ -refresh=false หรือสั่งตรง ๆ ผ่าน terraform apply -refresh-onlyDrift Detection and Import
registryTerraform Registry (registry.terraform.io) host provider กับ module ที่ version แล้วและค้นหาได้แบบ public — module source อย่าง Azure/avm-res-network-virtualnetwork/azurerm resolve มาจากที่นี่โดย default ไม่ต้องใส่ Git URL เต็มModule Versioning and Registries
remote_stateblock remote_state { backend = "azurerm" ... } ของ Terragrunt generate backend block ของ Terraform ที่เทียบเท่ากันให้ทุก unit ที่ include มัน เก็บ config storage account/container/key ไว้ที่เดียวจริง ๆ แทนที่จะ copy-paste ไปทุก unitTerragrunt HCL and the Root Config
removed blockblock removed { from = ... } แบบ declarative (Terraform 1.7+) เอา resource ออกจาก state — ใส่ lifecycle { destroy = false/true } ซ้อนไว้ข้างในก็ได้ — โดยไม่ต้องมี config ของ resource นั้นเหลืออยู่เลยก็ได้ เป็นตัวแทนที่ปลอดภัยของ terraform state rm เวลา config ก็ถูกลบไปด้วยDrift Detection and Import
renderterragrunt render print config ของ unit ที่ resolve เสร็จเรียบร้อยแล้ว (หลัง include, generate และ evaluate function) ออกมาเป็น JSON หรือ HCL — วิธีดูว่า unit จะรันอะไรจริง ๆ โดยไม่ต้อง trigger plan/applyRunning Many Units at Once
replace_triggered_byข้างใน lifecycle {}, replace_triggered_by = [azurerm_linux_virtual_machine_scale_set.this] บังคับให้ resource นี้ถูก replace ทุกครั้งที่ resource/attribute ที่ reference ไว้เปลี่ยน — แม้ argument ของ resource นี้เองจะไม่ได้เปลี่ยนอะไรเลยก็ตามHCL, Providers, and Resources
resourcebuilding block หลัก: block resource "azurerm_linux_virtual_machine" "this" {} ประกาศ object จริงหนึ่งตัวที่ถูกจัดการ ซึ่ง lifecycle เต็ม (create/read/update/delete) ของมัน Terraform เป็นเจ้าของทั้งหมดตั้งแต่ต้นจนจบHCL, Providers, and Resources
resource group (azurerm_resource_group)ตู้คอนเทนเนอร์ที่ resource อื่นทุกตัวของ Azure ในคอร์สนี้อยู่ข้างใน คุมทั้งการลบ (ลบ group ก็ลบทุกอย่างข้างในไปด้วย), การเข้าถึง (scope ที่ใช้ตั้ง RBAC บ่อย ๆ) และมักเป็นค่า default ของ location ให้ resource ที่ไม่ได้ตั้งของตัวเองด้วยHCL, Providers, and Resources
root moduleไฟล์ .tf ใน directory ที่เรารัน terraform จริง ๆ — module อื่นทุกตัวเป็น child module ที่ไปถึงผ่านมันเท่านั้น และเป็นที่เดียวที่ block provider {} หรือ backend configuration จะอยู่ได้Writing a Reusable Module
root.hclชื่อตามธรรมเนียม (แทนที่ pattern เก่าที่ใช้ terragrunt.hcl เป็น root) สำหรับไฟล์ Terragrunt บนสุดของ tree ที่ block include ของทุก unit หามันเจอผ่าน find_in_parent_folders() — เก็บ remote_state, generate และ provider config ที่แชร์กันTerragrunt HCL and the Root Config
run --all (formerly run-all/plan-all)รันคำสั่ง Terraform ข้ามทุก unit ใต้ directory ปัจจุบันตามลำดับ dependency — syntax ปัจจุบันคือ terragrunt run --all apply; รูปแบบเก่าที่แยกตาม command (terragrunt plan-all, terragrunt run-all apply) เป็นคำสั่งที่ไม่รู้จักบน Terragrunt 1.1Running Many Units at Once
Termความหมายบทเรียน
sensitiveตั้ง variable/output ด้วย sensitive = true จะซ่อนค่าออกจาก CLI output กับ log ของ plan/apply — แต่มันยังถูกเก็บเป็น plaintext อยู่ใน state file เอง นี่คือเหตุผลที่ sensitive state ต้องมี encryption ระดับ backend ด้วยSensitive Data and Team Workflows
Sentinel / OPApolicy-as-code engine ที่ evaluate output show -json ของ plan กับกฎที่องค์กรเขียนเองก่อนจะให้ apply ผ่านไปได้ — Sentinel เป็น engine built-in ของ HCP Terraform; Open Policy Agent (ผ่าน conftest) เป็นตัวแทนแบบ open-source ที่ไม่ผูกกับ platform ไหนPolicy as Code and Static Analysis
show -jsonterraform show -json <planfile> render plan (หรือ state) ที่เซฟไว้ออกมาเป็น JSON ที่เครื่องอ่านได้ — สิ่งที่ Sentinel/OPA, Infracost และ CI gate ที่เขียนเองส่วนใหญ่ parse จริง ๆ แทนที่จะ scrape output ของ plan แบบที่คนอ่านThe Terraform Workflow
staterecord แบบ JSON (terraform.tfstate หรือของเทียบเท่าบน remote backend) ที่ map resource/module ทุกตัวใน config ไปหา object จริงที่มันจัดการ — source of truth เดียวของ Terraform ว่ามันสร้างอะไรไปแล้วบ้าง ไม่เคย derive ใหม่ด้วยการ scan cloud account เลยThe State File
storage account backend leaseกลไกเบื้องหลัง locking ที่ built-in ของ azurerm backend: Terraform ขอ blob lease บน state blob ใน storage account/container ที่ config ไว้ก่อนจะเขียน แล้วปล่อยคืนเมื่อ operation จบ — ไม่ต้องสร้าง lock resource หรือ table แยกเลย ต่างจากประวัติของ S3 backend ที่เคยพึ่ง DynamoDBRemote Backends and Locking
subscription_idargument ที่ต้องใส่ตรง ๆ บน block azurerm provider ระบุว่า resource ทุกตัวใน config นี้ถูกสร้างใน Azure subscription ไหน — ถ้าไม่ใส่แล้วปล่อยให้ใช้ subscription ที่ Azure CLI ล็อกอินอยู่ตอนนั้น เป็นสาเหตุที่พบบ่อยที่ plan ไปรันผิด subscriptionHCL, Providers, and Resources
Termความหมายบทเรียน
.terraform.lock.hclบันทึก provider version ที่ตรงเป๊ะและ checksum ของมัน (ทุก platform เว้นแต่ตัดออกด้วย -platform) ที่ตอบโจทย์ terraform init — commit เข้า version control ไว้เพื่อไม่ให้ init อีกครั้งบนเครื่องอื่น resolve provider build ที่ต่างกันและยังไม่ verify แบบเงียบ ๆModule Versioning and Registries
terraform graphemit dependency graph ที่ Terraform สร้างจริงสำหรับ config ปัจจุบัน ในรูปแบบ DOT ส่งต่อให้ Graphviz (terraform graph | dot -Tsvg) เพื่อดูภาพว่าทำไม resource ตัวหนึ่งถึง depend กับอีกตัวThe Terraform Workflow
terraform testtest runner ที่ built-in มาให้ (ไฟล์ .tftest.hcl, Terraform 1.6+) ที่ plan และ apply ก็ได้ต่อ config จริงหรือ mock แล้ว assert ผลลัพธ์ — รันด้วย terraform test ไม่ต้องมี testing framework แยกเลยTesting Modules
.tftest.hclนามสกุลไฟล์ที่ terraform test มองหา: block run หนึ่งอันหรือมากกว่า แต่ละอันมี command (plan หรือ apply) และ block assert ที่เช็ค condition กับค่าที่ plan หรือ apply ของ run นั้นTesting Modules
terraform_dataresource ที่เป็น first-class ไม่ผูกกับ provider ไหน (Terraform 1.4+) เก็บค่า input/triggers_replace ที่ต้องการได้เลยโดยไม่มี infrastructure จริงอยู่ข้างหลัง — ตัวแทนของ null_resource ของ community เดิม ใช้บ่อยเพื่อบังคับให้ resource ที่ depend อยู่ถูก replace หรือพา provisioner behavior ไปด้วยTesting Modules
terraform_remote_statedata source ที่อ่าน state ของ config อื่น (พร้อม output ของมัน) ตรง ๆ จาก backend ของมันเลย — เทียบเท่ากับสิ่งที่ block dependency ของ Terragrunt ทำผ่าน mock_outputs กับการเดินสายที่ generate ให้ แต่เป็น Terraform ธรรมดาRemote Backends and Locking
terragrunt stack / terragrunt.stack.hclไฟล์ terragrunt.stack.hcl ประกาศชุด block unit/stack ที่ terragrunt stack generate ขยายออกมาเป็น directory tree ของ unit จริง (ใต้ .terragrunt-stack/) ก่อนที่ stack run จะ apply มัน — วิธี template “หนึ่ง stack ของ unit” ในระดับที่สูงกว่าการ copy-paste directory ต่อ environmentRunning Many Units at Once
tflintlinter สำหรับ Terraform source ที่จับความผิดพลาดเฉพาะ provider (VM SKU ที่เลิกใช้แล้ว, string ของ Azure region ที่ผิด) ที่ plan/apply จับไม่ได้ และ terraform validate — ซึ่งเช็คแค่ syntax ของ HCL กับความสอดคล้องภายใน — ก็จับไม่ได้เหมือนกันPolicy as Code and Static Analysis
Termความหมายบทเรียน
unitชื่อของ Terragrunt สำหรับ directory หนึ่งที่มี terragrunt.hcl หนึ่งไฟล์ บวก Terraform module ที่มันชี้ไปผ่าน terraform { source = ... } — สิ่งที่ run --all, dependency และ --filter ทำงานด้วย เทียบเท่ากับ root module ใน Terraform ธรรมดาTerragrunt HCL and the Root Config
use_oidc / use_cli (provider auth)flag แบบ boolean บน config ของ azurerm provider (และ backend) เลือกว่ามัน authenticate ยังไง — use_oidc สำหรับ token แบบ federated จาก CI, use_cli สำหรับ identity ที่ az login ตั้งไว้ในเครื่องอยู่แล้ว — แทนที่จะเป็น client secret แบบ static ที่นอนอยู่ใน variable หรือ CI secret storeRemote Backends and Locking
validationblock validation { condition = ..., error_message = ... } ของ variable ปฏิเสธค่าที่ไม่ถูกต้องตอน plan พร้อม message ที่กำหนดเอง; ตั้งแต่ Terraform 1.9 condition นี้ reference variable ตัวอื่นได้ด้วย กฎที่ต้องเช็คข้าม variable เลยไม่ต้องหาทางเลี่ยงผ่าน precondition อีกต่อไปInput Variables
variableinput ที่ตั้งชื่อและมี type ให้ module หรือ root config ให้ค่าผ่าน .tfvars, -var, environment variable (TF_VAR_name) หรือ default — ทางเดียวที่ข้อมูลไหล เข้า module จากภายนอกInput Variables
version constraint (~>)operator แบบ pessimistic-constraint: ~> 6.66 ยอมรับ 6.66.x (patch upgrade เท่านั้น) ส่วน ~> 6.0 ยอมรับ 6.x ทั้งหมด (minor upgrade ด้วย) — วิธีมาตรฐาน pin provider ให้หลวมพอจะได้ bugfix แต่ไม่ได้ major version ที่ breakingModule Versioning and Registries
Workload Identity Federation (OIDC for CI)การ implement federated identity ของ Azure: federated credential บน App Registration เชื่อถือ OIDC issuer/subject ของ CI platform ตัวใดตัวหนึ่งโดยเฉพาะ ทำให้ pipeline แลก token อายุสั้นของตัวเองกับ Azure AD access token ได้ — กลไกเฉพาะของ Azure ที่อยู่เบื้องหลังศัพท์ทั่วไป OIDCSecrets and Credential Management
workspaceกลไก built-in ของ Terraform (terraform workspace new/select) สำหรับรัน config เดียวกับ state file ที่ตั้งชื่อไว้หลายตัวบน backend เดียวกัน — คอร์สนี้สอน pattern directory-per-environment ของ Terragrunt แทน เพราะ workspace แชร์ backend config กับโค้ดเดียวกันทุก environment แบบเงียบ ๆ ซึ่งมักเป็น tradeoff ที่ผิดสำหรับ prod เทียบกับ non-prodTerraform Workspaces
write-onlyvariable/attribute ที่ marked write_only = true (Terraform 1.11+) รับค่าตอน input ได้แต่ไม่เคยถูกเก็บลง state หรือ plan file เลย คู่กับ argument _version ที่ต้องขยับเพื่อบอกว่า “ค่า write-only นี้เปลี่ยนแล้ว ส่งใหม่”Sensitive Data and Team Workflows