Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_app_service_certificate can't reference azurerm_key_vault_certificate versionless secret ID #23237

Closed
1 task done
jared-koiter opened this issue Sep 11, 2023 · 7 comments · Fixed by #27537
Closed
1 task done

Comments

@jared-koiter
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

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 and review the contribution guide to help.

Terraform Version

1.5.3

AzureRM Provider Version

3.66.0

Affected Resource(s)/Data Source(s)

azurerm_app_service_certificate

Terraform Configuration Files

data "azurerm_key_vault_certificate" "example_keyvault_cert" {
  name         = "example-keyvault-cert"
  key_vault_id = azurerm_key_vault.example_keyvault.id
}

resource "azurerm_app_service_certificate" "example_appservice_cert" {
  resource_group_name = azurerm_resource_group.example_rg.name
  location            = azurerm_resource_group.example_rg.location
  name                = "example-appservice-cert"
  key_vault_secret_id = data.azurerm_key_vault_certificate.example_keyvault_cert.versionless_secret_id
}

Debug Output/Panic Output

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: parsing "https://example-key-vault.vault.azure.net/secrets/example-keyvault-cert": expected a key vault versioned ID but no version information was found in: "https://example-key-vault.vault.azure.net/secrets/example-keyvault-cert"
│
│   with azurerm_app_service_certificate.example_appservice_cert,
│   on example.tf line 10, in resource "azurerm_app_service_certificate" "example_appservice_cert":
│   10:   key_vault_secret_id = data.azurerm_key_vault_certificate.example_keyvault_cert.versionless_secret_id
│

Expected Behaviour

azurerm_app_service_certificate resource should be created referencing the versionless (latest) ID of the Key Vault certificate, allowing for automatic certificate rotation.

Actual Behaviour

Resource cannot be created. Only works if referencing the secret_id attribute of the Key Vault certificate which contains the version. Resource field validation seems to be using the NestedItemId function which requires the parsed string to include a version ID, though there are other functions in that file that allow for versionless/optional version validation.

Steps to Reproduce

terraform apply

Important Factoids

No response

References

Similar request to #14085 which added versionless ID support to azurerm_storage_encryption_scope.

@UppyAU
Copy link
Contributor

UppyAU commented Sep 12, 2023

Hi rcskosir,

From my use of this resource I haven't needed to specify the versionless secret ID like you might for an Application Gateway.

When I used the .id resource attribute and viewed the certificate in the app services Certificate pane it did not seem to be pinned to a version ID. I haven't been through a renewal of these certificates yet however.

From the App Service Certificate management pane there seems to be a sync option which furthers my suspicion that .id is fine here.

Cheers

@jared-koiter
Copy link
Author

I might have missed the intended path for automatic certificate rotation in that case.

In my own scenario I had updated a certificate in the Key Vault to a new version, but the certificate reference in the App Service certificates pane was not updating to the new version (unless I hit 'Sync' manually). When I looked at the contents of the azurerm_key_vault_certificate secret_id it was displaying a versioned path like https://example-key-vault.vault.azure.net/secrets/example-keyvault-cert/1234567890abcdef1234567890abcdef. I was under the impression that this meant it was locked to a specific version, but running something like terraform apply to try and force an update (like I assumed the 'Sync' button would do) showed no changes.

I found another issue connected to the #21989 PR which appears to have added suppression for changes to the secret ID, which explains why I didn't see any changes to be made by Terraform.

I also found the following in the documentation for managing Key Vault certificate imports in App Services:

If you update your certificate in Key Vault with a new certificate, App Service automatically syncs your certificate within 24 hours.

I suspect that I was merely impatient in expecting the App Services to automatically sync their certificates once the Key Vault source was updated to a new version, and that the Terraform provider doesn't need to be responsible for forcing the update to take place. It might still be worth adding support for using a versionless ID in the key_vault_secret_id field, especially if Azure itself is not storing a versioned reference.

@mazjindeel-code42
Copy link

I had the same misconception @jared-koiter mentions about how the auto rotation works.

