iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
自我挑戰組

Terraform 繁體中文系列 第 24

Day24-【入門教程】state(list, mv, pull, push, replace-provider, rm, show)

  • 分享至 

  • xImage
  •  

原簡體中文教程連結: Introduction.《Terraform入門教程》


1.6.18.1. state

terraform state 指令可以用來進行複雜的狀態管理操作。隨著你對 Terraform 的使用越來越深入,有時候你需要對狀態檔做一些修改。由於我們在狀態管理章節中提到的,狀態檔案的格式屬於 HashiCorp 未公開的私有格式,所以直接修改狀態檔案是不適合的,我們可以使用 terraform state 指令來執行修改。

這個指令含有數個子指令,我們會一一介紹。

1.6.18.1.1. 用法

terraform state \[options] [args]

1.6.18.1.2. 遠端狀態

所有的 state 子命令都可以搭配本地狀態檔案以及遠端狀態使用。使用遠端狀態時讀寫操作可能用時稍長,因為讀寫都要透過網路完成。備份檔案仍然會寫入本機磁碟。

1.6.18.1.3. 備份

所有會修改狀態檔的 terraform state 子指令都會產生備份檔。可以透過 -backup 參數指定備份檔案的位置。

只讀子指令(例如 list)由於不會修改狀態,所以不會產生備份檔。

注意修改狀態的 state 子命令無法停用備份。由於狀態檔案的敏感性,Terraform 強制所有修改狀態的子指令都必須產生備份檔。如果你不想儲存備份,可以手動刪除。

1.6.18.1.4. 命令列友好

state 子命令的輸出以及命令結構都被設計成易於與 Unix 下其他命令列工具搭配使用,例如 grep、awk 等等。同樣的,輸出結果也可以在 Windows 上輕鬆使用 PowerShell 處理。

對於複雜場景,我們建議使用管道組合 state 子命令與其他命令列工具一同使用。

1.6.18.1.5. 資源地址

state 子指令中大量使用了資源位址,我們在資源位址章節中做了相關的介紹。


1.6.18.1.1. list

terraform state list 指令可以列出狀態檔案中記錄的資源物件。

1.6.18.1.1.1. 用法

terraform state list [options] [address...]

指令會根據 address 列出狀態檔中相關資源的資訊(如果給定了 address 的話)。如果沒有給定 address,那麼所有資源都會被列出。

列出的資源根據模組深度以及字典序進行排序,這意味著根模組的資源在前,越深的子模組定義的資源越在後。

對於複雜的基礎設施,狀態檔案可能包含成千上萬到的資源物件。可以透過提供一個或多個資源地址來進行過濾。

可以使用的可選參數有:

  • -state=path:指定使用的狀態檔案位址。預設為 "terraform.tfstate"。使用遠端 Backend 時此參數設定無效
  • -id=id:要顯示的資源 ID

1.6.18.1.1.2. 例:所有資源

$ terraform state list
aws_instance.foo
aws_instance.bar[0]
aws_instance.bar[1]
module.elb.aws_elb.main

1.6.18.1.1.3. 範例:根據資源位址過濾

$ terraform state list aws_instance.bar
aws_instance.bar[0]
aws_instance.bar[1]

1.6.18.1.1.4. 範例:根據模組過濾

$ terraform state list module.elb
module.elb.aws_elb.main

1.6.18.1.1.5. 範例:根據 ID 過濾

下面的例子顯示了根據資源物件ID過濾資源:

$ terraform state list -id=sg-1234abcd
module.elb.aws_security_group.sg

1.6.18.2.1. mv

terraform state mv 指令可以在狀態檔中移動資源。此指令可以移動單一資源物件、多實例資源物件中特定實例、整個模組以及其他物件。該指令也可以在不同的狀態檔案之間移動對象,以配合程式碼重構。

1.6.18.2.1.1. 用法

terraform state mv [options] SOURCE DESTINATION

這個指令會將資源物件從 SOURCE 位址移到 DESTINATION 位址。這可以用來實現單一簡單資源的重命名、在模組之間移動物件、移動整個模組等操作。它也可以用來在 Terraform 管理的不同基礎設施堆疊之間移動物件。

該指令在進行任意修改之前會先生成一個備份檔。備份機制不可關閉。如果是在不同狀態檔案之間移動對象,那麼每個狀態檔案都會產生一個備份。

此指令的 SOURCE 與 DESTINATION 為必填參數,必須是合法的資源地址。

