arrow_back

管理 Terraform 狀態

加入 登录
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

管理 Terraform 狀態

Lab 1 小时 universal_currency_alt 5 积分 show_chart 中级
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

本研究室是我們與合作夥伴 Hashicorp 攜手開發而成。如果您在帳戶資料中選擇接收產品最新動態、公告和優惠資訊,我們可能會將您的個人資訊提供給 Hashicorp,也就是這個研究室的贊助方。

GSP752

Google Cloud 自修研究室標誌

總覽

Terraform 必須儲存代管基礎架構和設定的相關狀態,並透過狀態來確認實際資源和設定的對應關係、追蹤中繼資料,以及改善大型基礎架構的效能。

根據預設,狀態會儲存在本機檔案 terraform.tfstate 中,但也可以儲存在遠端的空間,以符合團隊環境的運作方式。

Terraform 使用本機狀態來建立方案和變更基礎架構。開始任何作業前,Terraform 會重新整理更新狀態,以便貼合實際基礎架構。

遠端系統中的物件與設定中宣告的資源執行個體彼此繫結,而 Terraform 狀態主要用於儲存這類繫結關係。當 Terraform 建立遠端物件以因應設定變更時,會依據特定資源執行個體,記錄該遠端物件的身分;若日後設定有所變更,也可以更新或刪除該物件。

目標

在本研究室中,您將瞭解如何執行下列工作:

  • 建立本機後端。
  • 建立 Cloud Storage 後端。
  • 重新整理 Terraform 狀態。
  • 匯入 Terraform 設定。
  • 運用 Terraform 管理匯入的設定。

設定和需求

點選「Start Lab」按鈕前的須知事項

請詳閱以下操作說明。研究室活動會計時,而且中途無法暫停。點選「Start Lab」 後就會開始計時,讓您瞭解有多少時間可以使用 Google Cloud 資源。

您將在真正的雲端環境中完成實作研究室活動,而不是在模擬或示範環境。為達此目的,我們會提供新的暫時憑證,讓您用來在研究室活動期間登入及存取 Google Cloud。

如要完成這個研究室活動,請先確認:

  • 您可以使用標準的網際網路瀏覽器 (Chrome 瀏覽器為佳)。
注意:請使用無痕模式或私密瀏覽視窗執行此研究室。這可以防止個人帳戶和學生帳戶之間的衝突,避免個人帳戶產生額外費用。
  • 是時候完成研究室活動了!別忘了,活動一開始將無法暫停。
注意:如果您擁有個人 Google Cloud 帳戶或專案,請勿用於本研究室,以免產生額外費用。

如何開始研究室及登入 Google Cloud 控制台

  1. 按一下「Start Lab」(開始研究室) 按鈕。如果研究室會產生費用,畫面中會出現選擇付款方式的彈出式視窗。左側的「Lab Details」(研究室詳細資料) 面板會顯示下列項目:

    • 「Open Google Console」(開啟 Google 控制台) 按鈕
    • 剩餘時間
    • 必須在這個研究室中使用的暫時憑證
    • 完成這個研究室所需的其他資訊 (如有)
  2. 按一下「Open Google Console」(開啟 Google 控制台)。接著,研究室會啟動相關資源並開啟另一個分頁,當中會顯示「Sign in」(登入) 頁面。

    提示:您可以在不同的視窗中並排開啟分頁。

    注意事項:如果頁面中顯示了「Choose an account」(選擇帳戶) 對話方塊,請按一下「Use Another Account」(使用其他帳戶)
  3. 如有必要,請複製「Lab Details」(研究室詳細資料) 面板中的使用者名稱,然後貼到「Sign in」(登入) 對話方塊。按一下「Next」(下一步)

  4. 複製「Lab Details」(研究室詳細資料) 面板中的密碼,然後貼到「Welcome」(歡迎使用) 對話方塊。按一下「Next」(下一步)

    重要注意事項:請務必使用左側面板中的憑證,而非 Google Cloud 技能重點加強的憑證。 注意事項:如果使用自己的 Google Cloud 帳戶來進行這個研究室,可能會產生額外費用。
  5. 按過後續的所有頁面:

    • 接受條款及細則。
    • 由於這是臨時帳戶,請勿新增救援選項或雙重驗證機制。
    • 請勿申請免費試用。

Cloud 控制台稍後會在這個分頁中開啟。

