通过 SystemAssigned 托管标识与 KeyVault 的 APIM 连接失败

APIM connection to KeyVault via SystemAssigned Managed Identity fails

提问人:komluk 提问时间:11/15/2023 最后编辑:Vinay Bkomluk 更新时间:11/21/2023 访问量:61

问:

我正在使用此处描述的以下设置。https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-properties?WT.mc_id=Portal-fx&tabs=azure-cli

我使用系统托管标识设置 APIM,然后转到 KV,将 Key Vault 机密和证书管理授予 APIM 标识,但当我尝试通过 terraform 将自定义域和证书发送到 APIM 时,出现以下错误:

错误:创建/更新自定义域:xxx 执行 CreateOrUpdate: xx 意外状态 400 出现错误:InvalidOperation:失败 使用托管服务标识访问 KeyVault 机密 xxx (http://aka.ms/apimmsi) 的 Api 管理服务。检查是否托管 类型标识:SystemAssigned、ClientId:xxx 和 ObjectId:xxx 具有 对 KeyVault 访问策略中的机密的 GET 权限。

terraform azure-keyvault apim

评论

0赞 Vinay B 11/16/2023
你能分享你@komluk尝试的代码吗?

答:

0赞 Vinay B 11/17/2023 #1

我厌倦了使用 terraform 通过 SystemAssigned 托管标识预配到 KeyVault 的 APIM 连接,并且能够成功预配要求。

在这里,你将尝试使用系统托管标识设置 Azure API 管理 (APIM),然后使用此标识访问 Azure Key Vault 中的机密,以便通过 Terraform 配置自定义域和证书。遇到的错误表示访问 Key Vault 的托管服务标识 (MSI) 存在权限问题。

收到的错误消息表明,与 Azure API 管理服务关联的托管服务标识没有访问 Azure Key Vault 中的机密所需的权限。

  • API 管理的系统托管标识可能对 Key Vault 中的机密没有正确的权限(特别是 GET 权限)。
  • 有时,在设置权限后,在完全传播和生效之前可能会有延迟。

确保您的 SP 或用户权限符合您的配置要求。由于需要预配 keyvault 并访问其机密,因此需要 keyvault 管理员、机密官员和参与者角色才能用于标识。

我尝试了具有必要权限的配置演示版本,我可以在其中成功配置要求。

我的 terraform 配置:

provider "azurerm" {
    features {}
}

variable "resource_group_name" {
    description = "Name of the resource group"
    type        = string
}

variable "location" {
    description = "Location for all resources"
    type        = string
}
  
variable "tenant_id" {
    description = "Tenant ID for the Azure resources"
    type        = string
}
  
resource "azurerm_resource_group" "example" {
    name     = var.resource_group_name
    location = var.location
}
  
resource "azurerm_api_management" "example" {
    name                = "examplevk-apim"
    location            = azurerm_resource_group.example.location
    resource_group_name = azurerm_resource_group.example.name
    publisher_name      = "example"
    publisher_email     = "[email protected]"
    sku_name            = "Developer_1"
  
    identity {
      type = "SystemAssigned"
    }
}
  
resource "azurerm_key_vault" "example" {
    name                = "examplekvvksb"
    location            = azurerm_resource_group.example.location
    resource_group_name = azurerm_resource_group.example.name
    tenant_id           = var.tenant_id
    sku_name            = "standard"
  
    access_policy {
      tenant_id = var.tenant_id
      object_id = azurerm_api_management.example.identity[0].principal_id
  
      secret_permissions = ["Get", "List", "Set", "Delete", "Recover", "Backup", "Restore", "Purge"]
    }
}

输出:

enter image description here

enter image description here

enter image description here

现在,将 SSL 证书推送到密钥保管库,并继续执行以下配置。

# Assuming the certificate is already in the Key Vault
data "azurerm_key_vault_secret" "example_certificate" {
  name         = "myCertificateName"
  key_vault_id = azurerm_key_vault.example.id
}

# Configure Custom Domain in APIM
resource "azurerm_api_management_custom_domain" "example" {
  api_management_id = azurerm_api_management.example.id

  portal {
    host_name            = "portal.my-custom-domain.com"
    key_vault_id         = azurerm_key_vault.example.id
    key_vault_secret_id  = data.azurerm_key_vault_secret.example_certificate.id
  }

  # Configure additional domains (developer portal, gateway, etc.) as needed
}

此配置将允许您访问认证,因为您的 SP 具有上述所有相关权限。