Error attaching trusted_root_certificate to terraform azurerm application gateway

186 views Asked by At

I would like to have an Ingress in my k8s cluster point to a service and pod on my k8s cluster which will serve a tls cert signed from a CA which is not well-known. To do this, I am trying to add a trusted_root_certificate block to my already existing azurerm_application_gateway terraform resource.

However, I get the following error

Error: waiting for update of Application Gateway: (Name "@@@" / Resource Group "@@@"): Code="ApplicationGatewayKeyVaultSecretException" Message="Problem occured while accessing and validating KeyVault Secrets associated with Application Gateway '/subscriptions/@@@/resourceGroups/@@@/providers/Microsoft.Network/applicationGateways/@@@'. See details below:" Details=[{"code":"ApplicationGatewayTrustedRootCertificateInvalidData","message":"Data for certificate /subscriptions/@@@/resourceGroups/@@@/providers/Microsoft.Network/applicationGateways/@@@/trustedRootCertificates/@@@ is invalid."}]

I have tried using a referenced key vault certificate in both PEM (private key with certificate chain) and PFX (manually converted PEM to PFX using openssl).

Below is the terraform with omissions for brevity.

locals {
  ca_name = "myca"
}

data "azurerm_key_vault_certificate" "ca" {
  name         = local.ca_name
  key_vault_id = data.azurerm_key_vault.myvault.id
}

resource "azurerm_application_gateway" "http_ingress" {
  sku {
    name     = "WAF_v2"
  }

  backend_http_settings {
    name                  = "https"
    cookie_based_affinity = "Disabled"
    port                  = 443
    protocol              = "Https"
    pick_host_name_from_backend_address = true
    trusted_root_certificate_names = ["${local.ca_name}"]
  }

  trusted_root_certificate {
    name                = local.ca_name
    key_vault_secret_id = data.azurerm_key_vault_certificate.ca.versionless_secret_id
  }
}

azurerm provider

...

    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.78.0"
    }

In the Azure Portal, the following error is displayed for the application gateway:

Last configuration update operation on this Application Gateway failed. This will not impact the functioning of the Application Gateway and it will continue to serve your application traffic. If you intend to change the configuration of the Application Gateway, please try doing the configuration update again.

However, another interesting piece is that even though the terraform apply fails, the trusted root certificate does get added to the application gateway and backend setting.

terraform -v
Terraform v1.4.5
on darwin_arm64

Any ideas?

1

There are 1 answers

4
Venkat V On
Error: waiting for update of Application Gateway: (Name "@@@" / Resource Group "@@@"): Code="ApplicationGatewayKeyVaultSecretException" Message="Problem occured while accessing and validating KeyVault Secrets associated with Application Gateway '/subscriptions/@@@/resourceGroups/@@@/providers/Microsoft.Network/applicationGateways/@@@'. See details below:" Details=[{"code":"ApplicationGatewayTrustedRootCertificateInvalidData","message":"Data for certificate /subscriptions/@@@/resourceGroups/@@@/providers/Microsoft.Network/applicationGateways/@@@/trustedRootCertificates/@@@ is invalid."}]

The above error is indicating that data for the certificate is invalid. The key_vault_secret_id attribute should point to a key vault secret, not a certificate, in the trusted_root_certificate block. Using the versionless_secret_id of the azurerm_key_vault_certificate data source, which retrieves a certificate, may be causing the issue.

I used below code to create Application Gateway with trusted_root_certificate module

provider "azurerm" {
  features {}
}
data "azurerm_resource_group" "example" {
  name = "Venkat"
}

data "azurerm_key_vault" "example" {
  name                = "venkatkeyvaulttest"
  resource_group_name = "Venkat"
}

data "azurerm_key_vault_certificate" "ca" {
  name         = "sasmplecertificate"
  key_vault_id = data.azurerm_key_vault.example.id
}

data "azurerm_key_vault_secret" "ca_secret" {
  name         = "venkat"
  key_vault_id = data.azurerm_key_vault.example.id
}
data "azurerm_user_assigned_identity" "example" {
  name                = "venkat"
  resource_group_name = "Venkat"
}

resource "azurerm_virtual_network" "example" {
  name                = "example-network"
  resource_group_name = data.azurerm_resource_group.example.name
  location            = data.azurerm_resource_group.example.location
  address_space       = ["10.254.0.0/16"]
}

resource "azurerm_subnet" "frontend" {
  name                 = "frontend"
  resource_group_name  = data.azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.254.0.0/24"]
}

resource "azurerm_public_ip" "example" {
  name                = "example-pip"
  resource_group_name = data.azurerm_resource_group.example.name
  location            = data.azurerm_resource_group.example.location
  allocation_method   = "Static"
  sku                 = "Standard"
}



locals {
  backend_address_pool_name      = "${azurerm_virtual_network.example.name}-beap"
  frontend_port_name             = "${azurerm_virtual_network.example.name}-feport"
  frontend_ip_configuration_name = "${azurerm_virtual_network.example.name}-feip"
  http_setting_name              = "${azurerm_virtual_network.example.name}-be-htst"
  listener_name                  = "${azurerm_virtual_network.example.name}-httplstn"
  request_routing_rule_name      = "${azurerm_virtual_network.example.name}-rqrt"
  redirect_configuration_name    = "${azurerm_virtual_network.example.name}-rdrcfg"
}

resource "azurerm_application_gateway" "network" {
  name                = "venkat-appgateway-demo"
  resource_group_name = data.azurerm_resource_group.example.name
  location            = "eastus"

  sku {
    name     = "Standard_v2"
    tier     = "Standard_v2"
    capacity = 2
  }

  gateway_ip_configuration {
    name      = "my-gateway-ip-configuration"
    subnet_id = azurerm_subnet.frontend.id
  }

  frontend_port {
    name = local.frontend_port_name
    port = 80
  }

  frontend_ip_configuration {
    name                 = local.frontend_ip_configuration_name
    public_ip_address_id = azurerm_public_ip.example.id
  }

  backend_address_pool {
    name = local.backend_address_pool_name
  }

  backend_http_settings {
    name                  = local.http_setting_name
    cookie_based_affinity = "Disabled"
    path                  = "/path1/"
    port                  = 80
    protocol              = "Http"
    request_timeout       = 60
  }

  http_listener {
    name                           = local.listener_name
    frontend_ip_configuration_name = local.frontend_ip_configuration_name
    frontend_port_name             = local.frontend_port_name
    protocol                       = "Http"
  }

  request_routing_rule {
    name                       = local.request_routing_rule_name
    priority                   = 9
    rule_type                  = "Basic"
    http_listener_name         = local.listener_name
    backend_address_pool_name  = local.backend_address_pool_name
    backend_http_settings_name = local.http_setting_name
  }
 identity {
    type        = "UserAssigned"
    identity_ids = [data.azurerm_user_assigned_identity.example.id]
  }
   trusted_root_certificate {
    name                = data.azurerm_key_vault_certificate.ca.name
    key_vault_secret_id = data.azurerm_key_vault_certificate.ca.versionless_secret_id
  }
}

The Keyvault Certificate is displayed and accessible when Terraform apply is executed.

enter image description here

enter image description here

Refer Application gateway SSL Profile & Application Gateway module in Terraform