'Azure terraform application gateway does not have secrets get permission on key vault

I am trying to provision an azure application gateway with terraform. And I have a key vault which has a self signed certificate referenced by the application gateway, but I am getting the below error:

Error: waiting for create/update of Application Gateway: (Name "ssi-test-public-appgateway" / Resource Group "ssi-test"): Code="ApplicationGatewayKeyVaultSecretException" Message="Problem occured while accessing and validating KeyVault Secrets associated with Application Gateway '/subscriptions/XXX/resourceGroups/ssi-test/providers/Microsoft.Network/applicationGateways/ssi-test-public-appgateway'. See details below:" Details=[{"code":"0","message":"The user, group or application 'name=Microsoft.Network/applicationGateways;appid=XXX;oid=XXX;iss=https://sts.windows.net/XXX/' does not have secrets get permission on key vault 'ssi-app-gw-kv;location=westeurope'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287"}]

And here's my terraform code:

identity.tf

data "azurerm_client_config" "current" {}

resource "azurerm_key_vault" "front_end_key_vault_cert" {
  name                        = var.key_vault_name
  location                    = var.location
  resource_group_name         = var.resource_group_name
  enabled_for_disk_encryption = true
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days  = 7
  purge_protection_enabled    = false

  sku_name = "standard"

  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = data.azurerm_client_config.current.object_id

    certificate_permissions = [
      "Backup",
      "Create",
      "Delete",
      "DeleteIssuers",
      "Get",
      "Import",
      "List",
      "ListIssuers",
      "ManageContacts",
      "ManageIssuers",
      "Purge",
      "Recover",
      "Restore",
      "SetIssuers",
      "Update"
    ]

    key_permissions = [
      "Backup",
      "Create",
      "Decrypt",
      "Delete",
      "Encrypt",
      "Get",
      "Import",
      "List",
      "Purge",
      "Recover",
      "Restore",
      "Sign",
      "UnwrapKey",
      "Update",
      "Verify",
      "WrapKey",
    ]

    secret_permissions = [
      "Backup",
      "Delete",
      "Get",
      "List",
      "Purge",
      "Recover",
      "Restore",
      "Set",
    ]   
  }
}

resource "azurerm_key_vault_certificate" "https_cert" {
  name         = "ssi-self-signed-cert"
  key_vault_id = azurerm_key_vault.front_end_key_vault_cert.id

  certificate_policy {
    issuer_parameters {
      name = "Self"
    }

    key_properties {
      exportable = true
      key_size   = 2048
      key_type   = "RSA"
      reuse_key  = true
    }

    lifetime_action {
      action {
        action_type = "AutoRenew"
      }

      trigger {
        days_before_expiry = 30
      }
    }

    secret_properties {
      content_type = "application/x-pkcs12"
    }

    x509_certificate_properties {
      # Server Authentication = 1.3.6.1.5.5.7.3.1
      # Client Authentication = 1.3.6.1.5.5.7.3.2
      extended_key_usage = ["1.3.6.1.5.5.7.3.1"]

      key_usage = [
        "cRLSign",
        "dataEncipherment",
        "digitalSignature",
        "keyAgreement",
        "keyCertSign",
        "keyEncipherment",
      ]

      subject_alternative_names {
        dns_names = ["*.ssi.com"]
      }

      subject            = "CN=*.ssi.com"
      validity_in_months = 12
    }
  }

  depends_on = [
    azurerm_key_vault.front_end_key_vault_cert
  ]
}

resource "azurerm_user_assigned_identity" "key_vault_read" {
  resource_group_name = var.resource_group_name
  location            = var.location
  name                = join("-", [var.project, var.environment, "key_vault_read_permission"])

}

resource "azurerm_role_assignment" "key_vault_role" {
  scope                = azurerm_key_vault.front_end_key_vault_cert.id
  role_definition_name = "Reader"
  principal_id         = azurerm_user_assigned_identity.key_vault_read.principal_id

  depends_on = [
    azurerm_key_vault.front_end_key_vault_cert, 
    azurerm_user_assigned_identity.key_vault_read, 
    azurerm_key_vault_certificate.https_cert
  ]

app-gateway.tf

resource "azurerm_application_gateway" "public_app_gateway" {
  name                = join("-", [var.project, var.environment, "public-appgateway"])
  location            = var.location
  resource_group_name = var.resource_group_name

  sku {
    name = "Standard_V2"
    tier = "Standard_v2"
  }

  . 
  .
  .

  dynamic "ssl_certificate" {
    for_each = var.ssl_certificates_configs
    content {
      name = lookup(ssl_certificate.value, "name")
      key_vault_secret_id = azurerm_key_vault_certificate.https_cert.secret_id 
    }
  }

  identity {
    type         = "UserAssigned"
    identity_ids = [azurerm_user_assigned_identity.key_vault_read.id]
  }

  dynamic "request_routing_rule" {
    for_each = var.appgw_routings
    content {
      name      = lookup(request_routing_rule.value, "name", local.pb_request_routing_rule_name)
      rule_type = lookup(request_routing_rule.value, "rule_type", "Basic")

      http_listener_name         = lookup(request_routing_rule.value, "http_listener_name", local.pb_listener_name)
      backend_address_pool_name  = lookup(request_routing_rule.value, "backend_address_pool_name", null)
      backend_http_settings_name = lookup(request_routing_rule.value, "backend_http_settings_name", null)
      url_path_map_name          = lookup(request_routing_rule.value, "url_path_map_name", null)
      # redirect_configuration_name = lookup(request_routing_rule.value, "redirect_configuration_name", null)
      # rewrite_rule_set_name       = lookup(request_routing_rule.value, "rewrite_rule_set_name", null)
    }
  }

 
  depends_on = [azurerm_role_assignment.key_vault_role]

}

Can someone help me on this?



Solution 1:[1]

This role assignment is wrong (i.e. not doing what you want to do): resource "azurerm_role_assignment" "key_vault_role"

What you want do add is a Key Vault access policy: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_access_policy

Beware: You need to remove the one access policy that you already have defined in your Key Vault resource and make this a distinct key_vault_access_policy resource, too. You can't mix those two ways to create access policies.

See for instance here for a complete example. Make sure to add an explicit dependency on our resource "azurerm_key_vault_certificate" "https_cert" for the first access policy (example).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 silent