注意事項:按一下畫面左上方的導覽選單,即可在選單中查看 Google Cloud 產品與服務的清單。「導覽選單」圖示

啟動 Cloud Shell

Cloud Shell 是搭載多項開發工具的虛擬機器,提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作。Cloud Shell 提供指令列存取權,方便您使用 Google Cloud 資源。

  1. 點按 Google Cloud 控制台上方的「啟用 Cloud Shell」圖示 「啟動 Cloud Shell」圖示

連線完成即代表已通過驗證,且專案已設為您的 PROJECT_ID。輸出內容中有一行宣告本工作階段 PROJECT_ID 的文字:

您在本工作階段中的 Cloud Platform 專案會設為「YOUR_PROJECT_ID」

gcloud 是 Google Cloud 的指令列工具,已預先安裝於 Cloud Shell,並支援 Tab 鍵自動完成功能。

  1. (選用) 您可以執行下列指令來列出使用中的帳戶:
gcloud auth list
  1. 點按「授權」

  2. 輸出畫面應如下所示:

輸出內容:

ACTIVE: * ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (選用) 您可以使用下列指令來列出專案 ID:
gcloud config list project

輸出內容:

[core] project = <project_ID>

輸出內容範例:

[core] project = qwiklabs-gcp-44776a13dea667a6 附註:如需有關 gcloud 的完整說明,請前往 Google Cloud 並參閱「gcloud CLI overview guide」(gcloud CLI 總覽指南)。

Terraform 狀態的用途

狀態是 Terraform 運作的必備要素。開發人員有時會詢問 Terraform 能否在沒有狀態的情況下運作,或能否不使用狀態,只在每次執行時檢查雲端資源。若要讓 Terraform 在不依靠狀態的情況下運作,會需要將大量的複雜元件從一個位置 (狀態) 遷移到另一個位置 (即替換的概念)。本節內容將說明須使用 Terraform 狀態的原因。

對應實際情況

Terraform 需要某種資料庫,來對應 Terraform 設定和實際資源之間的關係。如設定內含 resource resource "google_compute_instance" "foo",Terraform 可透過此對應關係,來瞭解該資源代表的是執行個體 i-abcd1234

Terraform 預期每個遠端物件只與一個資源執行個體繫結,一般情況下也皆是如此,畢竟是由 Terraform 負責建立物件並在狀態中記錄物件的身分。如要將非 Terraform 建立的物件匯入 Terraform,務必確認每個不同的物件僅匯入至一個資源執行個體。

如果一個遠端物件與二或多個資源執行個體繫結,Terraform 可能會對這類物件執行非預期的處置,因為設定和遠端物件狀態的對應關係已變得不明確。

中繼資料

除了追蹤資源和遠端物件之間的對應關係,Terraform 也必須追蹤中繼資料,例如資源依附元件。

Terraform 一般利用設定來判斷依附元件的順序。但您從 Terraform 設定移除資源時,Terraform 必須瞭解如何刪除該資源。Terraform 可以找出擁有對應關係但不屬於設定檔的資源,並規劃將其刪除。但資源不存在後,便無法單憑設定判斷順序。

為確保能正確執行作業,Terraform 會在狀態中保留最新的依附元件組合副本。這樣一來,您從設定刪除一或多個物件時,Terraform 仍能透過狀態判斷正確的刪除順序。

如果 Terraform 知道不同資源類型之間的必然順序,也可以避免這項問題。舉例來說,Terraform 可以知道必須先刪除伺服器,才能刪除其所屬的子網路。這種做法會使複雜度迅速提高,變得難以管理,而且 Terraform 除了必須瞭解每個雲端中每項資源的順序語意,還必須瞭解各供應商的排序。

另外,Terraform 也會基於類似的原因儲存其他中繼資料,例如在同時採用多個具有別名的供應商時,儲存最近期與資源搭配使用的供應商設定指標。

效能

除了基本的對應關係,Terraform 也會在狀態中儲存所有資源的屬性值快取資料。這是 Terraform 狀態的選用功能,只會用於改善效能。

執行 terraform plan 時,Terraform 必須瞭解資源目前的狀態,才能有效判斷需要變更的項目,以達成預期設定。

就小型基礎架構而言,Terraform 可以向供應商提出查詢,並同步處理所有資源的最新屬性。根據預設,對於所有 planapply 指令,Terraform 會同步處理狀態中的所有資源。

