Keyvault secrets can be used in Azure app conciguratoins and can be setup with terraform. However, if the secret is modified then modified secret reference is not get updated to the app configuration. There are two ways to fix this issue in terraform. Let's explore them.
First let's look at the problem.
Consider below secrets defined in terraform for keyvault.
# Secrets
resource "azurerm_key_vault_secret" "secret" {
for_each = {
AzureWebJobsStorage = azurerm_storage_account.demo.primary_connection_string
SqlDBPwd = azurerm_mssql_server.demo.administrator_login_password
}
name = each.key
value = each.value
key_vault_id = azurerm_key_vault.instancekeyvault.id
depends_on = [
azurerm_key_vault.instancekeyvault
]
}
To refer these in the app configuration we can defined them as below.
resource "azurerm_app_configuration_key" "config_vault" {
for_each = {
"AzureWebJobsStorage" = azurerm_key_vault_secret.secret["AzureWebJobsStorage"].id
"SqlDBPwd" = azurerm_key_vault_secret.secret["SqlDBPwd"].id
}
configuration_store_id = azurerm_app_configuration.appconf.id
key = each.key
type = "vault" # keyvault reference
label = azurerm_resource_group.instancerg.name
vault_key_reference = each.value
depends_on = [
azurerm_role_assignment.appconf_dataowner
]
}
The problem of this appraoch: As explained above the azurerm_key_vault_secret.secret["SqlDBPwd"].id is giving the keyvalt reference with the version id. So that the app config will store the value in below format. The Guid represents the version of the keyvault secret.
https://keyvaultname.vault.azure.net/secrets/SqlDBPwd/15061a22c4284082bf0c6e8f3f7cb501
When the the secret value is changed for SqlDBPwd the terraform for keyvault will udate the secret vaule in keyvault which will have a diffrent GUID. However, this is not getting updated to the app config if we use the above terraform code to set the app configuration values.
The Solution - Option One - Not so good
One option to fix the issue is refer the keyvault secret as data in terraform as shown below and get it applied to the app configuration.This will ensure the new version changes in keyvault secret for SqlDBPwd is always get applied to app configuration.
# Secrets
resource "azurerm_key_vault_secret" "secret" {
for_each = {
AzureWebJobsStorage = azurerm_storage_account.demo.primary_connection_string
SqlDBPwd = azurerm_mssql_server.demo.administrator_login_password
}
name = each.key
value = each.value
key_vault_id = azurerm_key_vault.instancekeyvault.id
depends_on = [
azurerm_key_vault.instancekeyvault
]
}
# Refer SqlDBPwd as data to get updated value
data "azurerm_key_vault_secret" "sqldbpwd" {
name = "SqlDBPwd"
key_vault_id = azurerm_key_vault.instancekeyvault.id
depends_on = [
azurerm_key_vault_secret.secret
]
}
resource "azurerm_app_configuration_key" "config_vault" {
for_each = {
"AzureWebJobsStorage" = azurerm_key_vault_secret.secret["AzureWebJobsStorage"].id
"SqlDBPwd" = data.azurerm_key_vault_secret.sqldbpwd.id
}
configuration_store_id = azurerm_app_configuration.appconf.id
key = each.key
type = "vault" # keyvault reference
label = azurerm_resource_group.instancerg.name
vault_key_reference = each.value
depends_on = [
azurerm_role_assignment.appconf_dataowner
]
}
If we need to have same for other secrets we need to define data blocks for each secrets. This would mean lot of unneccessary complexity to code.
The Solution - Option Two
Use of
versionless_id is the best option. Then each of the secret of keyvault will be referred without version in below format.
https://keyvaultname.vault.azure.net/secrets/SqlDBPwd
# Secrets
resource "azurerm_key_vault_secret" "secret" {
for_each = {
AzureWebJobsStorage = azurerm_storage_account.demo.primary_connection_string
SqlDBPwd = azurerm_mssql_server.demo.administrator_login_password
}
name = each.key
value = each.value
key_vault_id = azurerm_key_vault.instancekeyvault.id
depends_on = [
azurerm_key_vault.instancekeyvault
]
}
resource "azurerm_app_configuration_key" "config_vault" {
for_each = {
"AzureWebJobsStorage" = azurerm_key_vault_secret.secret["AzureWebJobsStorage"].versionless_id
"SqlDBPwd" = data.azurerm_key_vault_secret.sqldbpwd.versionless_id
}
configuration_store_id = azurerm_app_configuration.appconf.id
key = each.key
type = "vault" # keyvault reference
label = azurerm_resource_group.instancerg.name
vault_key_reference = each.value
depends_on = [
azurerm_role_assignment.appconf_dataowner
]
}
This will ensure latest version of keyvault secret is always referred by the app configuration so that your application will always obtain the latest version of secret value.
No comments:
Post a Comment