Terraform部署Azure Key Vault多访问策略报错:需导入资源到状态
问题描述
尝试通过Terraform部署包含两个key_vault_access_policy的Azure Key Vault资源,用于给Application Gateway存储SSL证书。相关代码及执行错误如下:
主配置文件代码
data "azurerm_client_config" "current" {} module "agw_user_assigned_identity" { source = "../modules/resources-blocks/user_assigned_identity" user_assigned_identity_name = "agw-user-signed-id" resource_group_name = module.resource_group.name resource_group_location = module.resource_group.location } module "key_vault" { source = "../modules/resources-hub/key_vault" key_vault_name = local.key_vault_name resource_group_location = module.resource_group.location resource_group_name = module.resource_group.name tenant_id = data.azurerm_client_config.current.tenant_id soft_delete_retention_days = 90 } module "key_vault_private_certificate" { source = "../modules/resources-blocks/key_vault_certificate" key_vault_id = module.key_vault.id certificate_name = local.agw_certificate_name certificate_path = var.SSL_CERTIFICATE_PATH certificate_password = var.SSL_CERTIFICATE_PASSWORD depends_on = [module.key_vault_access_policy_agw] } module "key_vault_access_policy_users" { source = "../modules/resources-blocks/key_vault_access_policy" key_vault_id = module.key_vault.id tenant_id = data.azurerm_client_config.current.tenant_id object_id = data.azurerm_client_config.current.object_id certificate_permissions = ["Backup", "Create", "Delete", "DeleteIssuers", "Get", "GetIssuers", "Import", "List", "ListIssuers", "ManageContacts", "ManageIssuers", "Purge", "Recover", "Restore", "SetIssuers", "Update"] key_permissions = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey"] secret_permissions = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set"] storage_permissions = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update"] depends_on = [module.key_vault] } module "key_vault_access_policy_agw" { source = "../modules/resources-blocks/key_vault_access_policy" key_vault_id = module.key_vault.id tenant_id = data.azurerm_client_config.current.tenant_id object_id = module.agw_user_assigned_identity.principal_id secret_permissions = ["Get"] depends_on = [module.key_vault_access_policy_users] }
模块资源定义文件代码
resource "azurerm_key_vault" "kv" { name = var.key_vault_name location = var.resource_group_location resource_group_name = var.resource_group_name enabled_for_disk_encryption = true tenant_id = var.tenant_id soft_delete_retention_days = var.soft_delete_retention_days purge_protection_enabled = false sku_name = "standard" } locals { get_only_access = ["Get", "List"] } resource "azurerm_key_vault_access_policy" "acess_policy" { key_vault_id = var.key_vault_id tenant_id = var.tenant_id object_id = var.object_id key_permissions = var.get_only_access ? local.get_only_access : var.key_permissions secret_permissions = var.get_only_access ? local.get_only_access : var.secret_permissions storage_permissions = var.get_only_access ? local.get_only_access : var.storage_permissions certificate_permissions = var.get_only_access ? local.get_only_access : var.certificate_permissions }
执行错误
执行terraform apply -var-file="variables.tfvars"时触发报错:
Error: A resource with the ID "/subscriptions/xxxxxxxxxxx/resourceGroups/xxxxxxxxxx/providers/Microsoft.KeyVault/vaults/xxxxxxxx/objectId/xxxxxxxxxxxx" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_key_vault_access_policy" for more information. │ │ with module.key_vault_access_policy_users.azurerm_key_vault_access_policy.acess_policy, │ on ..\modules\resources-blocks\key_vault_access_policy\main.tf line 5, in resource "azurerm_key_vault_access_policy" "acess_policy": │ 5: resource "azurerm_key_vault_access_policy" "acess_policy" {
解决方案
错误核心原因是:目标Key Vault中已存在对应object_id的访问策略,但该资源未被纳入Terraform状态管理。以下是三种解决路径:
方案1:导入已存在的访问策略到Terraform状态
若需保留该策略并交由Terraform管理,执行以下导入命令(替换占位符为实际值):
terraform import module.key_vault_access_policy_users.azurerm_key_vault_access_policy.acess_policy "/subscriptions/xxxxxxxxxxx/resourceGroups/xxxxxxxxxx/providers/Microsoft.KeyVault/vaults/xxxxxxxx/objectId/xxxxxxxxxxxx"
导入完成后重新执行terraform apply即可。
方案2:合并访问策略到Key Vault资源定义(推荐)
Azure Key Vault的azurerm_key_vault资源本身支持内嵌access_policy块,这种方式能避免多策略资源冲突,更符合最佳实践。修改Key Vault模块代码如下:
resource "azurerm_key_vault" "kv" { name = var.key_vault_name location = var.resource_group_location resource_group_name = var.resource_group_name enabled_for_disk_encryption = true tenant_id = var.tenant_id soft_delete_retention_days = var.soft_delete_retention_days purge_protection_enabled = false sku_name = "standard" # 用户访问策略 access_policy { tenant_id = var.tenant_id object_id = var.user_object_id # 新增变量传递用户object_id certificate_permissions = ["Backup", "Create", "Delete", "DeleteIssuers", "Get", "GetIssuers", "Import", "List", "ListIssuers", "ManageContacts", "ManageIssuers", "Purge", "Recover", "Restore", "SetIssuers", "Update"] key_permissions = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey"] secret_permissions = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set"] storage_permissions = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update"] } # AGW用户托管身份访问策略 access_policy { tenant_id = var.tenant_id object_id = var.agw_principal_id # 新增变量传递AGW身份的principal_id secret_permissions = ["Get"] } }
随后修改主配置文件,删除两个key_vault_access_policy模块,直接将用户和AGW的身份ID传递给Key Vault模块即可。
方案3:删除已存在的访问策略(谨慎操作)
若该策略为冗余资源,可通过Azure CLI删除(替换占位符为实际值):
az keyvault delete-policy --name <你的Key Vault名称> --resource-group <资源组名称> --object-id <对应的Object ID>
注意:删除前需确认该策略未被其他依赖服务使用,避免影响现有业务。
内容的提问来源于stack exchange,提问作者Gregory
相关产品推荐
相关产品推荐

