terraform本身就有變數為什麼還要用這產品,但在多環境基礎設施性能皆不同,管理上偏好使用,職則切分。
terraform
- 專心製作 Moduleterragrunt
- 傳入參數
install
$ brew install terragrunt
$ terragrunt -v
terragrunt version 0.50.1
terragrunt 資料夾規範建議
├── terragrunt.hcl # remote_state 設定 terraform state
├── _envcommon # 傳入 terraform module 參數定義,(遠端Module or 自身專案Module)
│ └── provider
│ └── resource.hcl
├── provider # 供應商 ex: google
│ └── region # 地區 ex: asia-east1 台灣
│ ├── common.hcl # 環境共用參數 ex: 相同專案名稱
│ ├── dev # 環境名
│ │ └── resource # 使用 _envcommon 名
│ │ ├── env.hcl # 預加傳入 _envcommon 資料夾下 resource variable
│ │ └── terragrunt.hcl # 預需使用 _envcommon 資料夾下 resource
│ └── prod
│ └── resource
│ ├── env.hcl
│ └── terragrunt.hcl
└── modules # 自製 terraform modlues
└── resource # terraform modlues 建議風格
├── main.tf # terraform 入口
├── output.tf # terraform output variable
├── variables.tf # terraform input variable
└── versions.tf # terraform 版本定義
入門
基礎設施有設置順序性問題,所以需要定義好規範 在撰寫文件時,順序會分成
- modules - 自製 terraform modlues 若無可略
- _envcommon - 操作環境
- provider - 操作環境
modules
略
介紹 terraform 時有簡單介紹撰寫方式
_envcommon
基本上我認為這份檔案扮演很重要的角色
# _envcommon/provider/resource.hcl
# 指定所需的 terraform modules (以 cloud-router 為範例)
terraform {
# 若使用同專案自製module 使用註解這行指定 resource
# source = "${get_repo_root()}//modules/resource"
source = "tfr:///terraform-google-modules/cloud-router/google//?version=5.0.1"
}
# 基礎設施順序性 需先建置下方 path 中的項目才能執行此項目 (cloud-router 需繼承 vpc)
dependencies {
paths = [find_in_parent_folders("vpc")]
}
# 帶入 variables
locals {
environment_vars = read_terragrunt_config("env.hcl") # 環境自訂參數
common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl")) # 環境共用參數
env = local.common_vars.locals.environment
name = local.common_vars.locals.name
project = local.common_vars.locals.project
region = local.common_vars.locals.region
zone = local.common_vars.locals.zone
}
# 產出 provider
generate "provider" {
path = "provider.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
provider "google" {
project = "${local.project}"
region = "${local.region}"
zone = "${local.zone}"
}
EOF
}
# 若需依賴的 output variable 需先模擬 mock (vpc 的 output variable)
dependency "vpc" {
config_path = find_in_parent_folders("vpc")
mock_outputs = {
network_name = "my-vpc"
}
}
# 入口處引用的 source 需 input variable (cloud-router 的 input variable)
inputs = {
project = local.project
name = "${local.name}-cloud-router"
network = dependency.vpc.outputs.network_name
region = local.region
nats = [{
name = "${local.name}-nat-gateway"
}]
}
provider
基本上是設定 input varable 入口
- common.hcl - 環境共用參數
- env.hcl - 預加傳入 _envcommon 資料夾下 resource variable
- terragrunt.hcl - 預需使用 _envcommon 資料夾下 resource
# provider/region/common.hcl
locals {
name = "product_name" # 產品名
domain = "sample.com" # domain
project = "gcp_id" # gcp project id
region = "asia-east1" # gcp region
zone = "asia-east1-a" # gcp zone
environment = "dev" # dev/qa/prod
}
# provider/region/dev/resource/env.hcl
locals {
# ... 其實和 common 類似 看 module 需求
}
# provider/region/dev/resource/terragrunt.hcl
include "root" {
path = find_in_parent_folders()
}
include "envcommon" {
path = "${dirname(find_in_parent_folders())}/_envcommon/provider/resource.hcl"
}
CLI 操作方式
有兩種方式
provider/region/dev/resource
folder 底下操作
- terragrunt init - 安裝依賴
- terragrunt plan - 預覽更改
- terragrunt apply - 確認執行
- terragrunt destroy - 確認執行 會有再次確認
provider/region/dev
folder 底下操作
- terragrunt run-all plan - 整個環境預覽更改
- terragrunt run-all apply - 整個環境確認執行
- terragrunt graph-dependencies | dot -Tsvg > graph.svg - 強力推薦,可以看整個建置拓樸
常見錯誤
command not found: dot
安裝 dot 套件
$ terragrunt graph-dependencies | dot -Tsvg > graph.svg
zsh: command not found: dot
$ brew install graphviz
brew install graphviz