IaC = Infrastructure as Code
Terraform, 用人類讀得懂的語言來敘述雲端資源
到今天前, 我們都是在gcp上手動點擊,操作UI來完成設定, 而terraform則像是source of truth, 他是系統,服務, 權限的設定檔, 可以透過套用terraform來快速啟動, 複寫當前狀況, 並且可以對terraform的檔案做到版控追蹤各種設定的改動原因
實務上也會盡可能避免,不鼓勵人去操作terraform控制的設定, 以免造成管理狀況分歧, 不清楚是code還是console才是正確的設定
在大型專案中 terraform可能會是一個獨立的repo, 而在我們的POC小專案 則可以把前後端和terraform分開資料夾 但放在一個repo
/chat-bot-proj
-/client (前端)
-/bff (後端)
-/terraform (terraform相關設定)
-iam.tf
-network.tf
-...
取得當前iam的terraform 修改並複寫回去
在本地的terminal 抓取gcp當前的terraform
首先需要建立一個資料夾來給下載檔案用 mkdir -p ./gcp_export 不然會在terminal把文字都印出來
接著進行下載
gcloud beta resource-config bulk-export \
--project=<project-id> \
--resource-format=terraform \
--path=./gcp_export
下載後大概可以得到這樣的結果

可以看出第一層有兩個專案相關的資料夾
全數字那個是gcp幫你建立的project id, 存放內建的設定
另一個則是自訂的專案名稱 裡面就是自訂義出來的設定如custom role, 和自己建立的service account
手動把service accoun 和custom role整理為一隻 iam.tf

#custom role for cloud run operator
resource "google_project_iam_custom_role" "cloudrun_customrole" {
description = "具有cloud run的觀看和重啟權限"
permissions = ["run.revisions.list", "run.services.get", "run.services.list", "run.services.update"]
project = "chat-bot-484615"
role_id = "Cloudrun.CustomRole"
title = "BFF cloud run operator"
}
# service account for chatbot bff
resource "google_service_account" "chatbot_bff_sa" {
account_id = "chatbot-bff-sa"
description = "用於 BFF 呼叫 Dialogflow 與讀寫 Cloud Storage"
display_name = "chatbot-bff-sa"
project = "chat-bot-484615"
}
然後要讓我們地端的repo和遠端gcp的資源做連結 知道彼此當前的狀況
cd 到 /terraform 用以下command (須先安裝terraform cli)
## 初始化
terraform init
## 匯入取得遠端狀態
terraform import google_project_iam_custom_role.<custom-role-名稱> projects/<proj-id>/roles/Cloudrun.CustomRole
terraform import google_service_account.chatbot_bff_sa projects/<proj-id>/serviceAccounts/<service-account-名稱>@<proj-id>.iam.gserviceaccount.com
##以我專案會是
terraform import google_project_iam_custom_role.cloudrun_customrole projects/chat-bot-484615/roles/Cloudrun.CustomRole
terraform import google_service_account.chatbot_bff_sa projects/chat-bot-484615/serviceAccounts/chatbot-bff-sa@chat-bot-484615.iam.gserviceaccount.com
匯入後會看到出現 .tfstate檔 裡面是遠端的狀態

接著執行 terraform plan 同步兩邊看有無差異
我得到
terraform main $ terraform plan
google_service_account.chatbot_bff_sa: Refreshing state... [id=projects/chat-bot-484615/serviceAccounts/chatbot-bff-sa@chat-bot-484615.iam.gserviceaccount.com]
google_project_iam_custom_role.cloudrun_customrole: Refreshing state... [id=projects/chat-bot-484615/roles/Cloudrun.CustomRole]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
~ update in-place
Terraform will perform the following actions:
# google_project_iam_custom_role.cloudrun_customrole will be updated in-place
~ resource "google_project_iam_custom_role" "cloudrun_customrole" {
id = "projects/chat-bot-484615/roles/Cloudrun.CustomRole"
name = "projects/chat-bot-484615/roles/Cloudrun.CustomRole"
+ stage = "GA"
# (6 unchanged attributes hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
看來是我手動設定時 沒有加上stage資訊
回去iam.tf 把custom role的參數中加上 stage = ‘GA’
再輸入一次 terraform apply 系統會確認是否要改寫 輸入yes
接著再輸入一次 terraform plan 就會顯示 no changes 代表我們已經同步遠端了
到這裡我們就完成 透過repo 的terraform設定改寫gcp的iam設定
未來我們應該還會有更多同步gcp的操作
此外我們在repo中同步了gcp上的iam設定(service account, custom role), 不過為何我們不在repo中進行使用者管理, 有一份清單決定誰是什麼角色呢, 因為以組織治理來說, 人員是會流動的, 而這些on-board, off-board會伴隨帳號及權限的變更與刪除, 還是在google的platform上維護會比較全面, 在repo上可能做得的會是對’group’與權限的管理
如
# 將你剛做好的 Custom Role 綁定給開發團隊群組
resource "google_project_iam_member" "dev_team_operator" {
project = "chat-bot-484615"
role = google_project_iam_custom_role.cloudrun_customrole.id
member = "group:gcp-dev-team@yourcompany.com" # 這裡用群組,而不是個人 Email
}
我的個人專案上沒這個需求, 公司的專案上不是我來管理就先不碰
不過可以知道管理上會這樣做 可以要求建立或是要求加入定義好的群組