前言
開始動筆後才發現好難寫啊~~~
一方面是官方的文件其實就已經寫得相當清楚了,寫太少不如自己去看官方文件就好,想寫多一些可能又會需要很多的情境設計,且目前 Terraform 也還未正式發布(Terraform v0.9.11),難保未來不會差異太多,所以目前會以我自己使用上的心得挑重點記錄下來,後續再來補充需要知道的細節或範例之類的。
Terraform 是什麼?
Terraform 是個管理雲端基礎建設的工具,支持 AWS、Google Cloud、DigitalOcean、Azure 等雲。Terraform 的核心概念為「基礎設施即程式碼」(Infrastructure as Code),使用 HCL 定義供應者(Provider)、資源(Resource)、資料來源(Data Source)、變數(Variable)、輸出(Output)、模組(Module),使用指令執行整個基礎建設的初始化(init)、計畫(plan)、套用(apply)、摧毀(destroy)等生命週期。
安裝
直接下載執行檔
基本使用及名詞解釋
Load Order and Semantics
所有同一個資料夾底下的 .tf 檔案都會載入
所有 .tf 最後都會是「合併」在一起的,要注意不能有重複的命名
所有宣告的 Resource, Variable 等並沒有先後順序,所有的參考都是不需要考慮順序的
Syntax
Configuration
直接看官網文件範例:
# An AMI
variable "ami" {
description = "the AMI to use"
}
/* A multi
line comment. */
resource "aws_instance" "web" {
ami = "${var.ami}"
count = 2
source_dest_check = false
connection {
user = "root"
}
}
單行註解以
#
開頭多行註解以
/*
跟*/ 包起來
賦值:
key = value
,中間有幾個空白並不重要字串使用雙引號
"
多行的字串可以以
<<EOF
開始,並以EOF
結尾,要注意這兩個標記不能縮排數字預設是 10 進位,如果需要十六進位可以使用
0x
開頭布林: true, false
List:
["foo", "bar", "baz"]
Map:
{ "foo": "bar", "bar": "baz" }
Interpolation
Resource
- resource 是 Terraform 裡最關鍵的 syntax,每個 resource 都是 infra 的元件
- resource 裡面會使用到的語法就看文件吧 :)
附帶一提,Resource 的 interpolation 長這樣:${type.name.attribute}
Provider
provider "aws" {
region = "us-west-2"
}
- provider 是 resource 在創建、更新、銷毀時的依據,如果沒有宣告就會用 resource 的 prefix 來去決定
- 可以設
alias
,並在宣告 resource 時可使用不同的alias
來指定 provider - 如果是使用在 AWS 上蠻常見的就是使用
alias
來指定不同的 region,比如你的主要的 region 在 tokyo,但像是 SES 在 tokyo 並沒有,但卻需要使用時可以這樣宣告:
resource "aws_ses_domain_identity" "example" {
provider = "aws.virginia"
domain = "tf.example.com"
}
Data Source
- 通常用來讀取既有資源,並提供給其他資源的參考使用,最常用的可能就是
aws_ami
了:
# Find the latest available AMI that is tagged with Component = web
data "aws_ami" "web" {
filter {
name = "state"
values = ["available"]
}
filter {
name = "tag:Component"
values = ["web"]
}
most_recent = true
}
附帶一提,Data Source 的 interpolation 長這樣:${data.type.name.attribute}
Variable
就是參數了,Variable 的參數有:
- type (optional): 類型,有
string
、list
、map 三種
。 - default (optional): 預設值。
- description (optional): 描述。
附帶一提,Variable 的 interpolation 長這樣:${var.foo}
Output
- 通常用來給其他程式處理時使用。
Module
- Module 建議是不要一開始就使用,因為沒有規劃好的話,會有很多參數需要重複定義,其實挺煩的!
Provisioners
用來在 Resource 創建或銷毀結束後執行,常用的有:
local-exec:執行本地的指令
remote-exec:在遠端執行指令或 script
null_resource:跟其他 provisioner 不同,null_resource 要用獨立的 Resource 宣告,常用來在多個 Resource 有改變時觸發其他 provisioner
Backends
Backend 主要是用來存放 terraform 定義的基礎設施的狀態,以 AWS 的使用來說,建議可以直接放 S3。
Terraform with Packer
packer 主要的功能是產生映像檔(以 AWS 來說就是 AMI),跟 terraform 的互動可以透過 data.aws_ami
,透過 filter 定義出 packer 包出來的 AMI,如此就可以在其他 Resource 中使用,如 aws_launching_configuration
、aws_instance
等。
其他
工具
- terraforming: 把已經建立的 AWS 資源轉成 terraform 的模板
- VS Code Extension: VS Code 的 terraform 語法高亮