Jason
Jason

Reputation: 637

Terraform bind SSL Certificate to Azure WebApp

I have recently been trying to bind a domain and an SSL certificate to a web app using Terraform in Azure.

I am having no luck in doing this and the documentation is a bit confusing / light on the ground.

The error I am getting when just doing a plan is:

Error: parsing "/subscriptions/<SUB-ID>/resourceGroups/Testing_Prod_KeyVault_JC/providers/Microsoft.KeyVault/vaults/secrets-testingprodjc": KeyVault Nested Item should contain 2 or 3 segments, got 8 from "subscriptions/<SUB-ID>/resourceGroups/Testing_Prod_KeyVault_JC/providers/Microsoft.KeyVault/vaults/secrets-testingprodjc"

I was wondering if anyone had been able to do this so far?

Here is my code for the Certificate and Domain bind:

//First Read the External Key Vault
data "azurerm_key_vault" "production_keyvault" {
  name                = "secrets-testingprodjc"
  resource_group_name = "Testing_Prod_KeyVault_JC"
}

// Now Read the Certificate
data "azurerm_key_vault_certificate" "prod_certificate" {
  name         = "testing-certificate-for-cic"
  key_vault_id = data.azurerm_key_vault.production_keyvault.id
}

// Now bind the webapp to the domain and look for certificate. 
resource "azurerm_app_service_custom_hostname_binding" "website_app_hostname_bind" {
  hostname            = "portal-staging-westeurope.jasoncontenttestingdomain.com"
  app_service_name    = azurerm_app_service.website_app.name
  resource_group_name = azurerm_resource_group.Terraform.name
  ssl_state = "SniEnabled"
  thumbprint = azurerm_app_service_certificate.cert.thumbprint
}

/* // Following block NOT BEING USED
resource "azurerm_app_service_certificate_binding" "bind_certificate_to_webapp" {
  hostname_binding_id = azurerm_app_service_custom_hostname_binding.website_app_hostname_bind.id
  ssl_state           = "SniEnabled"
  thumbprint = azurerm_app_service_certificate.cert.thumbprint 
}
*/

// Get Certificate from External KeyVault
resource "azurerm_app_service_certificate" "cert" {
  name                = "testing-certificate-for-cic"
  resource_group_name = azurerm_resource_group.Terraform.name
  location            = azurerm_resource_group.Terraform.location 
  key_vault_secret_id = data.azurerm_key_vault.production_keyvault.id
}

I am just for now doing this with my logged-in user account, not a service principle I am aware of the service principal part but for now I am just testing this. My logged-in account does have access to the external keyvault with full rights.

Upvotes: 3

Views: 4094

Answers (4)

Scott Taylor
Scott Taylor

Reputation: 66

Its a bit late, but I just had the same issue. They way I got it to work is add app_service_plan_id to the azurerm_app_service_certificate

resource "azurerm_app_service_certificate" "appservicecert" {
  name                = <name>
  location            = <location>
  resource_group_name = <resourcegroupname>
  key_vault_secret_id        = data.azurerm_key_vault_secret.example.id
  app_service_plan_id = data.azurerm_service_plan.example.id
}

Upvotes: 3

user19104728
user19104728

Reputation: 1

may i know if this below solution working ? // First Read the External Key Vault data "azurerm_key_vault" "production_keyvault" { name = "secrets-testingprodjc" resource_group_name = "Testing_Prod_KeyVault_JC" }

// Now Read the Certificate
data "azurerm_key_vault_certificate" "prod_certificate" {
  name         = "testing-certificate-for-cic"
  key_vault_id = data.azurerm_key_vault.production_keyvault.id
}

// Get Certificate from External KeyVault
resource "azurerm_app_service_certificate" "cert" {
  name                = "testing-certificate-for-cic"
  resource_group_name = azurerm_resource_group.Terraform.name
  location            = azurerm_resource_group.Terraform.location 
  key_vault_secret_id = data.azurerm_key_vault.production_keyvault.id
}

