You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

azurerm_management_lock导致Terraform apply执行失败的解决方法

问题场景

在资源组 my-rg 中创建了azurerm_storage_account和azurerm_cosmosdb_account两类资源,同时在my-rg资源组层级配置了锁级别为 ReadOnly 的azurerm_management_lock资源,相关Terraform配置代码如下:

resource "azurerm_storage_account" "main" {
  name                = "my-storage"
  resource_group_name = azurerm_resource_group.main.name 
  ...
}

resource "azurerm_cosmosdb_account" "main" {
  name                = "my-cosmosdb"
  resource_group_name = azurerm_resource_group.main.name
  ...
}

resource "azurerm_resource_group" "main" {
  name     = "my-rg"
  ...
}

resource "azurerm_management_lock" "resource-group-level" {
  name       = "terraform-managed-resources"
  scope      = azurerm_resource_group.main.id
  lock_level = "ReadOnly"
}

执行terraform apply命令时出现以下报错:

Error: [ERROR] Unable to List Write keys for CosmosDB Account "my-cosmosdb": documentdb.DatabaseAccountsClient#ListKeys: Failure sending request: StatusCode=409 -- Original Error: autorest/azure: Service returned an error. Status= Code="ScopeLocked" Message="The scope '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/my-rg/providers/Microsoft.DocumentDB/databaseAccounts/my-cosmosdb' cannot perform write operation because following scope(s) are locked: '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/my-rg'. Please remove the lock and try again."

Error: building Queues Client: retrieving Account Key: Listing Keys for Storage Account "my-storage" (Resource Group "my-rg"): storage.AccountsClient#ListKeys: Failure sending request: StatusCode=409 -- Original Error: autorest/azure: Service returned an error. Status= Code="ScopeLocked" Message="The scope '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/my-storage' cannot perform write operation because following scope(s) are locked: '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/my-rg'. Please remove the lock and try again."

注:以上为简化示例,实际环境中还有大量不受该锁影响的资源,此处仅列出错误日志涉及的相关资源。

需求:在无需手动移除管理锁的前提下,需要如何配置才能正常执行terraform apply?

报错根因

Azure将存储账户、CosmosDB账户的ListKeys(列出访问密钥)接口归类为写操作,资源组级别的ReadOnly锁会拦截作用域下所有写操作。Terraform创建这两类资源后,默认会调用ListKeys接口拉取密钥存入状态文件,如果锁在密钥读取操作完成前就已创建,请求会被直接拦截返回409。

解决方案

根据部署阶段选择对应配置即可,全程不需要手动操作管理锁:

  • 首次部署场景(资源和锁都未创建)
    给azurerm_management_lock资源显式添加对存储账户、CosmosDB账户的依赖,调整资源创建顺序:确保存储、CosmosDB完全创建完成、密钥读取等所有初始化操作全部执行完毕后,再创建资源组级别的ReadOnly锁。配置示例:

    resource "azurerm_management_lock" "resource-group-level" {
      name       = "terraform-managed-resources"
      scope      = azurerm_resource_group.main.id
      lock_level = "ReadOnly"
    
      # 显式声明依赖,锁在依赖资源全部创建完成后才会部署
      depends_on = [
        azurerm_storage_account.main,
        azurerm_cosmosdb_account.main
      ]
    }
    

    锁创建完成后,后续如果没有对存储、CosmosDB资源的变更操作,Terraform不会重复调用ListKeys接口,不会触发锁拦截。

  • 存量环境场景(锁已经存在,需要正常执行后续apply)
    在azurerm provider配置块中开启锁自动托管特性,Terraform执行需要写权限的操作前会自动临时移除锁,操作完成后自动按原配置恢复,全程无人工介入:

    provider "azurerm" {
      features {
        management_lock {
          # 开启后自动临时处理操作路径上的管理锁,操作完成自动恢复
          automatically_remove_on_resource_operations = true
        }
      }
    }
    

    额外优化配置(推荐):如果业务不需要通过账户密钥访问存储和CosmosDB,可以在对应资源块中关闭密钥认证,从根源上避免Terraform调用ListKeys接口,同时符合云资源安全最佳实践:

    • 存储账户添加配置:shared_access_key_enabled = false
    • CosmosDB账户添加配置:key_based_authentication_enabled = false

内容的提问来源于stack exchange,提问作者Will

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 17:27:52