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

Support for azurerm_app_service_managed_certificate when using multiple app services with the same custom domain in a single resource group #17378

Open
1 task done
dcrreynolds opened this issue Jun 24, 2022 · 5 comments

Comments

@dcrreynolds
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

Description

Trying to build an application that uses Traffic Manager to balance between 2 function apps in the same resource group in different regions. This requires that the Traffic Manager endpoint be added as a Custom domain to both function apps with the same name.

I tried to achieve this with the below HCL

resource "azurerm_app_service_custom_hostname_binding" "function_traffic_manager_custom_hostname_binding" {
  for_each = local.function_app_services

  hostname            = local.trafficmanager_baseurl
  app_service_name    = each.value.app_service_name
  resource_group_name = var.resource_group_name
}

resource "azurerm_app_service_managed_certificate" "function_traffic_manager_managed_certificate" {
  for_each = azurerm_app_service_custom_hostname_binding.function_traffic_manager_custom_hostname_binding

  custom_hostname_binding_id = each.value.id
}

resource "azurerm_app_service_certificate_binding" "function_traffic_manager_certificate_binding" {
  for_each = azurerm_app_service_managed_certificate.function_traffic_manager_managed_certificate

  hostname_binding_id = each.value.custom_hostname_binding_id
  certificate_id      = each.value.id
  ssl_state           = "SniEnabled"
}

This creates a Custom hostname on each function as expected, but only a single certificate with the name of the binding (a unique name per instance of the cert would be needed). Then azurerm_app_service_certificate_binding fails because one of the functions does not end up with a matching certificate.

Looking at the state file I see 2 instances for azurerm_app_service_managed_certificate. They have different custom_hostname_binding_id's like I would expect, but all other values are the same, including the thumbprint and id. This crossing of certs leads to azurerm_app_service_certificate_binding failing.

New or Affected Resource(s)/Data Source(s)

azurerm_app_service_custom_hostname_binding, azurerm_app_service_managed_certificate, azurerm_app_service_certificate_binding

Potential Terraform Configuration

One possible solution would be separating the name of the cert from the hostname value.

References

No response

@xiaxyi
Copy link
Contributor

xiaxyi commented Jun 27, 2022

@dcrreynolds have you tried azure portal and does it work?

@dcrreynolds
Copy link
Author

Hi @xiaxyi, yes, you can build this structure using the portal. You end up with 2 different certs (on per region) each attached to the expected function app. The certs are named "-".

@crmitchelmore
Copy link

@dcrreynolds did you ever solve this?

@dcrreynolds
Copy link
Author

yes, but with a null_resource. Its been a long while since I messed with it, so maybe things have changed.

@kbjarkefur
Copy link

kbjarkefur commented Nov 10, 2024

I had the same issue, and have been working with Azure support to find a solution. But we came to the conclusion that it is not supported to create and bind app manged certificates to the same custom domain in multiple apps, since the azurerm_app_service_managed_certificate resource is not able to handle the name conflict by appending the name of the function app to the certificate name. (This is how the portal handles the name conflict.)

For anyone else stuck with the same issue, here is a workaround using the CLI. In a loop over all apps (you can export this info from your terraform run to a json file):

   # Create a unique name for certificate - random string, app name, region etc.
   certificate_name="${custom_domain}-${<unique identifier across apps>}"
   
   # Create the certificate
   certificate_response=$(az functionapp config ssl create \
        --resource-group "$resource_group" \
        --name "$app_name" \
        --hostname "$custom_domain" \
        --certificate-name "$certificate_name")
   
   # Get the thumbprint 
   thumbprint=$(echo "$certificate_response" | jq -r '.properties.thumbprint')

   # If you want to handle the case when you rerun the script, 
   # and certificate already existed, then it is accessed 
   # using $(echo "$certificate_response" | jq -r '.thumbprint')
   # values will be null if thumbprint is not found in either of these paths
   
   # Bind the certificate
   az functionapp config ssl bind \
        --resource-group "$resource_group" \
        --name "$app_name" \
        --certificate-thumbprint "$thumbprint" \
        --ssl-type SNI

az functionapp config ssl create is still in preview, but once its status is moved to Generally Available, then azurerm_app_service_managed_certificate should have an optional input certificate-name where a unique name can be set for each certificate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants