前言
你是否有以下困擾?
- 花了10分鐘從圖形介面建資源
- 再花10分鐘刪資源
- 刪除資源後想重建但不記得架構了
- 橫跨多雲的複雜架構
你需要Terraform!
Terraform是一個IaC(Infrastructure as Code)工具,可以用簡單易讀的設定檔,建立許多Provider,如AWS、GCP等,提供的資源
還可以快速建立或快速銷毀,Provider會自動計算依賴關係,按照順序建立或刪除
更好的是可以進版控,方便追蹤修改的歷史
這麼偷懶便利的東西,簡直是工程師的心頭好啊
Terraform的檔案種類
main.tf
main.tf是主要的entrypoint,用來指定data, resource等等
data
- 格式:
data <type> <name>
- 引用:
data.<type>.<name>.<attribute>
resource
- 格式:
resource <type> <name>
- 引用:
<resource type>.<name>.<attribute>
範例: main.tf
1terraform {
2 required_providers {
3 aws = {
4 source = "hashicorp/aws"
5 version = "~> 5.2"
6 }
7 }
8
9 required_version = ">= 1.4"
10}
11
12provider "aws" {
13 region = "ap-south-1"
14
15 default_tags {
16 tags = {
17 Creator = "FallPrediction"
18 Environment = "Prod"
19 Service = "Musical wiki"
20 }
21 }
22}
23
24data "aws_availability_zones" "available" {
25 state = "available"
26}
27
28resource "aws_instance" "app_server" {
29 ami = "ami-830c94e3"
30 instance_type = "t3a.nano"
31 availability_zone = data.aws_availability_zones.available.names[0]
32}
33
34resource "aws_eip" "app_server_ip" {
35 instance = aws_instance.app_server.id
36 domain = "vpc"
37}
provider version最大5.2,指定aws provider的region為孟買,然後加上一個default_tags讓下面的資源全部打上相同的tag
取得aws_availability_zones的資料,並命名為available,並且參數是state = available。引用data aws_availability_zones的available的屬性names然後取得第0個
建立一個叫app_server的aws_instance resource,參數指定了ami和instance_type,和剛才說的availability_zone
resource要引用aws_instance app_server的屬性id
variables.tf
使用變數的話,就可以根據需要輸入想要的數值了,當然也可以給一個預設值!
可以在variables.tf列出此專案需要的變數,在實際建立資源之前,Terraform會要求輸入變數的值
範例
variable.tf 設定一個變數
1variable "app_media_bucket" {
2 default = "app_media_bucket"
3 type = string
4}
可以在其他.tf中引用var.<variable name>
1resource "aws_s3_bucket" "app_media_bucket" {
2 bucket = var.app_media_bucket
3}
.tfvars
剛才講variables,如果我有敏感資料,例如資料庫帳密怎麼辦呢?
可以使用.tfvars檔案,這邊範例叫做secret.tfvars
1app_media_bucket = "media-bucket"
這種檔案不能進版控,就跟常見的.env file一樣!
然後在apply的時候指定variable file
1terraform apply -var-file="secret.tfvars"
outputs.tf
這是讓Terraform印出配置的最後,也印出指定的output
指定output的方式為value = <resource_type>.<name>.<attribute>
1output "app_server_public_ip" {
2 description = "Public IP address of App server"
3 value = aws_eip.app_server_ip.public_ip
4}
最小模組結構
簡單介紹terraform模組的結構
唯一個必要條件是Terraform檔案,也就是.tf檔,必須在根目錄中,其他都是建議選項,不是強制的
最小的推薦模組如下,就是上面所述的幾種檔案,再加上README等。當然更簡單也可以只有main.tf
1$ tree minimal-module/
2.
3├── LICENSE
4├── README.md
5├── main.tf
6├── variables.tf
7├── outputs.tf
如果是複雜的結構,可以使用資料夾分類,每個module都有自己的variables等
1$ tree complete-module/
2.
3├── LICENSE
4├── README.md
5├── main.tf
6├── modules
7│ └── aws-s3-static-website-bucket/
8 ├── README.md
9 ├── main.tf
10 ├── variables.tf
11 └── outputs.tf
12├── outputs.tf
13├── terraform.tfstate
14├── terraform.tfstate.backup
15└── variables.tf
terraform.tfstate
上面的模組結構中,可以看到有一個terraform.tfstate檔案。它是用於儲存設置的resource和實際建立的物件之間的綁定。所以它有敏感資料,不可以進版控
要小心保管如果遺失,要復原會很麻煩(下方參考連結中有一條示範復原的方法)
最好的方法是設定backend儲存在本地或雲端,預設是本地
下方是設定為S3的範例,指定在哪個region, bucket, key。而且建議這個bucket要開啟版本控制
main.tf
1terraform {
2 # ...
3 backend "s3" {
4 bucket = "terraform-backup-ap-south-1"
5 key = "terraform.tfstate"
6 region = "ap-south-1"
7 }
8}
使用Terraform吧
安裝
根據官網的指示安裝以後,檢查安裝的版本
1terraform –version
建議安裝自動完成套件~
1terraform -install-autocomplete
建立IAM User和 Access Key
這裡使用Access Key讓Terraform可以存取AWS的資源,所以需要給予相關的權限
取得Access Key以後,配置AWS CLI
1$ aws configure
2AWS Access Key ID [None]: 產生的key id
3AWS Secret Access Key [None]: 產生的 access key
4Default region name [None]: 預設 region
5Default output format [None]: json
初始化
進入專案目錄後,需要初始化,會安裝Provider、backend等
1terraform init
想要格式檔案,可以用
1terraform fmt
驗證配置
1terraform validate
建立/更改infrastructure
1terraform apply
會印出執行計畫,列出建立什麼資源、刪除什麼資源
1$ terraform apply
2Plan: 27 to add, 0 to change, 0 to destroy.
3
4Changes to Outputs:
5 + app_server_public_ip = (known after apply)
6
7Do you want to perform these actions?
8 Terraform will perform the actions described above.
9 Only 'yes' will be accepted to approve.
10
11 Enter a value:
沒問題的話,輸入 yes 執行計畫,就可以開始建立資源囉~
檢查狀態
1terraform show
小心謹慎!
請仔細閱讀 terraform apply 印出的計畫,因為可能不小心刪除或建立資源!
曾經聽過有人在下班前沒看清楚直接apply,結果很多人跟著加班的慘案
要注意的是,某些資源的更改是刪除後重建,東西不是同一個了
刪除infrastructure
1terraform destroy
當資源不再使用時,可以簡單的快速銷毀
範例
可以看我的Repo,有建立AWS EC2等資源的範例