對大型基礎架構來說,逐一查詢各項資源速度太慢。許多雲端服務供應商並未提供同時查詢多種資源的 API,而每項資源的封包往返時間都是數百毫秒。此外,雲端服務供應商通常設有 API 頻率限制,因此 Terraform 在一段時間內只能執行有限次數的資源查詢。為因應這項問題,規模較大的 Terraform 用戶通常會同時使用 -refresh=false 旗標和 -target 旗標。在這種情況下,快取狀態視同真正記錄。

同步處理

根據預設設定,Terraform 會將狀態檔案儲存在當前執行 Terraform 的工作目錄。這個做法在初期或許可行,但當團隊共用 Terraform 時,所有成員都必須使用相同的狀態,才能確保在相同的遠端物件上執行作業。

建議採用遠端狀態來解決這項問題。Terraform 擁有功能完善的狀態後端,透過遠端鎖定功能,即可避免多名使用者不小心同時執行 Terraform,藉此確保每項 Terraform 作業都以最新狀態開始執行。

狀態鎖定

如果您的後端支援這項功能,Terraform 會針對所有可能寫入狀態的作業鎖定狀態。這可以防止他人取得鎖定,並降低狀態損壞的可能性。

系統會為所有可能寫入狀態的作業自動套用狀態鎖定。您不會看到任何說明狀態鎖定的訊息。如果未能鎖定狀態,Terraform 會停止執行作業。您可以使用 -lock 旗標為大部分指令停用狀態鎖定功能,但不建議這麼做。

如果花費比預期更長的時間後仍未完成鎖定,Terraform 會輸出狀態訊息。若 Terraform 未輸出狀態訊息,即表示狀態鎖定作業仍在持續進行。

並非所有後端都支援鎖定功能。如要進一步瞭解後端是否支援鎖定功能,請參閱後端類型清單。

工作區

每個 Terraform 設定都與一個後端相關聯,並由該後端定義作業執行方式,以及儲存 Terraform 狀態等永久性資料的位置。

儲存於後端的永久性資料會屬於某個「工作區」。一開始,後端只會有一個名為「default」的工作區,因此只有一個 Terraform 狀態與該設定相關聯。

某些後端支援「多個」命名工作區,即許可單一設定與多個狀態相關聯。這樣一來,部署該設定的多個不同執行個體時,就不必設定新後端或變更認證憑證,而該設定依然只有一個後端。

工作 1:設定後端

Terraform 中的「後端」會指定狀態載入方式,以及如何執行 apply 等作業。有了這項抽象化機制,就能在本機以外的位置儲存狀態檔案、從遠端執行作業等。

根據預設,Terraform 會使用「本機」後端,這也是您習慣的 Terraform 正常運作方式。在先前的研究室中,都是叫用這種後端。

以下是後端的幾項優點:

  • 適合團隊合作:後端可從遠端儲存狀態,並利用鎖定功能防止狀態損毀。有些後端 (例如 Terraform Cloud) 甚至能自動儲存所有狀態修訂版本記錄。
  • 不必將機密資訊存入磁碟:系統會視需要從後端擷取狀態,並僅將狀態儲存於記憶體。
  • 執行遠端作業:對較大型的基礎架構或特定變更而言,terraform apply 作業需要相當長的處理時間。有些後端支援遠端作業,讓開發人員可從遠端執行作業。即使關閉電腦,系統仍會繼續執行直到完成作業。除了先前所述的遠端狀態儲存和鎖定功能,這項優勢也有助於打造適合團隊工作的環境。

後端皆為視需求選用:即使不學習或使用後端,也能順利使用 Terraform。不過,當團隊達到特定規模,後端確實能解決一些難題。若是獨立工作,可能完全不必使用後端即可順利執行作業。

即使您只打算使用「本機」後端,瞭解相關知識仍大有助益,因為您就可以變更本機後端的行為。

新增本機後端

在本節中,您將設定本機後端。

第一次設定後端時 (從未定義後端到明確設定後端),Terraform 會提供將狀態遷移至新後端的選項。這樣一來,您採用後端時,就不會失去任何現有狀態。

為了謹慎起見,我們一律建議您另外手動備份狀態,只要將 terraform.tfstate 檔案複製到另一個位置即可。系統執行初始化程序時也會建立備份,但小心一點準沒錯!

