--- tags: 'Infrastructure as Code' --- # Terraform conventions ## Naming Rules ### General conventions - 使用4個空格 - 使用小寫字母或是數字 - 使用底線(_)分隔單詞 ### Resource and data source arguments - 請使用單數名詞作為名稱 - O: ``` resource "azurerm_resource_group" "example" {} ``` - X: ``` resource "azurerm_resource_group" "examples" {} ``` - 不在資源名稱中重複資源類型 - O: ``` resource "azurerm_resource_group" "example" {} ``` - X: ``` resource "azurerm_resource_group" "example_resource_group" {} ``` - 當使用多個argument, 請對齊其等號 - O: ``` resource "azurerm_virtual_network" "vnet" { name = var.vnet_name resource_group_name = data.azurerm_resource_group.network.name location = data.azurerm_resource_group.network.location address_space = [var.address_space] dns_servers = var.dns_servers tags = var.tags } ``` - X: ``` resource "azurerm_virtual_network" "vnet" { name = var.vnet_name resource_group_name = data.azurerm_resource_group.network.name location = data.azurerm_resource_group.network.location address_space = [var.address_space] dns_servers = var.dns_servers tags = var.tags } ``` - 當argument和block出現在同一層級時, 請將所有argument放在頂部, 並用空行分隔argument與block - O: ``` resource "azurerm_virtual_network" "vnet" { name = var.vnet_name resource_group_name = data.azurerm_resource_group.network.name location = data.azurerm_resource_group.network.location address_space = [var.address_space] dns_servers = var.dns_servers tags = var.tags lifecycle { create_before_destroy = true } } ``` - 請將count放置在第一行, 並空格一行 - O: ``` resource "azurerm_storage_account" "vm-sa" { count = var.boot_diagnostics ? 1 : 0 name = "bootdiag${lower(random_id.vm-sa.hex)}" resource_group_name = data.azurerm_resource_group.vm.name location = coalesce(var.location, data.azurerm_resource_group.vm.location) account_tier = element(split("_", var.boot_diagnostics_sa_type), 0) account_replication_type = element(split("_", var.boot_diagnostics_sa_type), 1) tags = var.tags } ``` - X: ``` resource "azurerm_storage_account" "vm-sa" { name = "bootdiag${lower(random_id.vm-sa.hex)}" resource_group_name = data.azurerm_resource_group.vm.name location = coalesce(var.location, data.azurerm_resource_group.vm.location) account_tier = element(split("_", var.boot_diagnostics_sa_type), 0) account_replication_type = element(split("_", var.boot_diagnostics_sa_type), 1) count = var.boot_diagnostics ? 1 : 0 tags = var.tags } ``` ### Module #### When to write a module - 如果有多個資源會一起被使用到 - 不建議編寫僅作為單個資源類型 #### Structure ``` minimal-module ├── README.md ├── main.tf ├── outputs.tf └── variables.tf ``` #### Variables - 變數中的參數順序為: description > type > default ``` variable "cidr_block" { description = "The CIDR block for AWS VPC" type = string default = "10.0.0.0/16" } ``` - 使用與資源相同的變數名 - 即使你認為很簡單, 請描述每個變數 #### Outputs - 輸出名稱結構: <name>_<type>_<attribute> - 盡可能提供output變數 - 即使你認為很簡單, 請描述每個輸出 - 如果輸出是一個list, 請使用複數名稱 ## Structure - 共用資源,如provider, backend, resource_group等等放入main.tf - 共用資源變數放入bootstrap.tfvars(不可放入密碼等等資訊, 請善用環境變數) - 根據[資源類型](https://www.terraform.io/docs/providers/azurerm/index.html)新增或放入對應的<resource_type>.tf中 example_project ``` ├── bootstrap.tfvars ├── compute.local.tf ├── compute.tf ├── main.tf ├── main.variables.tf ├── modules │ └── virtual_network │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── network.local.tf ├── network.tf ├── README.md └── tags.tf ```