---
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
```