// Now bind the webapp to the domain. 
resource "azurerm_app_service_custom_hostname_binding" "website_app_hostname_bind" {
  hostname            = "portal-staging-westeurope.jasoncontenttestingdomain.com"
  app_service_name    = azurerm_app_service.website_app.name
  resource_group_name = azurerm_resource_group.Terraform.name
}

// Now bind certificate to the webapp. 
resource "azurerm_app_service_certificate_binding" "bind_certificate_to_webapp" {
  hostname_binding_id = azurerm_app_service_custom_hostname_binding.website_app_hostname_bind.id
  ssl_state           = "SniEnabled"
  certificate_id      = azurerm_app_service_certificate.cert.id
}

Upvotes: 0

Jason
Jason

Reputation: 637

I actually fixed this myself the other day with the following code, I found my answer on a GitHub repo for HashiCorp but I cant find the link now. It has to do with the resource azurerm_app_service_certificate if you use the key_vault_secret_id part it doesn't work you need to use pfx_blob.

Here is the code for anyone's ref:

//First Read the External Key Vault
data "azurerm_key_vault" "production_keyvault" {
  name                = "testingkeyvault2022"
  resource_group_name = "KeyVaultWestEuropeBackend"
}

// Now Read the Certificate
data "azurerm_key_vault_secret" "prod_certificate" {
  name         = "testcert"
  key_vault_id = data.azurerm_key_vault.production_keyvault.id
}

// Now bind the webapp to the domain and look for certificate. 
resource "azurerm_app_service_custom_hostname_binding" "website_app_hostname_bind" { //Website App
  depends_on = [
    azurerm_app_service_certificate.cert,
  ]
  hostname            = var.websiteurlbind
  app_service_name    = data.azurerm_app_service.read_website_app.name
  resource_group_name = data.azurerm_resource_group.Terraform.name
  ssl_state           = "SniEnabled"
  thumbprint          = azurerm_app_service_certificate.cert.thumbprint
}


// Get Certificate from External KeyVault
resource "azurerm_app_service_certificate" "cert" {
  name                = "testingcert"
  resource_group_name = data.azurerm_resource_group.Terraform.name
  location            = data.azurerm_resource_group.Terraform.location
  pfx_blob            = data.azurerm_key_vault_secret.prod_certificate.value
}

What I also noticed in my testing is you have to put the cert resource as a depends on on the bind. Its in my code but for clarity here is this piece of code:

depends_on = [
        azurerm_app_service_certificate.cert,
      ]

Upvotes: 1

adp
adp

Reputation: 1271

You can try with this:

    // First Read the External Key Vault
    data "azurerm_key_vault" "production_keyvault" {
      name                = "secrets-testingprodjc"
      resource_group_name = "Testing_Prod_KeyVault_JC"
    }
    
    // Now Read the Certificate
    data "azurerm_key_vault_certificate" "prod_certificate" {
      name         = "testing-certificate-for-cic"
      key_vault_id = data.azurerm_key_vault.production_keyvault.id
    }
    
    // Get Certificate from External KeyVault
    resource "azurerm_app_service_certificate" "cert" {
      name                = "testing-certificate-for-cic"
      resource_group_name = azurerm_resource_group.Terraform.name
      location            = azurerm_resource_group.Terraform.location 
      key_vault_secret_id = data.azurerm_key_vault.production_keyvault.id
    }
    
    // Now bind the webapp to the domain. 
    resource "azurerm_app_service_custom_hostname_binding" "website_app_hostname_bind" {
      hostname            = "portal-staging-westeurope.jasoncontenttestingdomain.com"
      app_service_name    = azurerm_app_service.website_app.name
      resource_group_name = azurerm_resource_group.Terraform.name
    }
    
    // Now bind certificate to the webapp. 
    resource "azurerm_app_service_certificate_binding" "bind_certificate_to_webapp" {
      hostname_binding_id = azurerm_app_service_custom_hostname_binding.website_app_hostname_bind.id
      ssl_state           = "SniEnabled"
      certificate_id      = azurerm_app_service_certificate.cert.id
    }

Upvotes: 0

Related Questions