Terraform-provider-azurerm: Unable to access certificate in keyvault to bind it in app service

Created on 5 Oct 2020  路  3Comments  路  Source: terraform-providers/terraform-provider-azurerm

Community Note

  • Please vote on this issue by adding a 馃憤 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and AzureRM Provider) Version

Terraform v0.12.23
provider.azurerm v2.21.0

Affected Resource(s)

azurerm_app_service_certificate

Terraform Configuration Files

### --- Key Vault section
### Create Key Vault, set access policy to allow service principal to import the certificate and to save secrets
resource "azurerm_key_vault" "kv" {
  name                        = local.kvName
  location                    = data.azurerm_resource_group.rg.location
  resource_group_name         = data.azurerm_resource_group.rg.name
  enabled_for_disk_encryption = false
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  tags                        = var.tags
  sku_name                    = "standard"

  lifecycle {
    ignore_changes = [
      access_policy
    ]
  }

  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = data.azurerm_client_config.current.object_id

    secret_permissions = [
      "get",
      "delete",
      "set"
    ]

    ### Give full control to the sevice principal as it might need to delete a certificate on the next update run
    certificate_permissions = [
      "create",
      "delete",
      "deleteissuers",
      "get",
      "getissuers",
      "import",
      "list",
      "listissuers",
      "managecontacts",
      "manageissuers",
      "setissuers",
      "update",
    ]
  }

  depends_on = [azurerm_app_service.as]
}

### Upload certificate to Key vault
resource "azurerm_key_vault_certificate" "kvCertificate" {
  name         = "certificate-name"
  key_vault_id = azurerm_key_vault.kv.id

  certificate {
    contents = filebase64("${var.Config.certificateFilename}")
    password = var.ConfigCertificatePassword
  }

  certificate_policy {
    issuer_parameters {
      name = var.Config.certificateIssuer
    }

    key_properties {
      exportable = true
      key_size   = 2048
      key_type   = "RSA"
      reuse_key  = false
    }

    secret_properties {
      content_type = "application/x-pkcs12"
    }
  }
  depends_on = [azurerm_key_vault.kv, azurerm_app_service.as]
}

### Assign get certificate permissions to the app service so the app service can access it (real issue here, get permission is not enough)
resource "azurerm_key_vault_access_policy" "kvPolicy" {
  key_vault_id = azurerm_key_vault.kv.id

  tenant_id = data.azurerm_client_config.current.tenant_id
  object_id = azurerm_app_service.as.identity.0.principal_id

  secret_permissions = [
      "get",
  ]

  certificate_permissions = [
      "get",
      "list"  
]

  depends_on = [azurerm_key_vault_certificate.kvCertificate, azurerm_app_service.as]
}

### reference the certificate in the app service (problem here: throws error)
resource "azurerm_app_service_certificate" "asCertificateReference" {
  name                = "certificate-name"
  location            = data.azurerm_resource_group.rg.location
  resource_group_name = data.azurerm_resource_group.rg.name
  key_vault_secret_id = azurerm_key_vault_certificate.kvCertificate.secret_id

  depends_on = [azurerm_key_vault_access_policy.kvPolicy, azurerm_app_service.as]
}

Expected Behavior

The app service certificate is created successfully.

Actual Behavior

Error: Error creating/updating App Service Certificate "certificate-name" (Resource Group "website-dev-we"): web.CertificatesClient#CreateOrUpdate: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="BadRequest" Message="**The service does not have access to '/subscriptions/4abasa3d-037f-463b-b913-aadf51843526/resourcegroups/website-dev-we/providers/microsoft.keyvault/vaults/kv-dev-we' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation.**" Details=[{"Message":"The service does not have access to '/subscriptions/4abasa3d-037f-463b-b913-aadf51843526/resourcegroups/website-dev-we/providers/microsoft.keyvault/vaults/kv-dev-we' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation."},{"Code":"BadRequest"},{"ErrorEntity":{"Code":"BadRequest","ExtendedCode":"59716","Message":"The service does not have access to '/subscriptions/4abasa3d-037f-463b-b913-aadf51843526/resourcegroups/website-dev-we/providers/microsoft.keyvault/vaults/kv-dev-we' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation.","MessageTemplate":"The service does not have access to '{0}' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation.","Parameters":["/subscriptions/4abasa3d-037f-463b-b913-aadf51843526/resourcegroups/website-dev-we/providers/microsoft.keyvault/vaults/kv-dev-we"]}}]
2020-10-05T12:59:37.9602725Z 

Steps to Reproduce

start by creating a simple app service, then add the rest.

  1. terraform apply

Important Factoids

No. standard account and region. Deployment is running on devops using a terraform task.

References


I've seen a similar complaint here:
https://github.com/terraform-providers/terraform-provider-azurerm/issues/5058

But the reason does not seem to be the same. My access policies are correct. and i have followed the instructions here:
https://www.terraform.io/docs/providers/azurerm/r/app_service_certificate.html

I have browsed a bit and see that this seems to be an issue with the permissions. apparently binding the policy requires a write permission, which does not exist on this resource?

references:
https://stackoverflow.com/questions/60160688/configuring-an-app-service-certificate-seems-to-require-write-access-to-the-key
https://nexxai.dev/using-a-certificate-stored-in-key-vault-in-an-azure-app-service/

  • #0000
question servickeyvault

Most helpful comment

hi guys. still waiting on a reply. I don't think this is a question, more of a report on a limitation of the azurerm_app_service_certificate and azurerm_key_vault_access_policy resources. as it is right now, the key vault access policy is not sufficient to work with azurerm_app_service_certificate. it seems to be unusable/doesn't serve its purpose. thank you for your time!

All 3 comments

hi guys. still waiting on a reply. I don't think this is a question, more of a report on a limitation of the azurerm_app_service_certificate and azurerm_key_vault_access_policy resources. as it is right now, the key vault access policy is not sufficient to work with azurerm_app_service_certificate. it seems to be unusable/doesn't serve its purpose. thank you for your time!

Last comment in #5058 helped me:
https://github.com/terraform-providers/terraform-provider-azurerm/issues/5058#issuecomment-585254067
looks like Azure API creating certificate binding actually uses "Microsoft Azure AppService" built-in ServicePrincipal with Application ID "abfa0a7c-a6b6-4736-8310-5855508787cd" (ObjectID for it is tenant-specific), not under the service principal actually used for core terraform script execution.
so you need to give Get permissions on KV policies both to SP executing the script, and for the built-in "Microsoft Azure AppService" SP

hi @ruifrvaz

Thanks for opening this issue - apologies for the delayed response here!

Taking a look through here this appears to be an issue with the Terraform Configuration - notably Key Vault Access Policies can either be defined inline, or using the separate resource - but can't be through both (as is called out in the documentation) since otherwise these will conflict. As @mkusmiy has mentioned the Service Principal the Azure API is using to retrieve this certificate appears different than the one used by it's Managed Identity - as such I'd recommend updating that as proposed above.

Since this should be fixed by updating the Terraform Configuration being used here, I'm going to close this issue for the moment - but should you have further questions I'd suggest opening an issue in the Community Forums where someone should be able to assist further.

Thanks!

Was this page helpful?
0 / 5 - 0 ratings