Skip to main content

第 5 章:管理多種環境的組態檔

先前的練習我們都使用一個資料夾,執行 Terraform 所產生的狀態檔就只會有一份。當你的需要按照使用情境分成多個的環境時,只有一份狀態檔就不夠用了。

為了解決多個環境的問題,我們要使用資料夾來區分工作環境,存放各自的狀態檔,並且把共用的組態匯整成模組。

我們將參考前一回的無伺服器架構 API 的範例,進行本次的練習。工作環境會分成開發 (dev) 跟正式 (prod) 兩個情況。

建立工作資料夾

我們先建立以下四個資料夾

  • code 放入程式碼
  • modules 放入自製 Terraform 模組
  • dev 放開發環境的 Terraform 組態
  • prod 放正式環境的 Terraform 組態

目前的資料夾如下:

$ tree
.
├── code
├── dev
├── modules
│   ├── api-gateway
│   └── lambda-go
└── prod

建立 Terraform 模組

把前一回的無伺服器架構 API 放入 api-gateway 跟 lambda-go 兩個模組裡,在模組裡建立需要的變數 (variables) 跟輸出 (outputs)。

這邊因為有了前一次的練習,我們可以很快速的建立我們需要的模組。但是在其他的情況,你可能要先完成開發版的組態,再一步步的改寫到模組中。

開發 dev 環境版本的 Terraform 組態

在 dev 資料夾下,建立 main.tf 跟 outputs.tf

dev/main.tf
...

module "lambda_go" {
source = "../modules/lambda-go"

lambda_role_name = "lambda_dev"
function_name = "hello_dev"
filename = data.archive_file.zip.output_path
source_code_hash = data.archive_file.zip.output_base64sha256

handler = "main"

tags = {
Terraform = "true"
Environment = "dev"
}
}

module "api" {
source = "../modules/api-gateway"

api_name = "hello_dev"
path_part = "hello_dev"
http_method = "GET"
lambda_invoke_arn = module.lambda_go.invoke_arn

tags = {
Terraform = "true"
Environment = "dev"
}
}

dev/output.tf
output "url" {
value = module.api.url
}
cd dev
terraform init

terraform apply
...
Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Outputs:

url = https://84loxa3q7h.execute-api.ap-northeast-1.amazonaws.com/v1/hello_dev

測試 API

curl https://84loxa3q7h.execute-api.ap-northeast-1.amazonaws.com/v1/hello_dev
{"message":"Hello World!","at":"2020-09-27T12:23:45Z"}%

以上看到開發版的 API 測試是成功的。

目前我們可以看到狀態檔案 .tfstate 位置就在 dev 資料夾中。

tree folder
tree
.
├── lambda_source.zip
├── main.tf
├── outputs.tf
└── terraform.tfstate

正式 prod 環境版本的 Terraform 組態

複製 dev 資料夾的 main.tf 跟 outputs.tf 到 prod 資料夾。

接著針對名稱做一點修改。有變動的內容如下:

module
module "lambda_go" {
lambda_role_name = "lambda_prod"
function_name = "hello_prod"

tags = {
Environment = "prod"
}
}

module "api" {
api_name = "hello"
path_part = "hello"

tags = {
Environment = "prod"
}
}

cd prod
terraform init

$ terraform apply
...

Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Outputs:

url = https://uibw65g914.execute-api.ap-northeast-1.amazonaws.com/v1/hello

curl https://uibw65g914.execute-api.ap-northeast-1.amazonaws.com/v1/hello
{"message":"Hello World!","at":"2020-09-27T13:21:45Z"}%

這邊同樣的,狀態檔案會留在 prod 資料夾中,現在我們可能同時管理兩個不同工作環境下的資源了。

移除測試資料

到 dev 與 prod 資料夾內,執行指令

terraform destroy