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_managed_certificate: validate domain with TXT DNS rather than CNAME #27920

Open
1 task done
bdc opened this issue Nov 6, 2024 · 5 comments
Open
1 task done

Comments

@bdc
Copy link

bdc commented Nov 6, 2024

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 comments along the lines of "+1", "me too" or "any updates", 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.9.6

AzureRM Provider Version

3.116.0

Affected Resource(s)/Data Source(s)

azurerm_app_service_custom_hostname_binding

Terraform Configuration Files

resource "azurerm_app_service_custom_hostname_binding" "api_server_hostname_binding" {
  resource_group_name = var.resource_group_name
  hostname            = var.api_server_hostname
  app_service_name    = azurerm_linux_web_app.app_service.name
}

Debug Output/Panic Output

Example error message follows (private names are altered):

azurerm_app_service_managed_certificate.api_server_managed_certificate: Creating...                                                     

Error: creating/updating App Service Managed Certificate "mydomain.com" (Resource Group "rg-name"): web.CertificatesClient#CreateOrUpdate: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="BadRequest" Message="Properties.CanonicalName is invalid.  Current CNAME records of the hostname mydomain.com is gateway-subdomain.westus2.cloudapp.azure.com"

Expected Behaviour

Validation should be consistent with the portal behavior: validate the domain via a TXT record instead of CNAME.


azurerm_app_service_custom_hostname_binding attaches a custom hostname to an App Service instance. During deployment, the provider checks the hostname's DNS CNAME record to verify that it points to the App Service.

However, the provider should instead check for a TXT record rather than a CNAME. The TXT record proves domain verification, not the CNAME. Checking a TXT record rather than CNAME would match the behavior of the Azure portal.

Why does it matter? Because there exist valid configurations of the App Service and DNS that do not require a CNAME to point directly to it. For example, the Azure docs advise to point the CNAME at a Gateway if using a Gateway. This is possible to configure from the Azure Portal but not from Terraform, which will reject the deployment.

What else? A possible cheap fix would be to allow azurerm_app_service_custom_hostname_binding to skip the CNAME check with a new optional parameter.

Actual Behaviour

Validation fails due to CNAME value different from expected.

Steps to Reproduce

terraform plan -out main.tfplan
terraform apply main.tfplan

Important Factoids

Using ASEv3, Application Gateway, vnet

References

No response

@github-actions github-actions bot added the v/3.x label Nov 6, 2024
@ziyeqf
Copy link
Contributor

ziyeqf commented Nov 7, 2024

Hi @bdc, thanks for operning the issue.

The validation is done on the service side, we can not skip validation on the provider.

For this specific scenario, I checked the document and it requires a CNAME record. Could you please provide a link to the gateway example?

And per my understanding, if you are pointing the CNAME record to an Application Gateway, it requires to configure the certificate with the Gateway instead of the app service.

For any further questions please leave comments.

@bdc
Copy link
Author

bdc commented Nov 7, 2024

Thanks ziyeqf for the quick response.

Here's an example that uses App Service with an Application Gateway.

What's interesting is that App Service only checks the TXT record for validation, not CNAME (although I agree with you - the doc you linked makes it look obligatory!). In practice, I've found the easiest way to deploy this setup is to point the CNAME to App Service, run the deployment, then modify the CNAME to point to the Application Gateway. (While this works alright, it misses out on some of the automation value that terraform/ARM could be providing.)

@ziyeqf
Copy link
Contributor

ziyeqf commented Nov 8, 2024

Hi @bdc, thanks for update.

The example you provided used a certificate stored in KeyVault, it's a bit different than the app service managed certificate, for the later one, I don't think the Application Gateway could read the certificate and use It to encrypt connection with clients. Even if the manual modification succeeded, does the TLS work correctly?

The Application Gateway is a layer-7 load balancer and requests from clients/browser will be "TLS terminated" at the Application Gateway ( source ), then if required, the Application Gateway connects to the backend (App service here) with another TLS connection.

I don't think keeping the certificate managed by App Service could enable the Application Gateway to accept TLS connection with the same certificate.

If you intent to keep certificate with App Service, Azure Load Balancer, a layer-4 load balancer might fit more.

@bdc
Copy link
Author

bdc commented Nov 8, 2024

Thanks, yeah, both methods appear to work with the certificate(s) --

Client --cert-referenced-in-keyvault-- Gateway --cert-imported-from-keyvault-- App Service
Client --cert-referenced-in-keyvault-- Gateway --cert-managed-by-app-service-- App Service

The Gateway decrypts & reencrypts; in the first case it uses the same cert for SSL for the two hops; in the second, it uses two distinct certs for the two hops.

In either case the App Service still validates that the CNAME points to it, at configuration time, even though it will ultimately point to the Gateway.

I'm not really blocked by this since the workaround is a simple manual step during configuration time.

@ziyeqf
Copy link
Contributor

ziyeqf commented Nov 11, 2024

Hi @bdc,

though the second way worked with this workaround, I'm a bit worried if the app service managed certificate will be renewed normally as the CNAME points to app service is required by the service at creation time.

If you intend to keep this, you can try to use azapi_update_resource to update the CNAME record after the certificate creation. But I'd recommend to open an Azure support ticket and confirm if this is a valid scenario and if the certificate renewal does not require CNAME record.

Thanks.

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

3 participants