首页 > 解决方案 > 配置应用服务证书似乎需要对 Key Vault、IBYP 的写入权限?

问题描述

以下 terraform 配置应该:

  1. 获取相关 Key Vault 的 id
  2. 获取证书secret的id
  3. 设置自定义主机名绑定
  4. 设置应用服务证书
data "azurerm_key_vault" "hosting_secondary_kv" {
  name                = local.ctx.HostingSecondaryKVName
  resource_group_name = local.ctx.HostingSecondaryRGName
}

data "azurerm_key_vault_secret" "cert" {
  name         = var.env == "prod" ? local.ctx.ProdCertificateName : local.ctx.NonProdCertificateName
  key_vault_id = data.azurerm_key_vault.hosting_secondary_kv.id
}

resource "azurerm_app_service_custom_hostname_binding" "webapp_fqdn" {
  for_each = local.apsvc_map

  hostname         = each.value.fqdn
  app_service_name = azurerm_app_service.webapp[each.key].name
  resource_group_name = var.regional_web_rg[each.value.location].name

  ssl_state = "SniEnabled"
  thumbprint = azurerm_app_service_certificate.cert[each.value.location].thumbprint

  depends_on = [
    azurerm_traffic_manager_endpoint.ep
  ]
}

resource "azurerm_app_service_certificate" "cert" {
  for_each = local.locations

  name                = var.env == "prod" ? local.ctx.ProdCertificateName : local.ctx.NonProdCertificateName
  resource_group_name = var.regional_web_rg[each.value].name
  location            = each.value
  key_vault_secret_id = data.azurerm_key_vault_secret.cert.id
}

我已经按照https://www.terraform.io/docs/providers/azurerm/r/app_service_certificate.html中的说明配置了所有权限

运行代码会产生以下错误:

Error: Error creating/updating App Service Certificate "wildcard-np-xyzhcm-com" (Resource Group "MyAppServiceResourceGroup"): web.CertificatesClient#CreateOrUpdate: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="LinkedAuthorizationFailed" Message="The client '5...8' with object id '5...8' has permission to perform action 'Microsoft.Web/certificates/write' on scope '/subscriptions/0...7/resourceGroups/MyAppServiceResourceGroup/providers/Microsoft.Web/certificates/wildcard-np-xyzhcm-com'; however, it does not have permission to perform action 'write' on the linked scope(s) '/subscriptions/0...7/resourceGroups/MyKeyVaultResourceGroup/providers/Microsoft.KeyVault/vaults/MyKeyVault' or the linked scope(s) are invalid."

所有资源都在同一个订阅中。

我不明白。Azure 是否希望我授予执行部署 ( 5...8) 的服务主体对包含证书的密钥保管库的“写入”权限?我错过了什么?

编辑 1

我使用 terraform 创建了对 Key Vault 的访问策略。以下是相关代码:

允许“Microsoft.KeyVault/vaults/read”操作的自定义角色定义:

resource "azurerm_role_definition" "key_vault_reader" {
  name  = "Key Vault Reader"
  scope = data.azurerm_subscription.current.id

  permissions {
    actions     = ["Microsoft.KeyVault/vaults/read"]
    not_actions = []
  }

  assignable_scopes = [
    data.azurerm_subscription.current.id
  ]
}

让 Microsoft WebApp 服务主体访问证书:

data "azurerm_key_vault" "hosting_secondary_kv" {
  name                = local.ctx.HostingSecondaryKVName
  resource_group_name = local.ctx.HostingSecondaryRGName
}

data "azuread_service_principal" "MicrosoftWebApp" {
  application_id = "abfa0a7c-a6b6-4736-8310-5855508787cd"
}

resource "azurerm_key_vault_access_policy" "webapp_sp_access_to_hosting_secondary_kv" {
  key_vault_id = data.azurerm_key_vault.hosting_secondary_kv.id

  object_id = data.azuread_service_principal.MicrosoftWebApp.object_id
  tenant_id = data.azurerm_subscription.current.tenant_id

  secret_permissions = ["get"]
  certificate_permissions = ["get"]
}

接下来,向部署使用的服务主体授予相应 Key Vault 的资源组中的自定义 Key Vault Reader 角色:

data "azurerm_key_vault" "hosting_secondary_kv" {
  name                = local.ctx.HostingSecondaryKVName
  resource_group_name = local.ctx.HostingSecondaryRGName
}

data "azurerm_role_definition" "key_vault_reader" {
  name  = "Key Vault Reader"
  scope = data.azurerm_subscription.current.id
}

resource "azurerm_role_assignment" "sp_as_hosting_secondary_kv_reader" {
  scope              = "${data.azurerm_subscription.current.id}/resourceGroups/${local.ctx.HostingSecondaryRGName}"
  role_definition_id = data.azurerm_role_definition.key_vault_reader.id
  principal_id       = azuread_service_principal.sp.id
}

最后为上述服务主体设置访问策略:

resource "azurerm_key_vault_access_policy" "sp_access_to_hosting_secondary_kv" {
  key_vault_id = data.azurerm_key_vault.hosting_secondary_kv.id

  object_id = azuread_service_principal.sp.object_id
  tenant_id = data.azurerm_subscription.current.tenant_id

  secret_permissions = ["get"]
  certificate_permissions = ["get"]
}

以及来自门户的快照:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

标签: azuressl-certificateterraformazure-web-app-serviceazure-keyvault

解决方案


因此,我们已经与 Microsoft 支持人员进行了讨论,他们提供的解决方案是我们可以使用基于内置阅读器角色 + Key Vault 部署操作的自定义角色定义。

terraform 角色定义如下所示:

resource "random_uuid" "reader_with_kv_deploy_id" {}

resource "azurerm_role_definition" "reader_with_kv_deploy" {
  role_definition_id = random_uuid.reader_with_kv_deploy_id.result
  name               = "Key Vault Reader with Action for ${var.sub}"
  scope              = data.azurerm_subscription.current.id
  description        = "Can deploy/import secret from key vault to Web App"

  permissions {
    actions     = ["*/read", "Microsoft.KeyVault/vaults/deploy/action"]
    not_actions = []
  }

  assignable_scopes = [
    data.azurerm_subscription.current.id
  ]
}

无论如何,使用此角色而不是“Key Vault Contributor”确实允许将应用服务链接到 Key Vault 中的证书。

这两个问题仍然存在:

  1. 为什么在地球上这种复杂性甚至是必要的,而只是 Reader 被认为不够好?
  2. 为什么没有内置角色呢?我无法相信任何人会同意授予服务主体 Key Vault Contributor 一个读者就足够的地方。

推荐阅读