大型团队中如何在Terraform与Azure控制台高效防止资源误删(含Owner权限用户)
全方位防护Azure资源误删的解决方案
针对你描述的Azure迁移初期场景——既要用Terraform统一管理资源、支持快速克隆订阅,又要防止团队(包括你自己)误删资源(不管是Terraform配置变更还是Azure GUI操作),我整理了一套分层的解决方案,结合工具、流程和权限管控来实现高效防护:
一、Terraform层面:从配置到流水线的双重防护
1. 拆分资源与锁的Terraform配置到独立Workspace
你之前考虑的把管理锁放在单独Terraform Workspace的思路完全可行,而且是解决「误删资源配置文件后执行terraform apply导致资源被删」的关键:
- 创建两个Workspace:一个用于资源部署(管理所有Azure资源的配置),另一个用于锁管理(专门部署
azurerm_management_lock资源),两者共享同一个后端存储(比如Azure Storage),但状态文件相互独立。 - 锁管理Workspace的配置只负责给关键资源(比如资源组、核心服务)添加
CanNotDelete级别的锁,即使资源部署Workspace的配置被误删,锁的状态依然存在,Terraform尝试删除资源时会因为Azure侧的锁而报错,同时也能阻止GUI/CLI的直接删除。
示例锁管理Workspace的配置(支持批量遍历资源):
# 从资源部署Workspace的状态文件中读取需要锁的资源ID data "terraform_remote_state" "resource_workspace" { backend = "azurerm" config = { storage_account_name = "your-storage-account" container_name = "tfstate" key = "resource-workspace.tfstate" } } resource "azurerm_management_lock" "critical_resources" { for_each = toset([ data.terraform_remote_state.resource_workspace.outputs.rgtest1_id, # 添加其他关键资源ID ]) name = "CanNotDelete-${replace(each.value, "/", "-")}" scope = each.value lock_level = "CanNotDelete" notes = "Critical resource - deletion is restricted" }
2. 强制CI/CD流水线的Plan审核
禁止团队成员在本地直接执行terraform apply,所有变更必须通过CI/CD流水线:
- 流水线第一步自动执行
terraform plan,并将输出(尤其是Plan: X to add, Y to change, Z to destroy的删除部分)作为核心审核内容。 - 要求所有PR(Pull Request)必须至少有一位团队成员审核,重点检查是否有未预期的删除操作,审核通过后才能触发流水线的
apply步骤。 - 这样即使有人误删了配置文件,流水线的Plan会清晰显示删除操作,审核环节能及时拦截。
二、Azure平台层面:锁+策略的双重屏障
1. 批量应用Azure资源锁
除了Terraform管理的锁,还可以结合Azure Policy来强制给特定资源添加锁:
- 创建一个Azure Policy定义,自动给带有
critical: true标签的资源添加CanNotDelete锁,这样即使资源是手动创建的(虽然你希望全部用Terraform),也会被自动保护。 - 将Policy分配到订阅或管理组级别,批量覆盖所有资源,避免手动设置的繁琐。
2. 用Azure Policy限制删除操作
创建额外的Azure Policy来阻止删除特定类型的资源(比如资源组、VM、数据库),或者限制只有特定角色能执行删除操作:
- 示例Policy规则:拒绝所有用户执行
Microsoft.Resources/subscriptions/resourceGroups/delete操作,除非是特定的应急审批角色。 - 这样即使有人绕过了Terraform的防护,在GUI/CLI尝试删除,也会被Policy阻止。
三、流程与权限:四眼原则+最小权限
1. 落地四眼原则(双审批)
这是防止误操作最有效的流程手段:
- 所有Terraform变更必须通过PR,且需要至少一位熟悉业务的成员审核,确认变更的必要性(尤其是删除操作)。
- 对于紧急变更,也要保留审批环节,可以设置快速审批通道,但不能跳过。
2. 限制Azure RBAC权限
不要给团队成员(包括你自己)分配Owner角色,而是使用自定义RBAC角色:
- 自定义角色允许创建、修改资源,但拒绝
Microsoft.Authorization/locks/delete、Microsoft.Resources/subscriptions/resourceGroups/delete等核心删除权限。 - 只有在真正需要删除资源时,才临时提升权限(比如通过Azure AD Privileged Identity Management激活权限),用完后立即收回。
四、补充:状态文件与配置的安全备份
- 启用Terraform后端存储的版本控制(比如Azure Storage的版本保留),这样即使状态文件被误删或损坏,也能恢复到之前的版本。
- 把Terraform配置存储在Git仓库,启用分支保护规则,禁止直接推送到主分支,防止误删配置文件。
对你已尝试方案的补充说明
lifecycle { prevent_destroy = true }:它确实只能阻止terraform destroy,但结合CI/CD的Plan审核,可以在apply前发现配置删除的问题,起到预警作用。- 手动设置资源锁:确实低效,用Terraform批量管理锁(独立Workspace)或Azure Policy自动添加锁是更优的选择。
terraform state rm:不推荐使用,因为会让资源脱离Terraform管理,通过上面的分层防护,你完全可以在保留Terraform管理的同时,防止误删。
这样一套组合方案,既能满足你用Terraform统一管理资源、快速克隆订阅的需求,又能从工具、平台、流程三个层面全方位防止误删,即使是经验不足的团队成员或你自己操作失误,也能被拦截。
内容的提问来源于stack exchange,提问作者FrankS77
相关产品推荐
相关产品推荐

