Terraform-provider-azurerm: Unable to add Private Certificates (.pfx) to App Service

Created on 24 Aug 2018  ·  5Comments  ·  Source: terraform-providers/terraform-provider-azurerm

Hello,

I'm trying to find a way to add a Private Certificate to an App Service.

To be more clear, I'm talking about the certificates you can import into an App Service following the Web Portal from: App Service -> SSL settings -> Private Certificates (.pfx) -> Upload Certificate

I cannot find anything useful on the azurerm_app_service Terraform documentation.

Thanks a lot.
IP

duplicate new-resource servicapp-service

Most helpful comment

@DeanDM you can have look at our terraform modules: transactiveltd, fork or use the one you think will help.

All 5 comments

iako,

This feature has been tagged for enhancement, #1136.

Currently, we do the following:

  • add the certificate to KeyVault, (manually or with Terraform)
  • create the services plan
  • add the certificate to the service plan, with Terraform azurerm_template_deployment
  • add the app service
  • bind the certificate to the app-service, with Terraform azurerm_template_deployment

FWIW here is quick example to help you get started, this assumes

  • the certificate is in keyvault
  • service_plan and app_service created
  • dns_cname for app_service created

Sorry i did not have time to test it, there maybe a copy paste error.

resource "azurerm_template_deployment" "ssl_certificate" {
  name                = "${format("%s-arm-certs", var.name)}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  deployment_mode     = "Incremental"

  template_body = <<DEPLOY
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "sslCertificateName": {
            "type": "string"
        },
        "keyVaultId" :{
            "type": "string"
        },
        "servicePlanId": {
            "type": "string"
        },
        "appServiceName":{
            "type": "string"
        },
        "appServiceFQDN":{
            "type": "string"
        }
    },
    variables : {
      "thumbprint":"[reference(resourceId('Microsoft.Web/certificates', parameters('sslCertificateName'))).Thumbprint]"
    }
    "resources": [
        {
            "type":"Microsoft.Web/certificates",
            "name":"[parameters('sslCertificateName')]",
            "apiVersion":"2016-03-01",
            "location":"[resourceGroup().location]",
            "properties":{
                "keyVaultId":"[parameters('keyVaultId')]",
                "keyVaultSecretName":"[parameters('sslCertificateName')]",
                "serverFarmId": "[parameters('servicePlanId')]"
            }
        },
        {
            "type":"Microsoft.Web/sites/hostnameBindings",
            "name":"[concat(parameters('appServiceName'), '/', parameters('appServiceFQDN'))]",
            "apiVersion":"2016-03-01",
            "location":"[resourceGroup().location]",
            "properties":{
                "sslState":"SniEnabled",
                "thumbprint":"[veriables('thumbprint')]"
            },
            "dependsOn": [
                "[concat('Microsoft.Web/certificates/',parameters('sslCertificateName'))]"
            ]
        }
    ]
    "outputs": {
        "thumbprint": {
            "type": "string",
            "value": "[veriables('thumbprint')]"
        }
    }
}
DEPLOY

  parameters {
    "appServiceName"     = "${azurerm_app_services.test.name}"
    "appServiceFQDN"     = "${format("%s.%s",azurerm_dns_cname_record.test.name, azurerm_dns_cname_record.test.zone_name)}"
    "servicePlanId"      = "${azurerm_app_service_plan.test.id}"
    "sslCertificateName" = "${var.keyvault_ssl_certificate_name}"
    "keyVaultId"         = "${var.keyvault_id}"
  }

  depends_on = [
    "azurerm_app_service.test",
    "azurerm_dns_cname_record.test",
  ]
}

Thanks @kevinneufeld that was really helpful. Here it is with some quotes fixed + typos

resource "azurerm_template_deployment" "ssl_certificate" {
  name                = "${format("%s-arm-certs", var.name)}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  deployment_mode     = "Incremental"

  template_body = <<DEPLOY
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "sslCertificateName": {
            "type": "string"
        },
        "keyVaultId" :{
            "type": "string"
        },
        "servicePlanId": {
            "type": "string"
        },
        "appServiceName":{
            "type": "string"
        },
        "appServiceFQDN":{
            "type": "string"
        }
    },
    "variables" : {
      "thumbprint":"(resourceId('Microsoft.Web/certificates', parameters('sslCertificateName'))).Thumbprint"
    },
    "resources": [
        {
            "type":"Microsoft.Web/certificates",
            "name":"[parameters('sslCertificateName')]",
            "apiVersion":"2016-03-01",
            "location":"[resourceGroup().location]",
            "properties":{
                "keyVaultId":"[parameters('keyVaultId')]",
                "keyVaultSecretName":"[parameters('sslCertificateName')]",
                "serverFarmId": "[parameters('servicePlanId')]"
            }
        },
        {
            "type":"Microsoft.Web/sites/hostnameBindings",
            "name":"[concat(parameters('appServiceName'), '/', parameters('appServiceFQDN'))]",
            "apiVersion":"2016-03-01",
            "location":"[resourceGroup().location]",
            "properties":{
                "sslState":"SniEnabled",
                "thumbprint":"[variables('thumbprint')]"
            },
            "dependsOn": [
                "[concat('Microsoft.Web/certificates/',parameters('sslCertificateName'))]"
            ]
        }
    ],
    "outputs": {
        "thumbprint": {
            "type": "string",
            "value": "[variables('thumbprint')]"
        }
    }
}
DEPLOY

  parameters {
    "appServiceName"     = "${azurerm_app_services.test.name}"
    "appServiceFQDN"     = "${format("%s.%s",azurerm_dns_cname_record.test.name, azurerm_dns_cname_record.test.zone_name)}"
    "servicePlanId"      = "${azurerm_app_service_plan.test.id}"
    "sslCertificateName" = "${var.keyvault_ssl_certificate_name}"
    "keyVaultId"         = "${var.keyvault_id}"
  }

  depends_on = [
    "azurerm_function_app.test",
    "azurerm_dns_cname_record.test",
  ]
}

I've been trying the same thing and I don't get any azure errors that my template is wrong but it is not succeeding for some reason. No error logs.

Error: Error applying plan:

1 error(s) occurred:

* azurerm_template_deployment.ssl_certificate: 1 error(s) occurred:

* azurerm_template_deployment.ssl_certificate: Error creating deployment: Code="" Message=""

I'll keep trying and update the post when it works.

Edit: It works. Just had to give it permissions to contact my vault

Set-AzureRmKeyVaultAccessPolicy -VaultName VAULTNAME -ServicePrincipalName abfa0a7c-a6b6-4736-8310-5855508787cd -PermissionsToSecrets get

@DeanDM you can have look at our terraform modules: transactiveltd, fork or use the one you think will help.

hi @iakko

Thanks for opening this issue :)

As mentioned by @kevinneufeld support for SSL Certificates on App Services has previously been requested in #1136 which I'm going to close this issue in favour of - would you mind subscribing to that one for updates?

Thanks!

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