此指令提供以下可選參數:

  • -backup=path:指定來源狀態檔案的備份位址,預設為來源狀態檔案加上 ".backup" 後綴
  • -bakcup-out=path:指定目標狀態檔案的備份位址,預設為目標狀態檔案加上 ".backup" 後綴
  • -state=path:來源狀態檔案位址,預設為目前 Backend 或是 "terraform.tfstate"
  • -state-out=path:目標狀態檔案位址。如果不指定則使用來源狀態檔案。可以是一個已經存在的文件或新建一個文件

1.6.18.2.1.2. 例子:重新命名一個資源

$ terraform state mv 'packet_device.worker' 'packet_device.helper'

1.6.18.2.1.3. 範例:將一個資源移到一個模組

以下範例展示了將 packet_device.worker 資源移至名為 app 的模組。如果模組目前不存在,則會建立模組。

$ terraform state mv 'packet_device.worker' 'module.app.packet_device.worker'

1.6.18.2.1.4. 例子:移動一個模組進入另一個模組

$ terraform state mv 'module.app' 'module.parent.module.app'

1.6.18.2.1.5. 例子:移動一個模組到另一個狀態文件

$ terraform state mv -state-out=other.tfstate 'module.app' 'module.app'

1.6.18.2.1.6. 移動一個有 count 參數的資源

$ terraform state mv 'packet_device.worker[0]' 'packet_device.helper[0]'

1.6.18.2.1.7. 移動一個有 for_each 參數的資源

Linux、MacOS 以及 Unix:

$ terraform state mv 'packet_device.worker["example123"]' 'packet_device.helper["example456"]'

PowerShell:

$ terraform state mv 'packet_device.worker[\"example123\"]' 'packet_device.helper[\"example456\"]'

Windows命令列:

$ terraform state mv packet_device.worker[\"example123\"] packet_device.helper[\"example456\"]

1.6.18.3.1. pull

terraform state pull 指令可以從遠端 Backend 手動下載狀態並輸出。此指令也可搭配本機狀態檔案使用。

1.6.18.3.1.1. 用法

terraform state pull

此命令下載目前位置對應的狀態文件,並以原始格式列印到標準輸出流。

由於狀態檔使用 JSON 格式,此功能可以搭配例如 jq 這樣的命令列工具使用,也可以用來人工修改狀態檔。


1.6.18.4.1. push

terraform push 指令被用來手動上傳本機狀態檔案到遠端 Backend。該指令也可以被用在目前使用的本機狀態檔案上。

1.6.18.4.1.1. 用法

terraform state push [options] PATH

這個指令會把 PATH 位置的狀態檔案推送到目前使用的 Backend 上(可以是目前使用的 terraform.tfstate 檔案)。

如果 PATH 的值為 "-" 那麼會從標準輸入流讀取要推送的狀態資料。這時資料會完全被載入進內存,並且在寫入目標狀態前進行檢查。

Terraform 會進行一系列檢查以防止你進行一些不安全的變更:

  • 檢查 lineage:如果兩個狀態檔案的 lineage 值不同,Terraform 會禁止推送。一個不同的 lineage 說明兩個狀態檔案描述的是完全不同的基礎設而你可能會因此丟失重要數據
  • 序號檢查:如果目標狀態檔案的 serial 值大於你要推送的狀態的 serial 值,Terraform 會禁止推送。一個更高的 serial 值說明目標狀態檔案已經無法與要推送的狀態檔案對應上了

這兩種檢查都可以透過新增 -force 參數停用,但不建議這樣做。如果停用安全檢查直接推送,那麼目標狀態檔案將會被覆寫。


1.6.18.5.1. replace-provider

terraform state replace-provider 指令可以取代狀態檔案中資源物件所使用的 Provider 的來源.

1.6.18.5.1.1. 用法

terraform state replace-provider [options] FROM_PROVIDER_FQN TO_PROVIDER_FQN

指令會更新所有使用 from Provider 的資源,將資源所使用的 Provider 更新為 to Provider。這允許我們更新狀態檔案中資源所使用的 Provider 的來源。

該指令在進行任意修改之前會先生成一個備份檔。備份機制不可關閉。

支援以下可選參數:

  • -auto-approve:跳過互動式提示確認環節
  • -backup=path:將備份寫入指定路徑。如果沒有該參數,則會寫入目前狀態檔案加上「.backup」 後綴的路徑
  • -lock=true:類似 apply,不再贅述
  • -lock-timeout=0s:類似 apply,不再贅述
  • -state=path:要讀取的狀態檔案位址。預設為目前使用的 Backend 或是 "terraform.tfstate" 文件

1.6.18.5.1.2. 範例

$ terraform state replace-provider hashicorp/aws registry.acme.corp/acme/aws

1.6.18.6.1. rm

terraform state rm 指令可以用來從狀態檔中刪除物件。此指令可以刪除單一資源、多實例資源中特定實例、整個模組以及等等。

1.6.18.6.1.1. 用法

terraform state rm [options] ADDRESS...

從狀態檔案中刪除一個或多個物件。

刪除對象並非刪除實際基礎設施對象,而只是狀態不再由 Terraform 管理,從狀態檔中刪除而已。舉例來說,如果你從狀態檔中刪除一個 AWS 虛擬機,那麼該虛擬機仍然會保持運行,只是運行 terraform plan 再也看不到該實例了。

從狀態檔案中刪除物件有著廣泛的用途。最常見的就是進行程式碼重構,不再管理某個資源(也許是轉移到另一個專案管理了)。

只有當所有要刪除的資源被刪除成功狀態檔案才會儲存。如果因為任何原因導致某個資源刪除發生錯誤(例如語法錯誤),那麼狀態檔案完全不會被修改。

該指令在進行任意修改之前會先生成一個備份檔。備份機制不可關閉。

此指令需要傳遞一個或多個待刪除資源的資源位址。

可使用如下可選參數:

  • -backup=path:寫入備份檔案的路徑
  • -state=path:要操作的資源檔案路徑。如果沒有該參數,則會使用目前 Backend 或是"terraform.tfstate"文件
1.6.18.6.1.1.1. 刪除一個資源
$ terraform state rm 'packet_device.worker'
1.6.18.6.1.1.2. 刪除一個模組
$ terraform state rm 'module.foo'
1.6.18.6.1.1.3. 刪除一個模組內資源
$ terraform state rm 'module.foo.packet_device.worker'
1.6.18.6.1.1.4. 刪除一個聲明 count 的資源
$ terraform state rm 'packet_device.worker[0]'
1.6.18.6.1.1.5. 刪除一個宣告 for_each 的資源

Linux, MacOS, and Unix:

$ terraform state rm 'packet_device.worker["example"]'

PowerShell:

$ terraform state rm 'packet_device.worker[\"example\"]'

Windows命令列:

$ terraform state rm packet_device.worker[\"example\"]

1.6.18.7.1. show

terraform state show 指令可以展示狀態檔案中單一資源的屬性。

1.6.18.7.1.1.1. 用法

terraform state show [options] ADDRESS

該命令需要指定一個資源位址。

此命令支援以下可選參數:

  • -state=path:指向狀態檔案的路徑。預設使用 "terraform.tfstate"。如果啟用了遠端 Backend 則該參數設定無效

terraform state show 的輸出被設計成人類可讀而非機器可讀。如果想要從輸出中提取數據,請使用 terraform show -json

1.6.18.7.1.1.2. 展示單一資源
$ terraform state show 'packet_device.worker'
# packet_device.worker:
resource "packet_device" "worker" {
    billing_cycle = "hourly"
    created       = "2015-12-17T00:06:56Z"
    facility      = "ewr1"
    hostname      = "prod-xyz01"
    id            = "6015bg2b-b8c4-4925-aad2-f0671d5d3b13"
    locked        = false
}
1.6.18.7.1.1.3. 展示單一模組資源
$ terraform state show 'module.foo.packet_device.worker'
1.6.18.7.1.1.4. 展示聲明 count 資源中特定實例
$ terraform state show 'packet_device.worker[0]'
1.6.18.7.1.1.5. 展示宣告 for_each 資源中特定實例

Linux, MacOS, and Unix:

$ terraform state show 'packet_device.worker["example"]'

PowerShell:

$ terraform state show 'packet_device.worker[\"example\"]'

Windows命令列:

$ terraform state show packet_device.worker[\"example\"]

原簡體中文教程連結: Introduction.《Terraform入門教程》


上一篇
Day23-【入門教程】providers, refresh, show
下一篇
Day25-【入門教程】taint, validate, untaint, workspace(list, delect, new, delete, show)
系列文
Terraform 繁體中文25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言