第一次設定後端和日後變更設定的做法是一樣的,都是建立新的設定並執行 terraform init。Terraform 會引導您完成後續步驟。

  1. 請開啟新的 Cloud Shell 視窗,建立 main.tf 設定檔:
touch main.tf
  1. 如要擷取專案 ID,請執行下列指令:
gcloud config list --format 'value(core.project)'
  1. 在 Cloud Shell 工具列中,按一下「開啟編輯器」。如要在 Cloud Shell 與程式碼編輯器之間切換,請視需求點選「開啟編輯器」或「開啟終端機」。或者,您也可以點選「在新視窗中開啟」,在另一個分頁中保持開啟編輯器。
  1. 將 Cloud Storage 值區資源程式碼複製到 main.tf 設定檔,並以專案 ID 取代 projectname 變數定義:
provider "google" { project = "# 替換成專案 ID" region = "{{{project_0.default_region | REGION}}}" } resource "google_storage_bucket" "test-bucket-for-state" { name = "# 替換成專案 ID" location = "US" uniform_bucket_level_access = true }

如要進一步瞭解 Cloud Storage 資源,請參閱 Terraform 說明文件

  1. main.tf 檔案中新增本機後端:
terraform { backend "local" { path = "terraform/state/terraform.tfstate" } }

這會參照 terraform/state 目錄中的 terraform.tfstate 檔案。如要指定不同的檔案路徑,請變更 path 變數。

本機後端會在本機檔案系統中儲存狀態、運用系統 API 鎖定狀態,並在本機執行作業。

Terraform 必須先將已設定的後端初始化,才能使用後端。如要進行初始化,需執行 terraform init。您的團隊成員務必先在所有 Terraform 設定上執行 terraform init 指令。為了安全起見,建議您重複多次執行 Terraform 環境所需的一切設定動作,包括後端初始化。

在下列情況中,務必呼叫 init 指令:

  • 為新環境設定後端時
  • 變更後端設定時 (包括變更後端類型)
  • 徹底刪除後端設定時

您不必逐一記住這些情況,因為 Terraform 會偵測需要進行初始化的時機,並顯示錯誤訊息。Terraform 不會自動進行初始化,因為可能會需要使用者提供額外資訊,或執行狀態遷移作業等。

  1. 請在 Cloud Shell 工具列中,按一下「開啟終端機」並執行 Terraform 初始化:
terraform init
  1. 請套用變更,並在出現提示時輸入 yes 確認套用:
terraform apply

Cloud Shell 編輯器現在應會顯示 terraform/state 目錄中的 terraform.tfstate 狀態檔案。

  1. 請檢查狀態檔案:
terraform show

系統應會顯示 google_storage_bucket.test-bucket-for-state 資源。

新增 Cloud Storage 後端

Cloud Storage 後端會將狀態視為物件,儲存在 Cloud Storage 指定值區的可設定前置字串。這種後端也支援狀態鎖定功能。狀態鎖定功能會針對所有可寫入狀態的作業鎖定狀態,這可以防止他人取得鎖定,並降低狀態損壞的可能性。

系統會為所有可能寫入狀態的作業自動套用狀態鎖定。您不會看到任何說明狀態鎖定的訊息。如果未能鎖定狀態,Terraform 會停止執行作業。您可以使用 -lock 旗標為大部分指令停用狀態鎖定功能,但不建議這麼做。

  1. 請返回編輯器中的 main.tf 檔案。現在您要將現有的本機後端替換成 gcs 後端。

  2. 如要變更現有的本機後端設定,請將下列設定複製到檔案中,以取代 local 後端:

terraform { backend "gcs" { bucket = "# 替換成您的值區名稱" prefix = "terraform/state" } } 注意:務必更新 bucket 變數的定義。如未變更,該變數定義就會是 google_storage_bucket 資源的 name。系統會使用該值區託管狀態檔案。
  1. 請再次進行後端初始化,這次是為了自動遷移狀態:
terraform init -migrate-state

在系統提示中輸入 yes 即可確認。

  1. 在 Cloud 控制台的「導覽選單」上,依序點選「Cloud Storage」>「值區」

  2. 按一下值區,然後前往 terraform/state/default.tfstate 檔案。現在狀態檔案已存放在 Cloud Storage 值區中!

注意:不想再使用後端時,只需從這個檔案刪除相關設定即可。Terraform 會像偵測其他變更一樣偵測到這項刪除作業,並提示您再次執行初始化。

