用Terraform舒適管理Infrastructure

Posted by Elizabeth Huang on Sun, Nov 26, 2023

前言

你是否有以下困擾?

  • 花了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的資源,所以需要給予相關的權限

Permissions policies

取得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等資源的範例

架構圖

參考