The provider requires a version, but after cert is added to the app service, the daily sync will will automatically bring in a newer version of the cert.

Terraform might still reference an older version, but Terraform ignores the version on this resource, so it doesn't detect a change.

So the certificate rotation works on its own.

It would still be good to have the provider allow a versionless secret ID, so you didn't have to refer to potentially stale versions just to get the resource created.

@calebak404
Copy link

calebak404 commented Mar 5, 2024

Terraform might still reference an older version, but Terraform ignores the version on this resource, so it doesn't detect a change.

This is incorrect, as I regularly see plans that cause a forced replacement due to the secret id changing.

@gsmith077
Copy link

gsmith077 commented Jun 3, 2024

This is ridiculous.

If you're following recommendations, you will likely have a key vault in a different subscription than the app service, as per Landing Zone Design recommendations.

If this is the case, the fact that I can't pass a versionless ID means that:

  • I need to create a data resource for the certificate in the key vault.
  • I need to create a data resource for the key vault itself.
  • I need to create an alternate provider for the subscription that has the key vault
  • All so I can reference a versioned ID for something that will change.

I don't care if Azure figures out the link on the backend: I'm being asked to hard code a versioned ID that will expire at some point. The azurerm_app_service_certificate resource should allow me to pass a single id string without a version.
https://{KV}.vault.azure.net/{secrets,certificate}/{cert_name} is a complete and valid reference, recognized by other resources that require a KV reference to a certificate (see the azurerm_application_gateway resource)

resource "azurerm_application_gateway" "application_gateway" {
[...]
  ssl_certificate {
    name                = "${name}-cert"
    key_vault_secret_id = var.certificate
  }
}

Especially in the case where I need to have an app gateway and an app service referencing the same KV stored certificate, I shouldn't have multiple interfaces in to the same value. I'm passing the standard KV ID for the secretless value, azurerm_app_service_certificate should accept that format, regardless of the backend behavior around versions and auto sync.

@NicholasMcGrath
Copy link

Here is a fix with help from post: phillipsj

data "azurerm_key_vault" "cert_kv"{
    name = "my-ky"
    resource_group_name = "my-rg"
    provider = azurerm.my-other-subscription
}
data "azurerm_key_vault_certificate" "domain_cert" {
  name         = replace(var.dns_hostname, ".", "-")
  key_vault_id = data.azurerm_key_vault.cert_kv.id
}
# This does not work because cross-subscription
# resource "azurerm_app_service_certificate" "domain_cert" {
#   name                = replace(var.dns_hostname, ".", "-")
#   resource_group_name = var.rg.name
#   location            = var.location
#   key_vault_secret_id = data.azurerm_key_vault_certificate.domain_cert.secret_id
# }

# Grant Microsoft managed app secret and cert reader on the keyvault before (not done here otherwise would affect other deployments)
# https://learn.microsoft.com/en-us/azure/app-service/configure-ssl-certificate?tabs=apex#authorize-app-service-to-read-from-the-vault 

resource "azapi_resource" "app_service_certificate" {
  type      = "Microsoft.Web/certificates@2022-03-01"
  name      = replace(var.dns_hostname, ".", "-")
  parent_id = var.rg.id
  location  = var.location
  
  body = jsonencode({
    properties = {
      keyVaultId         = data.azurerm_key_vault.cert_kv.id
      keyVaultSecretName = data.azurerm_key_vault_certificate.domain_cert.name
      serverFarmId       = azurerm_service_plan.plan.id
    }
    kind = "string"
  })
  response_export_values = ["properties.thumbprint"]
}

resource "azurerm_app_service_custom_hostname_binding" "main" {
  hostname            = var.dns_hostname
  app_service_name    = azurerm_linux_web_app.app.name
  resource_group_name = var.rg.name
  ssl_state           = "SniEnabled"
  thumbprint          = jsondecode(azapi_resource.app_service_certificate.output).properties.thumbprint
}

Copy link

github-actions bot commented Nov 3, 2024

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.