For Azure Key Vaults access policies based permision setup is now legacy and all key vaults will have to use Azure RBAC permisions eventually for data access permisions according to offcial Microsft documentation here. Using terraform we can setup the changes. However, we have to be carefull about the switching to RBAC from access policies in production scenarios to avoid interptions to applications. Taking two step approach, first set RBAC permisions and in a next release performing switch to RBAC for key vault will help the transtion to be smooth. Let's look at how to setup this requirement with terraform.
The expectation is to have a keyvault setup with RBAC permisions as shown below.
Let's first look at terrraform code used to setup a key vault with access policies based permission.
resource "azurerm_key_vault" "instancekeyvault" {
name = "ch-demo-kv"
location = azurerm_resource_group.instancerg.location
resource_group_name = azurerm_resource_group.instancerg.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
enabled_for_deployment = false
enabled_for_disk_encryption = false
purge_protection_enabled = true
network_acls {
bypass = "AzureServices"
default_action = "Deny"
ip_rules = split(",", local.kv_allowed_ips)
virtual_network_subnet_ids = local.kv_allowed_subnets
}
# Developers
access_policy {
tenant_id = var.TENANTID
object_id = data.azuread_group.devs.object_id
secret_permissions = var.ENV == local.dev_environment ? ["Get", "List"] : []
}
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = local.tenant_appservice_spn_objectid
secret_permissions = ["Get", ]
certificate_permissions = ["Get", ]
}
# IaC service principal
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
key_permissions = ["Get", "Purge", "Recover"]
secret_permissions = ["Get", "List", "Set", "Delete", "Purge", "Recover"]
certificate_permissions = ["Create", "Get", "List", "Delete", "Purge", "Recover"]
}
# Containers in AKS via user assigned identity
access_policy {
tenant_id = var.TENANTID
object_id = azurerm_user_assigned_identity.aks.principal_id
secret_permissions = ["Get", "List", ]
}
}
In above setup the keyvault will be using access policies to grant permisions to data pane objects keys. secrets and certificates.
Step1/Release1
While keeping above access policies based keyvault permisions, now we can as the first step/release add RBAC permisions equivalent to existing access policy based permisions. Note that we have to add roles sperately for same spn or user to match with the access policy permission setup. List of roles available can be found here in the documentation.
# Developers as secrets users in dev
resource "azurerm_role_assignment" "kv_devs_secret_user" {
count = var.ENV == local.dev_environment ? 1 : 0
scope = azurerm_key_vault.instancekeyvault.id
role_definition_name = "Key Vault Secrets User"
principal_id = data.azuread_group.devs.object_id
}
resource "azurerm_role_assignment" "kv_webapp_spn_secret_user" {
scope = azurerm_key_vault.instancekeyvault.id
role_definition_name = "Key Vault Secrets User"
principal_id = local.tenant_appservice_spn_objectid
}
resource "azurerm_role_assignment" "kv_webapp_spn_cert_user" {
scope = azurerm_key_vault.instancekeyvault.id
role_definition_name = "Key Vault Certificate User"
principal_id = local.tenant_appservice_spn_objectid
}
# Service principal for IaC as Key Vault Administrator - all data plane operations
resource "azurerm_role_assignment" "kv_iac_spn_admin" {
scope = azurerm_key_vault.instancekeyvault.id
role_definition_name = "Key Vault Administrator"
principal_id = data.azurerm_client_config.current.object_id
}
# Containers in AKS via user assigned identity
resource "azurerm_role_assignment" "kv_aks_uai_secret_user" {
scope = azurerm_key_vault.instancekeyvault.id
role_definition_name = "Key Vault Secrets User"
principal_id = azurerm_user_assigned_identity.aks.principal_id
}
With above when we deploy the key vault without any other change it will just add the RBAC permissions to key vault. But still the keyvault is using access policies to grant data pane operation permissions.
Once this is deployed to production we can move on with step 2.
Step2/Release2
In the step 2 we can set the keyvault to use the RBAC permisions and remove access policies as shown below. Now when the switch to RBAC for KV happens in the system in production, the RBAC permisions equivalent to previous access policy based permisions are already there in place. So there will be no down time for the applications due to the permission model of the keyvault is changed from access policies to RBAC. Key change is setting the rbac_authorization_enabled = true and removing access policies.
resource "azurerm_key_vault" "instancekeyvault" {
name = "ch-demo-kv"
location = azurerm_resource_group.instancerg.location
resource_group_name = azurerm_resource_group.instancerg.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
enabled_for_deployment = false
enabled_for_disk_encryption = false
purge_protection_enabled = true
rbac_authorization_enabled = true
network_acls {
bypass = "AzureServices"
default_action = "Deny"
ip_rules = split(",", local.kv_allowed_ips)
virtual_network_subnet_ids = local.kv_allowed_subnets
}
}
After the deployment the key vault will be using RBAC permisions as shown below.
No comments:
Post a Comment