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 到版本控制系统中的原因之一

<<:  C# 泛型(generics)

>>:  DAY5 Messaging API 设定

Day29 假设我们生活在别人的AR世界 那我们是不是很有可能明天就被删除了!?

上一篇说到了,AR宠物的部分,如果我们真的能用程序模拟出动物的习性、动作,那是不是代表说我们也能模拟...

[iT铁人赛Day26]练习题(5)

这次要来讲20201222的第五题了 这次的题目比较简单,但是题目叙述很长 大意就是:有一个人很爱喝...

Day44 ( 电子元件 ) 触碰开灯 ( 类比讯号 )

触碰开灯 ( 类比讯号 ) 教学原文参考:触碰开灯 ( 类比讯号 ) 这篇文章会介绍如何使用「序列写...

JavaScript学习日记 : Day18 - Class

在平时开发时,我们会遇到要创建许多类型相似的object,之前的文章有提到使用new操作符配合fun...

# Day5--Funny Function!一招函式打天下?

函式是每个程序语言都会有的一个语法,非常的实用,只要是编写功能,一定与函式脱离不了关系,而函式的内容...