Terraform升级Provider后资源变更处理最佳实践
Terraform azurerm Provider 2.x 升级 3.x 资源变更标准操作流程
前置必做操作(跳过这步出问题无法回滚)
- 全量备份当前工作目录,单独归档
.terraform目录、terraform.tfstate、terraform.tfstate.backup所有状态相关文件,存到操作目录外的路径 - 如果使用远程状态存储,先确认状态锁正常开启,迁移全过程禁止其他协作者执行任何Terraform命令
- 先把Provider版本锁回2.30.0,执行
terraform refresh同步状态,确认当前状态和Azure云上实际资源完全一致,无配置漂移
配置层适配
- 修改
required_providers块中azurerm版本号为3.13.0,执行terraform init -upgrade拉取对应版本的Provider - 对照官方升级文档逐行修改HCL配置,把所有重命名、移除的属性替换/删除干净:比如
azurerm_kubernetes_cluster_node_pool的availability_zones直接替换为zones,不要在配置里残留任何3.x版本不支持的旧字段 - 不要在这一步手动编辑状态文件:直接改状态是高风险非标准操作,JSON格式错误、字段值不匹配都会直接导致状态损坏,仅极端场景可作为最后手段,且必须提前备份。
分批次迁移状态(解决import失败问题)
之前import命令执行失败的核心原因是一次性加载全量有依赖的配置,只要依赖链上任意一个资源配置不匹配、变量解析异常,整个命令就会报错,不需要靠terraform graph梳理全量依赖,按资源依赖层级拆分批次逐个处理即可:
- 批次1:迁移无依赖基础资源,包括资源组、存储账户、日志分析工作区这类不依赖配置中其他资源的对象
- 批次2:迁移网络类资源,顺序为虚拟网络→子网→网络安全组→公网IP→路由表
- 批次3:迁移计算/容器类资源,包括AKS集群、节点池、虚拟机、虚拟机规模集
- 单个资源迁移操作步骤:
- 临时注释掉其他未迁移的资源块,避免依赖校验干扰当前操作
- 执行
terraform state rm <资源地址,例:azurerm_storage_account.mystorage>把旧版本资源从状态中移除 - 确认当前待迁移资源的HCL配置已经完全适配3.x语法,所有必填属性值和2.x版本保持一致
- 执行导入命令:
terraform import -var-file='./my.tfvars' <资源地址> <Azure资源完整资源ID> - 导入完成后执行
terraform plan,如果输出No changes. Your infrastructure matches the configuration.,说明该资源迁移完成,取消注释下一个待迁移资源,重复上述步骤
- 如果import报变量相关错误,先执行
terraform console -var-file='./my.tfvars'单独校验所有引用变量是否能正常解析,排查变量传值问题。
常见问题处理
- 导入后plan显示资源需要重建/产生大量非预期变更:先核对HCL配置中的属性值是否和Azure云上实际资源一致,3.x版本中部分属性的取值规则(比如SKU名称大小写、区域名格式)和2.x有差异,调整配置直到plan无预期变更后再执行apply
- 遇到属性不存在类报错:优先检查配置中是否残留2.x版本的旧属性,3.x已移除的属性直接从配置块中删除即可
- 遇到资源类型重命名的变更(比如2.x的资源类型在3.x中更换了资源名),直接用
terraform state mv <旧资源地址> <新资源地址>做状态内迁移,不需要删了重导,效率更高也不会出现配置比对冲突。
手动编辑状态文件不属于官方推荐的标准操作,仅当资源无法通过import命令正常导入、且操作者完全明确状态文件各字段含义时才可使用:编辑前必须做全量备份,编辑完成后执行
terraform validate校验格式正确性,首次apply前反复确认plan结果无非预期变更。
内容的提问来源于stack exchange,提问作者para
相关产品推荐
相关产品推荐

