Terraform-provider-azurerm: Application Gateway support for Keyvault SSL certificate

Created on 26 Jul 2019  ·  15Comments  ·  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

Description

Looking to implement keyvault certificates on HTTPS listener for application gateway. Here are the powershell docs I found on the subject: https://docs.microsoft.com/bs-latn-ba/azure/application-gateway/configure-keyvault-ps

we'd need to update the ssl_certificate section to allow the "ID" of the vault certificate also.

New or Affected Resource(s)

resource "azurerm_application_gateway" "AppGateway"

Potential Terraform Configuration

resource "azurerm_application_gateway" "AppGateway" {
  name                = var.name
  resource_group_name = data.azurerm_resource_group.ResourceGroup.name
  location            = data.azurerm_resource_group.ResourceGroup.location

  ssl_certificate {
    name     = var.ssl_certificate_name
    data     = var.ssl_certificate_file
    password = var.ssl_certificate_password
  }
}

References

related but not a replica:
https://github.com/terraform-providers/terraform-provider-azurerm/issues/3640

enhancement servicapplication-gateway

Most helpful comment

We use the following as an undocumented workaround:

  1. Upload SSL certificate to Azure Vault as a secret
az keyvault secret set --name "certificate" --vault-name "vault_name" --file "certificate.pfx" --encoding base64
  1. Read the secret using Terraform data resource
data "azurerm_key_vault_secret" "certificate" {
    name         = "certificate"
    key_vault_id = var.key_vault_id
}

resource "azurerm_application_gateway" "example" {
...
    ssl_certificate {
        name     = certificate
        data       = data.azurerm_key_vault_secret.certificate.value
        password = var.password
    }
...
}
  1. Profit

All 15 comments

I need exactly the same feature. Powershell has this script below. We need the same implementation extended for tf
$sslCert01 = New-AzApplicationGatewaySslCertificate -Name "SSLCert1" -KeyVaultSecretId $secretId

We use the following as an undocumented workaround:

  1. Upload SSL certificate to Azure Vault as a secret
az keyvault secret set --name "certificate" --vault-name "vault_name" --file "certificate.pfx" --encoding base64
  1. Read the secret using Terraform data resource
data "azurerm_key_vault_secret" "certificate" {
    name         = "certificate"
    key_vault_id = var.key_vault_id
}

resource "azurerm_application_gateway" "example" {
...
    ssl_certificate {
        name     = certificate
        data       = data.azurerm_key_vault_secret.certificate.value
        password = var.password
    }
...
}
  1. Profit

https://github.com/Azure/azure-cli/pull/10119 has just been merged. Can someone with a little more skill than I (@jeffreyCline @mbfrahry @tombuildsstuff etc) look at how difficult it would be to add it as a resource?

I need this too.

I will try to make the necessary updates, although I will need help contributing for the first time.

h/t to @katbyte for stubbing out most of the key_vault_secret_id already

We use the following as an undocumented workaround:

  1. Upload SSL certificate to Azure Vault as a secret
az keyvault secret set --name "certificate" --vault-name "vault_name" --file "certificate.pfx" --encoding base64
  1. Read the secret using Terraform data resource
data "azurerm_key_vault_secret" "certificate" {
    name         = "certificate"
    key_vault_id = var.key_vault_id
}

resource "azurerm_application_gateway" "example" {
...
    ssl_certificate {
        name     = certificate
        data       = data.azurerm_key_vault_secret.certificate.value
        password = var.password
    }
...
}
  1. Profit

Although this works it does not automatically poll for certificate renewals when done this way. Looking at ARM the difference below is observed:

Above method:

            "sslCertificates": [
                {
                    "name": "CertifcateName",
                    "properties": {}
                }

Proper Keyvault integration:

    "sslCertificates": [
                {
                    "name": "CertificateName",
                    "properties": {
                        "keyVaultSecretId": "https://vaultname.vault.azure.net/secrets/certificatename/certficatethumbprint"
                    }
                }
            ],

So it seems we need a change to allow the correct parameter to be used, ie. properties block with keyVaultSecretId as a property.

Noticed it's been requested already and seems on the 2.0.0 roadmap: https://github.com/terraform-providers/terraform-provider-azurerm/pull/4366

I'm very interested in this functionality too. Proper KV integration is important for centralized certificate lifecycle management.

If you need a tester, let me know.

@egorchabala Did you happen to find a way to retrieve the public key required for App Gateway's authentication_certificate? For App Gateway v2, we also need to add the root certificate's public key. If you happen to have a working approach for this I'd love to see it!

@JohnDelisle what's the need of adding root certificate's public key? For backend SSL encryption? If yes, this is naively supported in Terrafrom resource

@egorchabala yes, that's correct, if I understand the requirement correctly this is needed for root CA and the certificate on the backend pool too. I've since discovered that because my backend pool certs are issued by a well-known CA that I did not need to include either for App Gw to work.. it was happy without this.

If I wasn't using a well-known CA, I imagine I could have put the root CA (and intermediary signing certs') public keys into a Key Vault secret and retrieve that as data. However, in addition to the public key for CA and intermediary certs, I believe in some cases you need to provide the public key of the cert used on their backend pool too. In my case, the backend pool cert is the same as my front-end. What I was wondering with my question above was if there's an easy way (in TF) to derive the public key from the private key that's stored in the KV, rather than needing to maintain both the complete cert and the public key of that cert in KV as two items.

I see there are some TF certificate manipulation functions, but I'm not clear as to which if any would work for this situation and produce a public key compatible with App Gw's expectations.

@JohnDelisle Unfortunately, I'm not aware about this. In general, you either have two different certificates (trusted SSL cert for external publishing and self-signed SSL cert for backend pool) or have no need to specify certificate at all (in case backend SSL use trusted SSL cert)

This has been released in version 2.2.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:

provider "azurerm" {
    version = "~> 2.2.0"
}
# ... other configuration ...

How can we use this version? I tried to change the version in the provider to " version = "~> 2.2.0"" but it didn't work.

We use the following as an undocumented workaround:

  1. Upload SSL certificate to Azure Vault as a secret
az keyvault secret set --name "certificate" --vault-name "vault_name" --file "certificate.pfx" --encoding base64
  1. Read the secret using Terraform data resource
data "azurerm_key_vault_secret" "certificate" {
    name         = "certificate"
    key_vault_id = var.key_vault_id
}

resource "azurerm_application_gateway" "example" {
...
    ssl_certificate {
        name     = certificate
        data       = data.azurerm_key_vault_secret.certificate.value
        password = var.password
    }
...
}
  1. Profit

Hi there,

I tried this out and I am able to upload the cert as above. But I keep getting the error message below. Any pointers would be greatly appreciated.

Message="Password` specified for certificate /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/shared-rg/providers/Microsoft.Network/applicationGateways/aks01-appgw/sslCertificates/coreapicert is incorrect." Details=[]

Facts:
Cert is a 3rd part generated cert
I am on TF Enterprise
I have the password from the 3rd Party
Key Vault is in a separate resource group
I have full admin on subscription

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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

Was this page helpful?
0 / 5 - 0 ratings