再次進行初始化時,Terraform 會詢問您是否要遷移狀態,改回一般的本機狀態。完成初始化作業後,Terraform 將恢復預設行為。

重新整理狀態

terraform refresh 指令是用來核對 Terraform (透過狀態檔案) 所瞭解的狀態與實際基礎架構的對應情況。這可用來偵測上一個已知狀態與現況的偏移情形,並據此更新狀態檔案。

這項程序並不會修改基礎架構,而會修正狀態檔案。如果狀態有所變更,執行下一項 plan 或 apply 作業的過程中可能會發生變更。

  1. 請返回 Cloud 控制台中的 Cloud Storage 值區,並選取該名稱旁的核取方塊。

  2. 按一下「標籤」分頁標籤。

  3. 按一下「新增標籤」。將「鍵 1」和「值 1」分別設為 keyvalue

  4. 按一下「儲存」

  5. 返回 Cloud Shell,並使用下列指令更新狀態檔案:

terraform refresh
  1. 查看更新結果:
terraform show

設定的標籤屬性應會顯示為 "key" = "value" 鍵/值組合。

點選「Check my progress」來確認目標已達成。設定後端

清除工作區

請先刪除佈建的基礎架構,再繼續下一個工作。

  1. 首先,請將後端還原為 local,以便刪除 Cloud Storage 值區。請使用下列指令複製及取代 gcs 設定:
terraform { backend "local" { path = "terraform/state/terraform.tfstate" } }
  1. 再次進行 local 後端初始化:
terraform init -migrate-state

在系統提示中輸入 yes 即可確認。

  1. main.tf 檔案中,將 force_destroy = true 引數新增至 google_storage_bucket 資源。刪除值區後,這個布林值選項會刪除當中包含的所有物件。如果您嘗試刪除含有物件的值區,Terraform 會無法刪除該值區。資源設定應該會類似以下示例:
resource "google_storage_bucket" "test-bucket-for-state" { name = "qwiklabs-gcp-03-c26136e27648" location = "US" uniform_bucket_level_access = true force_destroy = true }
  1. 套用變更:
terraform apply

在系統提示中輸入 yes 即可確認。

  1. 現在您可以順利刪除基礎架構:
terraform destroy

在系統提示中輸入 yes 即可確認。

工作 2:匯入 Terraform 設定

在本節中,您會將現有的 Docker 容器和映像檔匯入空的 Terraform 工作區。這樣一來,您將瞭解把實際基礎架構匯入 Terraform 的策略和考量重點。

預設的 Terraform 工作流程包括完全運用 Terraform 建立和管理基礎架構。

  • 請寫下 Terraform 設定,以定義想建立的基礎架構。

  • 請檢查 Terraform 方案,確認這份設定可得出與預期相符的狀態和基礎架構。

  • 請套用設定以建立 Terraform 狀態和基礎架構。

Terraform 工作流程圖

運用 Terraform 建立基礎架構後,您可以更新設定和方案,並套用這類變更。最後不再需要該基礎架構時,就可以使用 Terraform 將其刪除。這份工作流程假設您使用 Terraform 建立全新的基礎架構。

不過,您可能需要管理非由 Terraform 建立的基礎架構。為解決這項問題,您需要使用 Terraform 匯入指令,將所支援的資源載入 Terraform 工作區的狀態。

但是,匯入指令並不會自動產生設定來管理基礎架構,因此需要採取多個步驟,才能將現有基礎架構匯入 Terraform。

如要運用 Terraform 管理現有基礎架構,共需採取五大步驟:

  • 找出要匯入的現有基礎架構。
  • 將該基礎架構匯入 Terraform 狀態。
  • 撰寫符合該基礎架構的 Terraform 設定。
  • 檢查 Terraform 方案,確保設定內容符合所預期的狀態和基礎架構。
  • 套用設定以更新 Terraform 狀態。

Terraform 匯入功能工作流程圖

在這個部分,首先要使用 Docker CLI 建立 Docker 容器。接著,要將容器匯入新的 Terraform 工作區,並使用 Terraform 更新容器設定。最後完成所有操作時,就要刪除容器。

警告:匯入基礎架構會影響 Terraform 狀態,且可能導致系統將現有 Terraform 專案列入無效狀態。因此,務必先備份並妥善儲存 terraform.tfstate 檔案和 .terraform 目錄,再對實際的 Terraform 專案使用匯入功能。

