0
votes

I'm trying to create azurerm backend_http_settings in an Azure Application Gateway v2.0 using Terraform and Letsencrypt via the ACME provider.

I can successfully create a cert and import the .pfx into the frontend https listener, acme and azurerm providers provide everything you need to handle pkcs12.

Unfortunatley the backend wants a .cer file, presumably encoded in base64, not DER, and I can't get it to work no matter what I try. My understanding is that a letsencrypt .pem file should be fine for this, but when I attempt to use the acme provider's certificate_pem as the trusted_root_certificate, I get the following error:

Error: Error Creating/Updating Application Gateway "agw-frontproxy" (Resource Group "rg-mir"): network.ApplicationGatewaysClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="ApplicationGatewayTrustedRootCertificateInvalidData" Message="Data for certificate .../providers/Microsoft.Network/applicationGateways/agw-frontproxy/trustedRootCertificates/vnet-mir-be-cert is invalid." Details=[]

terraform plan works fine, the above error happens during terraform apply, when the azurerm provider gets angry that the cert data are invalid. I have written the certs to disk and they look as I'd expect. Here is a code snippet with the relevant code:

locals {
  https_setting_name             = "${azurerm_virtual_network.vnet-mir.name}-be-tls-htst"
  https_frontend_cert_name       = "${azurerm_virtual_network.vnet-mir.name}-fe-cert"
  https_backend_cert_name        = "${azurerm_virtual_network.vnet-mir.name}-be-cert"
}
provider "azurerm" {
    version = "~>2.7"
    features {
      key_vault {
          purge_soft_delete_on_destroy = true
        }
    }
}
provider "acme" {
  server_url = "https://acme-staging-v02.api.letsencrypt.org/directory"
}
resource "acme_certificate" "certificate" {
  account_key_pem           = acme_registration.reg.account_key_pem
  common_name               = "cert-test.example.com"
  subject_alternative_names = ["cert-test2.example.com", "cert-test3.example.com"]
  certificate_p12_password  = "<your password here>"
  dns_challenge {
    provider          = "cloudflare"

    config = {
      CF_API_EMAIL      = "<your email here>"
      CF_DNS_API_TOKEN  = "<your token here>"
      CF_ZONE_API_TOKEN = "<your token here>"
    }
  }
}
resource "azurerm_application_gateway" "agw-frontproxy" {
 name                = "agw-frontproxy"
 location            = azurerm_resource_group.rg-mir.location
 resource_group_name = azurerm_resource_group.rg-mir.name

 sku {
     name     = "Standard_v2"
     tier     = "Standard_v2"
     capacity = 2
 }
   trusted_root_certificate {
    name = local.https_backend_cert_name
    data = acme_certificate.certificate.certificate_pem
  }
    ssl_certificate {
    name     = local.https_frontend_cert_name
    data     = acme_certificate.certificate.certificate_p12
    password = "<your password here>"
  }
  #  Create HTTPS listener and backend
  backend_http_settings {
   name                  = local.https_setting_name
   cookie_based_affinity = "Disabled"
   port                  = 443
   protocol              = "Https"
   request_timeout       = 20
   trusted_root_certificate_names = [local.https_backend_cert_name]
  }

How do I get AzureRM Application Gateway to take ACME .PEM cert as trusted_root_certificates in AGW SSL end-to-end config?

2

2 Answers

0
votes

For me the only thing that worked is using tightly coupled Windows tools. If you follow the below documentation it's going to work. Spend 2 days fighting the same issue :)

Microsoft Docs

0
votes

If you don't specify any certificate, the Azure v2 application gateway will default to using the certificate in the backend web server that it is directing traffic to. this eliminates the redundant installation of certificates, one in the web server (in this case a Traefik edge router) and one in the AGW backend.

This works around the question of how to get the certificate formatted correctly altogether. Unfortunately, I never could get a certificate installed, even with a Microsoft Support Engineer on the phone. He was like "yeah, it looks good, it should work, don't know why it doesn't, can you just avoid it by using a v2 gateway and not installing a cert at all on the backend?"

A v2 gateway requires static public IP and "Standard_v2" sku type and tier to work as shown above.