我想 rename 怎麽办?state mv 乾坤大挪移
课程内容与代码会放在 Github 上: https://github.com/chechiachang/terraform-30-days
赛後文章会整理放到个人的部落格上 http://chechia.net/
这边用范例讲解,同时注意三个部分的差异程度
terraform 是协助工程师管理上述三组 state,达到状态统一
terraform state 变更 (ex. mv 等) 只管理 terraform state 这一部分,.tf resource 与 remote resource 是维持原状的
state 变更会在三组 state 中产生分歧,这些分歧会产生额外的效果,这是我们在 state manipulation 时须要格外注意的
https://www.terraform.io/docs/cli/commands/state/mv.html
一样回到 azure/foundation/compute_network
的范例
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
例如:我们因为业务需求变更,希望 rename module.network
的 module name,从 module.network 变成 module.private-network
git diff
# https://github.com/Azure/terraform-azurerm-network
-module "network" {
+module "private-network" {
source = "Azure/network/azurerm"
resource_group_name = var.resource_group_name
(END)
改完之後,回到 azure/foundation/compute_network
,进行 terraform plan,请问会看到什麽变化?这边大家依据过去所学,预测一下 terraform 的行为
这边给几个提示
cd azure/foundation/compute_network
terragtunt plan
╷
│ Error: Module not installed
│
│ on compute_network.tf line 2:
│ 2: module "private-network" {
│
│ This module is not yet installed. Run "terraform init" to install all
│ modules required by this configuration.
╵
ERRO[0015] 1 error occurred:
* exit status 1
跳出 module not installed 的错误,於是这边我们进行 initA
terragrunt init
Initializing modules...
Downloading Azure/network/azurerm 3.5.0 for priavte-network...
- priavte-network in .terraform/modules/private-network
Initializing the backend...
Initializing provider plugins...
於是在进行 plan
terragrunt plan
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
- destroy
Terraform will perform the following actions:
# module.network.azurerm_subnet.subnet[0] will be destroyed
}
# module.network.azurerm_subnet.subnet[1] will be destroyed
}
# module.network.azurerm_subnet.subnet[2] will be destroyed
}
# module.network.azurerm_virtual_network.vnet will be destroyed
}
# module.private-network.azurerm_subnet.subnet[0] will be created
}
# module.private-network.azurerm_subnet.subnet[1] will be created
}
# module.private-network.azurerm_subnet.subnet[2] will be created
}
# module.private-network.azurerm_virtual_network.vnet will be created
}
Plan: 4 to add, 0 to change, 4 to destroy.
Changes to Outputs:
~ vnet_id = "/subscriptions/.../resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet" -> (known after apply)
~ vnet_subnets = [
...
+ (known after apply),
+ (known after apply),
+ (known after apply),
]
plan 的结果,获得 4 to add, 4 to destroy,terraform 认为要移除远端已经存在的 network,并重新建立新的
terraform 为何会有这样的判断?
完全符合之前讨论过 terraform 运作的逻辑
然而这样符合我们的需求吗?
实务上,我们尽量避免 rename resource / module,可以避免上述情形时常发生,然而这边的 state manipulation 就是在讲非常情形:我们真的被迫要做 module rename,然而不希望远端被 destroy + create
在回忆一下三个部分
我们只要能够 rename state 中的 module.network 变成 state module.private-network
於是我们进行 state mv,尝试看看
terragrunt state mv --dry-run SOURCE DESTINATION
terragrunt state mv --dry-run module.network.data.azurerm_resource_group.network module.private-network.data.azurerm_resource_group.network
Would move "module.network.data.azurerm_resource_group.network" to "module.private-network.data.azurerm_resource_group.network"
看起来跟我们预想的状况相符,於是我们为 module 底下所有 resource 进行 state mv
terragrunt state mv module.network.data.azurerm_resource_group.network module.private-network.data.azurerm_resource_group.network
terragrunt state mv "module.network.azurerm_subnet.subnet[0]" "module.private-network.azurerm_subnet.subnet[0]"
terragrunt state mv "module.network.azurerm_subnet.subnet[1]" "module.private-network.azurerm_subnet.subnet[1]"
terragrunt state mv "module.network.azurerm_subnet.subnet[2]" "module.private-network.azurerm_subnet.subnet[2]"
terragrunt state mv module.network.azurerm_virtual_network.vnet module.private-network.azurerm_virtual_network.vnet
由於这个范例刚好 mv 一整个 module,我们也可以
terragrunt state mv module.network module.network-private
检视 state list 中的最新状况
terragrunt state list
module.private-network.data.azurerm_resource_group.network
module.private-network.azurerm_subnet.subnet[0]
module.private-network.azurerm_subnet.subnet[1]
module.private-network.azurerm_subnet.subnet[2]
module.private-network.azurerm_virtual_network.vnet
从成功更改 state 这边开始,会产生多人协作问题
在本地 .tf merge 进去之前,master branch 上 plan,会出现 4 destroy, 4 create,这是为何?
卡在这里的风险,就是其他同事刚好也在 plan 的话,看到 plan 一定超困惑,不晓得发生什麽事情
如何用 terraform 惹怒同事:改 state 不讲
所以 state manipulation PR 需要走特别的开发流程
<<: 系统弱点扫描工具-Tenable Nessus(中)
前言 来到了困住我好几天的储存结构,希望可以让大家很快地看明白,假如看不懂可以再参考大话资料结构的7...
写在前面 虽然写铁人赛文章很有趣很有挑战性,但是常常很多时候都写得有点怕怕的,怕真实的状况跟自己写的...
前言 其实有一个特别的例子是just,直觉会认为just就是产生一个publisher等人来subs...
为了让这个教学系列可以适合持续变化的社会变化,会这最後这篇预留更新扩展的资源列表,会不停时更新在这个...
为了在後续章节里示范 TeamCity 可以怎麽协助我们建置专案及一系列的自动化,我们需要有一个可以...