建立 Docker 容器

  1. 請運用 Docker Hub 最新的 NGINX 映像檔建立容器並命名為 hashicorp-learn,然後透過通訊埠 80 (HTTP) 預覽 Cloud Shell 虛擬機器上的容器:
docker run --name hashicorp-learn --detach --publish 8080:80 nginx:latest
  1. 請確認容器是否正在執行:
docker ps
  1. 在 Cloud Shell 窗格,依序點選「網頁預覽」和「透過以下通訊埠預覽:8080」

 網頁預覽選項

Cloud Shell 會在新的瀏覽器視窗中,開啟相關 Proxy 服務的預覽網址,並顯示 NGINX 預設索引頁面。現在您已有 Docker 映像檔和容器,可以匯入工作區並透過 Terraform 管理。

將容器匯入 Terraform

  1. 複製範例存放區:
git clone https://github.com/hashicorp/learn-terraform-import.git
  1. 變更為該目錄:
cd learn-terraform-import

這份目錄內含兩個 Terraform 設定檔,也就是您將在本指南中使用的設定:

  • main.tf 檔案會設定 Docker 供應商。
  • docker.tf 檔案內含必要設定,可用來管理您在前述步驟建立的 Docker 容器。
  1. 將 Terraform 工作區初始化:
terraform init 注意:如果系統出現「Error: Failed to query available provider packages」,請執行下列指令:terraform init -upgrade
  1. 在 Cloud Shell 編輯器中,前往 learn-terraform-import/main.tf

  2. 找出 provider: docker 資源,然後註解排除或刪除 host 引數:

