文章目標:解釋 Terraform 的狀態管理機制,以及如何管理和維護狀態檔案。
Terraform State狀態是用於追蹤和管理正在管理的基礎設施的狀態信息。它是用於確保 Terraform 能夠正確地計劃和應用變更,並保持基礎設施的一致性。
說得這樣複雜,其實Terraform State就是用來記錄施工圖表與目前實際興建大樓狀況的差異,確認大樓工程按照施工圖表進行,這個狀態的紀錄就是所謂的Terraform State。
概念:State(狀態)記錄當前基礎架構的狀態,並在後續運行中與預期狀態進行比較,以確保基礎架構保持一致。
實作用途:Terraform使用狀態來確定要加入、修改或刪除哪些基礎架構元件,除了得知新的差異也要確保基礎架構的當前狀態與配置文件中描述的狀態一致。狀態還允許多個開發者或團隊共享基礎架構,而能夠共同開發。
支持種類:Terraform支持多種State後端,如本地state json、AWS S3、Azure Blob Storage、Consul等等。
注意事項:當多個開發者或團隊共享同一個基礎架構時,需要特別注意State的管理和同步,避免狀態的衝突導致錯誤部署。要小心地管理State,因為狀態中包含有關基礎架構的機密信息,例如密碼、私有金鑰。
使用GCP的cloud shell環境,來執行terraform (沒有使用過請參閱Terraform 工作流程)
使用Variables變數-Output輸出概念與Demo程式碼 (Day 11 — Terraform基礎 — 變數 (Variables) 與輸出 (Outputs)) 或是Github 連結
觀察terraform.tfstate檔案
創建專案以後,右上角先啟動cloud shell,並選擇使用vscode編輯器開啟新頁面。
進入vscode 編輯器後,新建或開啟main.tf的檔案,並複製下列程式碼到視窗中,我們要利用這些程式碼練習,可以先輸入練習後,再來回來看代表的意義。
可以到下方的github連結中,下載對應的參考程式碼
首先創建四個檔案,分別是 0-provider.tf, 1-variables.tf, 2-main.tf, 3-output.tf
0-provider.tf,
##################################################################################
# CONFIGURATION
##################################################################################
terraform {
# 指定 terraform 的最小版本
required_version = ">=1.0"
required_providers {
# provider 中的最小版本
google = {
source = "hashicorp/google"
version = ">= 4.40.0"
}
}
}
##################################################################################
# PROVIDERS
##################################################################################
provider "google" {
# your project name
project = "terraform101-384507"
}
這個檔案主要用於配置 Terraform 的提供者(provider),以確保 Terraform 可以正確地與 Google Cloud Platform(GCP)進行交互。
terraform
:這個區塊設定了 Terraform 的版本要求,確保使用的版本符合最低要求大於4.40.0版本。同時,它也定義了所需的提供者和版本。
provider "google"
:這個區塊指定了要使用的 GCP 提供,指定了 GCP 專案 ID(由 var.GCP_PROJECT 變數提供)。
1-variables.tf
variable "GCP_PROJECT" {
description = "GCP Project ID"
type = string
default = "terraform101-384507"
}
variable "gcs_name" {
type = string
default = "quick-start-gcs-bucket-variable"
}
variable "location" {
type = string
default = "asia-east1"
}
這個檔案用於定義 Terraform 使用的變數,以實現更高度的可配置性和重用性。
variable "GCP_PROJECT"
:這是 GCP 專案 ID 的變數,它描述了 GCP 專案的 ID。它的預設值是 "terraform101-384507",但可以在使用時指定不同的值。
variable "location"
:這是定義網路服務所在位置(地區)的變數。
variable "gcs_name"
:這是用於定義 Google Cloud Storage 名稱的變數。
2-main.tf
resource "google_storage_bucket" "quick_start_gcs" {
name = var.gcs_name
location = var.location
force_destroy = true
}
這個檔案的用途是定義和配置一個 Google Cloud Storage 存儲資源(Google Storage Bucket):
name
:quick_start_gcs 是這個資源的名稱,用於在 Terraform 配置中識別和引用這個存儲資源實例。。
location
:通過變數 var.location,你可以指定存儲資源的位置,這表示存儲資源存放的地理位置。
force_destroy
:表示當你刪除 Terraform 資源時,即使存儲資源中有數據,也將強制刪除存儲資源。。
3-output.tf
output "bucket_name" {
value = google_storage_bucket.quick-start-gcs.name
}
output "bucket_location" {
value = google_storage_bucket.quick-start-gcs.location
}
這兩個 Terraform 輸出使你能夠取得已經建立的 Google Cloud Storage 存儲資源的名稱和位置,以便在需要時可以在其他 Terraform 模塊、外部工具或文件中使用這些信息
bucket_name
:通過 value
欄位設置,它將等於 Terraform 資源 google_storage_bucket.quick-start-gcs
的名稱 (name)。這允許你在部署後輕鬆地檢索存儲資源的名稱,以便在其他 Terraform 代碼或外部應用程序中使用。
bucket_location
:通過 value
欄位設置,它將等於 Terraform 資源 google_storage_bucket.quick-start-gcs
的位置 (location)。
這允許你在部署後輕鬆地檢索存儲資源的位置,以便了解存儲資源在 Google Cloud 中的地理位置信息。
4-data-source.tf
data "google_storage_bucket" "my_bucket" {
name = "quick-start-gcs-bucket-variable"
depends_on = [
google_storage_bucket.quick_start_gcs
]
}
output "my_bucket_location" {
value = data.google_storage_bucket.my_bucket.location
}
output "my_bucket_link" {
value = data.google_storage_bucket.my_bucket.self_link
}
output "my_bucket_url" {
value = data.google_storage_bucket.my_bucket.url
}
Data Source: google_storage_bucket
:這個數據來源(Data Source)用於查詢名稱為 quick-start-gcs-bucket-variable
的 Google Cloud Storage 存儲。它檢索存儲資源的相關資訊,例如存儲的位置、自身連結和URL。 depends_on 則是用來等待 quick-start-gcs-bucket-variable必須要先產生出這個雲端資源,才可以做引用
Output: my_bucket_location
:這個輸出(Output)將存儲資源的位置(location)設定為 my_bucket_location
,使您可以在Terraform執行後獲取存儲資源的位置資訊。
Output: my_bucket_link
:這個輸出將存儲資源的自身連結(self_link)設定為 my_bucket_link
,以便在Terraform執行後獲取存儲資源的自身連結資訊。
Output: my_bucket_url
:這個輸出將存儲資源的URL(url)設定為 my_bucket_url
,以便在Terraform執行後獲取存儲資源的URL資訊。
這段Terraform代碼用於查詢指定名稱的 Google Cloud Storage 存儲資源,並檢索其位置、自身連結和URL等資訊,以供後續使用或顯示。可以明顯地看到數據來源是怎樣去做引用的,我們也可以利用這個方式去增加網路的引用、虛擬機器名稱的引用,或是虛擬機器目前ip的引用。
如果在尚未實際部署的情況下生成了資源計劃,首先需要執行資源初始化命令 terraform init,然後使用 terraform plan -out plan.out 來確認計劃。但由於尚未實際部署,因此不會生成狀態檔案。
terraform init
terraform plan -out plan.out
# terraform state 觀察:生成資源計劃的情況下,尚無狀態檔案
若要執行實際部署,使用 terraform apply -auto-approve,部署完成後將生成狀態檔案 terraform.tfstate。您可以解除註解 data-source.tf 以進行部署,然後再次確認狀態檔案 terraform.tfstate。
terraform apply -auto-approve
# terraform state 觀察:部署完成後生成的狀態檔案 terraform.tfstate
# terraform state 觀察:解除註解 data-source.tf 後,狀態檔案 terraform.tfstate 發生變化
如果刪除 terraform.tfstate 中的某個屬性,然後執行計劃確認 terraform plan -out plan.out,您將注意到計劃中包含了剛剛刪除的屬性。這將導致狀態檔案認為雲端基礎設施並未成功部署。再次執行實際部署 terraform apply -auto-approve 將會失敗,因為 Terraform 認為存在部署衝突,需要進行相應的修改。
因此,我們使用狀態檔案來明確管理,基礎設施程式碼(IAC)與實際在雲端上生成的架構。
terraform plan -out plan.out
terraform apply -auto-approve
# terraform.tfstate 狀態圖
# terraform.tfstate 狀態圖 - 刪除 terraform.tfstate 中的某個屬性
# terraform.tfstate 狀態圖 - 重新部署失敗
Terraform tip:可以利用下列的 Terraform tip,來增進部署效率。
打開終端機中的 .bashrc or .zshrc 檔案
在文件最下方加入下列指令
執行 source ~/.zshrc 或是 source ~/.bashrc 讓下面的 alias 快捷鍵生效
alias tf="terraform"
alias tfv="terraform validate"
alias tfdp="terraform apply -auto-approve plan.out"
alias tfd="terraform apply -auto-approve"
alias tfr="terraform destroy -auto-approve"
alias tfp="terraform plan -out plan.out"
Terraform State狀態:是用於追蹤和管理基礎設施狀態信息的工具。
它確保 Terraform 能夠正確地計劃和應用變更,以維持基礎設施的一致性。狀態檔案記錄了基礎架構的實際狀態,類似於施工圖與實際施工之間的對比。
實際操作:我們使用了 Google Cloud Platform(GCP)的 Cloud Shell 環境來創建 Google Cloud Storage 存儲資源,並使用三個階段來觀察狀態檔案的變化**:
Terraform-from-zero-to-hero-10-Lab-GCP-Infrastucture-as-Code — https://github.com/qwedsazxc78/Terraform-from-zero-to-hero-10-Lab-GCP-Infrastucture-as-Code
Terraform-project-best-practice — https://github.com/qwedsazxc78/terraform-project-best-practice
歡迎訂閱我的udemy課程:Terraform 從零開始 - 10+實戰Lab打造GCP雲端自動化架構課程 - https://devops-with-alex.com/go/terraform