'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 |