provider "docker" { # host = "npipe:////.//pipe//docker_engine" } 注意:我們已知 Docker 初始化錯誤會引發問題,這是目前的因應措施。
  1. 接下來,請前往 learn-terraform-import/docker.tf

  2. 到已註解排除的程式碼下方,在 docker.tf 檔案中定義空的 docker_container 資源,這會以 Terraform 資源 ID docker_container.web 代表 Docker 容器:

resource "docker_container" "web" {}
  1. 找到所要匯入容器的名稱。在這個案例中,就是您在上一個步驟中建立的容器:
docker ps
  1. 執行下列 terraform import 指令,將現有的 Docker 容器連接至剛剛建立的 docker_container.web 資源。Terraform 匯入指令需要這個 Terraform 資源 ID 和完整的 Docker 容器 ID。執行 docker inspect -f {{.ID}} hashicorp-learn 指令即可傳回完整的 SHA256 容器 ID:
terraform import docker_container.web $(docker inspect -f {{.ID}} hashicorp-learn) 注意:terraform import 所接受的 ID 須視資源類型而定,如要瞭解可匯入 Terraform 的資源,請參閱供應商說明文件。就本範例而言,請參閱 Docker 供應商說明文件
  1. 確認容器已匯入 Terraform 狀態:
terraform show

Terraform 對剛剛所匯入 Docker 容器的瞭解均包含在狀態中,但 Terraform 匯入功能並不會為資源建立設定。

建立設定

您需要先建立 Terraform 設定,才能使用 Terraform 管理容器。

  1. 請執行下列程式碼:
terraform plan 注意:若缺少必要的 imagename 引數,Terraform 會顯示錯誤訊息。如果資源缺少必要引數,Terraform 無法產生相關方案。

如要更新 docker.tf 中的設定以貼合匯入的狀態,可以採取兩種方式。您可以照原樣將資源目前狀態完整納入設定中,或是個別選擇設定所需的屬性。這兩種方式各有適合使用的情境。

  • 採用目前狀態通常速度較快,但可能導致設定過於詳細,畢竟這種方式會將每項屬性納入狀態,無論設定上是否需要。

  • 個別選擇所需屬性可讓設定較易於管理,但您必須瞭解設定中需要設置哪些屬性。

在本研究室中,您將採用資源目前狀態。

  1. 將 Terraform 狀態複製到 docker.tf 檔案:
terraform show -no-color > docker.tf 注意:使用 > 符號,即表示 docker.tf 中的所有內容均會替換成 terraform show 指令的輸出內容。雖然這種做法在此範例中可行,但如要將資源匯入已用於管理資源的設定中,就需要編輯 terraform show 的輸出內容,以移除不需要完全取代的現有資源設定,並將新的資源併入現有設定。
  1. 檢查 docker.tf 檔案,確認其內容已替換成剛剛執行的 terraform show 指令輸出內容。

  2. 請執行下列程式碼:

terraform plan

Terraform 會顯示警告和錯誤訊息,包括關於一個已淘汰引數 (即「links」),以及一些唯讀引數 (ip_addressnetwork_datagatewayip_prefix_lengthid)。

這些唯讀引數是 Terraform 在狀態中為 Docker 容器儲存的值,但因為容器是由 Docker 從內部進行管理,所以 Terraform 無法透過設定設置這些引數。Terraform 可以透過設定設置 links 引數,但仍會顯示警告訊息,因為該引數已淘汰,Docker 供應商也可能不會在日後版本中支援。

本範例所示範的方式為載入 Terraform 狀態中的所有屬性,因此設定中會包含採用預設值的選用屬性。至於哪些屬性為選用,預設值分別為何,則會依供應商而異,詳情請參閱供應商說明文件

  1. 現在您可以視需要移除這些選用的屬性。請移除所有這類屬性,僅保留必要的屬性imagenameports。移除選用屬性後,設定應如下所示:
resource "docker_container" "web" { image = "sha256:87a94228f133e2da99cb16d653cd1373c5b4e8689956386c1c12b60a20421a02" name = "hashicorp-learn" ports { external = 8080 internal = 80 ip = "0.0.0.0" protocol = "tcp" } }

匯入實際的基礎架構時,請參閱供應商說明文件瞭解各引數的功用,如果方案步驟出現錯誤或警告訊息,就能知道如何處理。舉例來說,您可以在 Docker 供應商說明文件中找到 links 引數相關說明。

  1. 請確認錯誤已排除:
terraform plan

現在應能順利執行方案。請注意,這項方案表示 Terraform 會更新容器以新增 attachlogsmust_runstart 屬性。

Terraform 使用這些屬性建立 Docker 容器,但 Docker 不會儲存這些屬性。因此,terraform import 不會將這些屬性的值載入狀態中。您規劃和套用設定時,Docker 供應商會為這些屬性指派預設值並儲存在狀態中,但這些屬性不會影響執行中的容器。

  1. 請套用變更,然後完成新版 Terraform 設定/狀態與 Docker 容器的同步處理程序。在系統提示中輸入 yes 即可確認。
terraform apply

現在設定檔、Terraform 狀態和容器皆已同步,您就能使用 Terraform 照常管理 Terraform 容器。

建立映像檔資源

在某些情況下,不使用 terraform import 指令即可透過 Terraform 管理資源。這類資源通常是由單一專屬 ID 或標記定義的資源,例如 Docker 映像檔。

docker.tf 檔案中,docker_container.web 資源會為用於建立容器的映像檔指定 SHA256 雜湊 ID。這就是 Docker 內部儲存映像檔 ID 的方式,因此 terraform import 會將映像檔 ID 直接載入狀態中。然而,映像檔 ID 不同於映像檔標記或名稱,並非易於理解的值,且可能不符合您的意圖。舉例來說,您可能會想使用最新版的「nginx」映像檔。

  1. 如要擷取映像檔的標記名稱,請執行下列指令,並以 docker.tf 中的映像檔 ID 取代 <IMAGE-ID>
docker image inspect -f {{.RepoTags}}
  1. docker.tf 檔案中新增以下設定,表示此映像檔屬於資源:
resource "docker_image" "nginx" { name = "nginx:latest" } 注意:現在還不要取代 docker_container.web 資源中的映像檔值,否則 Terraform 會刪除並重新建立容器。由於 Terraform 尚未將 docker_image.nginx 資源載入狀態中,因此沒有可與硬式編碼映像檔相比的映像檔 ID,這會導致 Terraform 以為必須取代容器。為避免這項問題,請先建立映像檔,更新容器後再加以使用,如本研究室示範的做法。
  1. 在狀態中建立映像檔資源:
terraform apply

現在 Terraform 已為映像檔建立資源,您就能在容器設定中參照該映像檔。

  1. docker_container.web 變更映像檔值,以參照新的映像檔資源:
resource "docker_container" "web" { image = docker_image.nginx.image_id name = "hashicorp-learn" ports { external = 8080 internal = 80 ip = "0.0.0.0" protocol = "tcp" } }
  1. 查看變更:
terraform apply

因為 docker_image.nginx.latest 符合您取代的硬式編碼映像檔 ID,所以現在執行 terraform apply 不會顯示任何變更。

注意:初次建立 Docker 容器後,如果您在執行這項指令前曾變更「nginx:latest」標記的映像檔 ID,系統會刪除容器並以新的映像檔重新建立容器。

運用 Terraform 管理容器

既然現在是由 Terraform 管理 Docker 容器,您就可以使用 Terraform 變更設定。

  1. 請在 docker.tf 檔案中,將容器的外部通訊埠從 8080 變更為 8081
resource "docker_container" "web" { name = "hashicorp-learn" image = docker_image.nginx.image_id ports { external = 8081 internal = 80 ip = "0.0.0.0" protocol = "tcp" } }
  1. 請套用變更:
terraform apply

在系統提示中輸入 yes 即可確認。

Terraform 就會刪除容器,並使用新的通訊埠設定重新建立容器。

  1. 請確認容器已替換成新的容器,且具有新的設定。
docker ps

請注意,容器 ID 已變更。變更通訊埠設定需要刪除並重新建立容器,因此這是全新的容器。

刪除基礎架構

現在您已將 Docker 容器和用來建立容器的映像檔匯入 Terraform。

  1. 請刪除容器和映像檔:
terraform destroy

在系統提示中輸入 yes 即可確認。

  1. 請確認容器已刪除:
docker ps --filter "name=hashicorp-learn" 注意:您之前已將映像檔新增至 Terraform 設定和容器中,因此映像檔會從 Docker 和容器中刪除。如果其他容器正在使用相同的映像檔,系統將無法完成刪除作業。記住,將資源匯入 Terraform 即表示 Terraform 會管理資源的整個生命週期,包括刪除。

限制和其他考量重點

將資源匯入 Terraform 時,務必考量一些重要事項。

Terraform 匯入功能對基礎架構目前狀態的瞭解僅限於 Terraform 供應商回報的內容,不包括:

  • 基礎架構是否正常運作。
  • 基礎架構的用意。
  • 非由 Terraform 控管的基礎架構變更,例如 Docker 容器檔案系統的狀態。

執行匯入作業中的手動步驟時很容易出錯,如果匯入資源的操作人員不瞭解當初建立資源的做法和原因等來龍去脈,則出錯機率更高。

匯入作業會影響 Terraform 狀態檔案,因此在匯入新基礎架構前,可以考慮先建立備份。

Terraform 匯入功能不會在基礎架構之間偵測或產生關聯。

Terraform 不會偵測設定中是否有不必要的預設屬性。

並非所有供應商和資源都支援 Terraform 匯入功能。

將基礎架構匯入 Terraform 不代表 Terraform 可以刪除和重新建立該基礎架構。舉例來說,匯入的基礎架構可能會仰賴其他非代管的基礎架構或設定。

遵循基礎架構即程式碼 (IaC) 最佳做法 (例如「不可變更的基礎架構」) 有助於防止許多這類問題,但手動建立的基礎架構可能難以遵循 IaC 最佳做法。

Terraformer 等工具可自動化執行部分與匯入基礎架構相關的手動步驟,但這些工具並不屬於 Terraform 本身,HashiCorp 亦不為其背書或提供支援。

恭喜!

在本研究室中,您學到了如何透過 Terraform 管理後端和狀態。您建立了本機和 Cloud Storage 後端來管理狀態檔案,也重新整理狀態、將設定匯入 Terraform。接著,您更新了設定並完成手動編輯,成功運用 Terraform 全面管理 Docker 容器。

後續步驟/瞭解詳情

請務必查看下列資源,獲得更多 Terraform 實作練習機會:

Google Cloud 教育訓練與認證

協助您瞭解如何充分運用 Google Cloud 的技術。我們的課程會介紹專業技能和最佳做法,讓您可以快速掌握要領並持續進修。我們提供從基本到進階等級的訓練課程,並有隨選、線上和虛擬課程等選項,方便您抽空參加。認證可協助您驗證及證明自己在 Google Cloud 技術方面的技能和專業知識。

使用手冊上次更新日期:2024 年 1 月 26 日

研究室上次測試日期:2023 年 12 月 11 日

Copyright 2024 Google LLC 保留所有權利。Google 和 Google 標誌是 Google LLC 的商標,其他公司和產品名稱則有可能是其關聯公司的商標。