iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
DevOps

Terraform Workshop - Infrastructure as Code for Public Cloud 疫情警戒陪你度過 30 天系列 第 22

Day 20-state inspection-更改 state 有其風險,State manipulation 有賺有賠,更改前應詳閱官方文件說明書之二

更改 state 有其風險,State manipulation 有賺有賠,更改前應詳閱官方文件說明書之二

state inspection

課程內容與代碼會放在 Github 上: https://github.com/chechiachang/terraform-30-days

賽後文章會整理放到個人的部落格上 http://chechia.net/

追蹤粉專可以收到文章的主動推播

https://ithelp.ithome.com.tw/upload/images/20210901/20120327NvpHVr2QC0.jpg


Terraform supported manipulation

既然手動直接 vim 下去不是一個好方法,我們先來看 terraform 官方支援的 state 操作

state

  • list
  • show
  • mv
  • rm
  • refresh
  • taint/untaint
  • import

list

terraform state list 上堂課已經說明過,放在這邊做範例

cd azure/foundation/compute_network
terragrunt state list

module.network.data.azurerm_resource_group.network
module.network.azurerm_subnet.subnet[0]
module.network.azurerm_subnet.subnet[1]
module.network.azurerm_subnet.subnet[2]
module.network.azurerm_virtual_network.vnet

另外一個用例是,有時我們在 web console 上看到 azure cloud 上的 remote resource,例如:在 azure web console 上看到一個 subnet,我們想要

  • 根據 subnet 在 web consoel 上的資訊查詢對應的 .tf resource {} 在哪以便更改
  • 根據我們對 terraform 的理解,實際的 subnet 需要透過 state 查詢,才能對應到 .tf resource
  • 然而在一個複雜的 module 中 state list 出來的 resource 可能很多
  • 直接閱讀 .tf 也會十分花時間,複雜的 terraform module 的 directory 也會十分複雜,可能會在引用外部 module,例如:azure/modules/compute_network 內又引用 Azure/network/azurerm

terraform 提供了 state filter by id 的方式

  • 在 web console 查到實際物件的 id
  • 直接在 state list 中 filter by id 就可以快速查到 state
  • 也可以根據 resource address 輕鬆找到 .tf resource
terraform state list -id /subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet/subnets/dev-1

module.network.azurerm_subnet.subnet[0]

show

這時我們可以進一步 show 出 state 的內容

terragrunt state show module.network.azurerm_virtual_network.vnet

resource "azurerm_virtual_network" "vnet" {
    address_space         = [
        "10.2.0.0/16",
    ]
    dns_servers           = []
    guid                  = "5e5fb9de-600b-4085-a59d-0792c567c3a3"
    id                    = "/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet"
    location              = "southeastasia"
    name                  = "acctvnet"
    resource_group_name   = "terraform-30-days"
    subnet                = [
        {
            address_prefix = "10.2.1.0/24"
            id             = "/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet/subnets/dev-1"
            name           = "dev-1"
            security_group = ""
        },
        {
            address_prefix = "10.2.2.0/24"
            id             = "/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet/subnets/dev-2"
            name           = "dev-2"
            security_group = ""
        },
        {
            address_prefix = "10.2.3.0/24"
            id             = "/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet/subnets/dev-3"
            name           = "dev-3"
            security_group = ""
        },
    ]
    tags                  = {
        "environment" = "foundation"
    }
    vm_protection_enabled = false
}

基本上所有 terraform 中設定 / 產生的資料,state 裡面都有

  • 設定的 resource argument 參數
  • apply 之後,API 回傳的實際 id / guid,對應遠端的 resource

在看另外一個

  • [] 是 bash 的特殊字元,再進到 terraform 前,就被 bash 判定語法有誤
  • 記得要使用 double / single quote
terragrunt state show module.network.azurerm_subnet.subnet[0]
zsh: no matches found: module.network.azurerm_subnet.subnet[0]

terragrunt state show 'module.network.azurerm_subnet.subnet[0]'

resource "azurerm_subnet" "subnet" {
    address_prefix                                 = "10.2.1.0/24"
    address_prefixes                               = [
        "10.2.1.0/24",
    ]
    enforce_private_link_endpoint_network_policies = false
    enforce_private_link_service_network_policies  = false
    id                                             = "/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet/subnets/dev-1"
    name                                           = "dev-1"
    resource_group_name                            = "terraform-30-days"
    service_endpoint_policy_ids                    = []
    service_endpoints                              = []
    virtual_network_name                           = "acctvnet"
}

Sensitive

對資安敏感的人,可能看到 state show 已經覺得不太舒服

  • 怎麼所有的參數都列出來啊
  • 這邊的範例還沒有使用 sensitive variable,例如 password / secret 內容,state 中這些參數也是明碼儲存的

terraform state 其實是有一定的敏感性,官方文件也有建議要好好保管 terraform state 檔案

  • 裡頭含有敏感資料,整個就要試做是敏感資料處理,應該加密儲存
  • 並在 storage account 加上帳號群線控管
  • 這課程的範例我們都沒做,所以 tfsec 掃描會一直報警 ;)
  • state 落到有心人士手上,可以做很多事情,請妥善保管
  • 這也是為何不建議 commit state 到版本控制系統中的原因之一

上一篇
Day 19-infrastructure 也可以 for each 之四:for & dynamic block
下一篇
Day 21-state manipulation 之三:我想 rename 怎麼辦?state mv 乾坤大挪移
系列文
Terraform Workshop - Infrastructure as Code for Public Cloud 疫情警戒陪你度過 30 天32

尚未有邦友留言

立即登入留言