基本語法 & 佈署指令介紹
使用 Terraform 佈署雲端其實可以很簡單,下面是在 AWS 佈署一台 EC2 的範例程式碼:
可以發現程式碼本身比起說成程式碼,更像是設定檔。而這個設定檔便是最基本的 EC2 佈署程式。
關於裡面用到的關鍵字,其解釋如下
variable
就是定義變數,但這個變數只能用於啟動時輸入參數使用,無法在程式內改變,而使用 default
可以在當輸入沒有指定數值時為變數設定預設值。另外,要指定變數可以透過環境變數或者在同資料夾下放置 terraform.tfvars
來完成,格式如下:
關於使用環境變數指定變數的方法可以看這裡:
provider
就是提供功能的提供商設定,因為我們使用 AWS 的服務所以是 "aws"
,因此這裡的 "aws"
是不能改的(除非你不想用 aws)。另外,這裡的 provider 以及 resource 實際上是一套另外維護的專案,比如這邊用 aws 以及他的 resource,那這部份的功能就是 aws 這個 terraform provider 專案(類似 plugin)提供。因此如果各提供商沒有好好維護, provider 之間可能會有所衝突,甚至文件也會有不全的狀況。
不過大部份比較大的雲端都會把自己的 provider 像這樣開源(白◯)
所以只要是夠大的平台一般不用擔心會有事。
resource
用來實際定義要佈署的資源(比如一台 EC2 一台 RDS 一台 Lambda…等等),另外剛剛說過 provider 是廠商各自維護,因此 resource 則可以當作是 provider 提供的功能。每個雲端每個資源都會有不同的用法以及設定方法,所以關於有什麼選項以及設定方法麻煩看官方教學網站。
output
其實就是印出變數或者中間產生的物件的值,比如 build 好之後輸出 EC2 的 public dns 名。挺好用的,只有 value
需要指定。
另外,實際用 Terraform 佈署之後應該還會看到 data
、local
與 module
,這裡也一併介紹。
data
用需要動態產生資料時可用,比如要打包程式碼算 hash 的時候,或者要動態跟 aws 取得可用 ami (AWS 上的作業系統映像 ID)的時候。
module
別人打包的一組可用的 resource,基本上就是為了簡化重複的程式碼。這部份不由 provider 提供,需要另外指定 source
參數來使用。架構越寫越大之後如果能正確使用對可讀性有幫助。
關於 module 詳細可以看這裡:
.tf
檔(可以不只一個)跟 terraform.tfvars
都寫好之後,就可以照以下方法佈署了:
$ terraform init
$ terraform plan -out dev.tfplan
$ terraform apply dev.tfplan
terraform.tfstate
另外特別注意, terraform 在佈署完成或失敗之後都會在資料夾下產生一個叫 terraform.tfstate
的檔案,這檔案非常重要,它被用來描述目前雲端的狀態。由於 terraform 不會隨時監視雲端,所以佈署後,不只這狀態檔不能丟,被佈署的雲端服務也基本不能以 terraform 之外的方式更動雲端。
到這裡我們算是簡單看過 Terraform 的使用方法與結構了,接著開始針對 Terraform 上使用 AWS provider 做解釋。如果對 Terraform 其他 provider 還有興趣深入了解,可以看看官網(相比 AWS 真的寫得很好)。
另外這邊特別提一下,取得 var/locals/data/resource 的變數內容的方法其實在寫法上有些不同,詳細如下
# var
定義: var "foo" {}
取值: var.foo# locals
定義: locals { foo="bar" }
取值: local.foo# data
定義: data "aws_availability_zones" "available"
取值: data.aws_availability_zones.available.names# resource
定義: resource "aws_vpc" "vpc"
取值: aws_vpc.vpc另外,以上都可以根據回傳型態繼續深入取值,比如
陣列: data.aws_availability_zones.available.names[0]
物件: aws_vpc.vpc.id
AWS VPC 網路結構
一開始在部署 EC2 時遇到最大問題會是難以理解的 VPC 結構。為此本藻繪製一張(可能有點醜):建立一台可 ssh EC2 時需要的 VPC 架構圖。
特別注意:雖然 AWS 一開始會付預設可用 VPC,但為了之後能「真正地」部署出一套可用服務,我們必須理解 VPC 裡的架構。
VPC 的結構簡單來說就如上圖,說極端點這區分就像一個家用網路環境,以下介紹各個元件:
VPC
AWS 所定義的服務組單位,一個 VPC 可以通俗理解為一個資料中心。基本上所有網路資源都需要一個 VPC 才能運行,並且 VPC 之間被視為不同內網,一般也不能互相溝通。
Subnet
其實就是網段,但這裡需要另外注意的是,Subnet 定義時需要指定實體位置一個 availability zone,因為相比 VPC 只是個抽象的組合,Subnet 會決定服務實際放置的區域。關於 availibility zone 可以看以下:
補充一下:在 AWS 上也基本上是透過指定多個 Subnet(Availability zone 要不一樣) 給一個資源來做冗余化。
Security Group
這也是幾乎所有 AWS 資源都需要的東東,把它當防火牆就好,而且是 Windows 防火牆,差別只是在 AWS 上可以寫好一份重複指定給多個資源。然後 ingress 指傳入,egress 指傳出, port 指定為 0 就是允許所有 port。
補充:圖中只寫出 port 規則,但實際上還可以針對來源(ingress)・目的地(egress)/傳輸層協定(tcp/udp)來做特定的放行。
Internet Gateway
跟家裡連 wifi 時網路設定裡的 Gateway 87% 像,反正就是內部網路出口。
Route Table
與 Subnet 關聯,用來處理 Subnet 的「傳出」需求所對應的 Gateway,設定方法是一個網段指定一個 Internet Gateway,但無法針對 Subnet 內的 IP/網段做 routing(本藻這麼覺得,歡迎指教)。另外,要讓一個 Route Table 被Subnet 使用時,得先寫好一份 Route Table 的 resource 然後透過 aws_route_table_association
(Terraform 的話) 關聯至 Subnet
到此本藻算是介紹完基本的 VPC 概念了,雖然還有非常多的坑,但若能理解相信之後就算遇到,也能擁有解決問題與查資料解決吧。
實戰 — 基本 EC2 佈署
那麼我們就趕緊來實戰吧,先上程式碼:
真的是江湖一點訣,說破不值錢阿。正如所見,Terraform 程式碼也就只是把剛剛提到的架構圖該定義的定義好罷了。
關於各個 resource 裡面為啥要這樣填之類的,本藻覺得在這裡講會顯的過於冗長,而且也講不細,就請移步直接來看官方教學吧:
https://registry.terraform.io/providers/hashicorp/aws/latest/docs
他的教學真的寫得很好,善用這裡的搜尋可以幫到你。
阿對,至於佈署嘛…只要寫好 terraform.tfvars
後執行跟剛剛一樣的:
$ terraform init
$ terraform plan -out dev.tfplan
$ terraform apply dev.tfplan
這次 tfvars 需要多一個 key_name 表示要使用的 EC2 key pair,記得加上去。
結語
包含 Terraform 基本語法、AWS VPC 架構以及實戰的 Terraform 佈署 EC2。本篇都算是完整講完一輪了,雖然東西可能有點多,但希望沒有說的太快。
不過就算後續應用上真的遇到問題,因為 Terraform 佈署的部份是程式碼,所以其實很好查。這邊偏重於介紹基本架構方面的觀念,希望對各位之後的學習有幫助。
那麼這篇就說到這裡吧,下篇我們將會把漫畫閱讀器跟漫畫爬蟲都佈署到 EC2 上(用 Terraform),最後還是那句老話,若有興趣就敬請關注吧,再會。
下篇預告
單純開發者
不單純的EC2
暴打開發者的 AWS