Introduction
How do you improve your efficiency as a programmer? Well... besides good sleep and healthy lifestyle I use scripts! Let`s just jump straight into the problem.
Typical commands to get settings from Azure Function instance
Usually when you want to test function locally, but with the same settings as used in your cloud instance, you have to invoke one the following commands:
az functionapp config appsettings list --name myFunctionAppName --resource-group myFunctionAppResourceGroupName
to print it out into the console (but it prints out the settings in a different format than used in local.settings.json
file), or:
func azure functionapp fetch-app-settings myFunctionAppName; func settings decrypt
in order to fetch them into your local.settings.json
file (but the file should aready be in the directory you are invoking the command in, because otherwise the command will complain about it).
Problem with that approaches
Both of them, while totally useful, need some additional, manual steps and have one main inconvenience for me:
In a project I`m working with, I have most of the common configuration stored in Azure Key Vault, so the output for my local settings doesn`t have actual values in it, but references (which apparently don`t work locally). It looks somewhat like the following (depending on the command you`ve used):
"MySetting": "@Microsoft.KeyVault(SecretUri=https://nameOfMyKeyVault.vault.azure.net:443/secrets/MySetting/versionOfTheKey)",
So if I would like to run the function locally with the same settings as in the cloud, I would have to go into Key Vault and get the settings from there one by one (which takes a fair amount of time).
Solution
I have created a script that simply gets all the settings, identifies values that are referencing to Key Vault and replaces them with actual latest value available for a particular key. The result is printed out into the console and doesn`t assume there is a local.settings.json
file beforehand, so we can invoke it from anywhere.
param (
[String]$rgName = "myFunctionAppResourceGroupName",
[String]$fnName = "myFunctionAppName",
[String]$kvName = "myKeyVaultName"
)
$azAppSettingsOutput = az functionapp config appsettings list --name $fnName --resource-group $rgName | ConvertFrom-Json
$OutputConfig = New-Object -TypeName PSObject
foreach($setting in $azAppSettingsOutput) {
$value = $setting.value
if ($value -match '.*/secrets/(.+)/.*') { # checks if it is a key vault reference
$keyVaultKey = $matches[1]
$value = (az keyvault secret show --vault-name $kvName --name $keyVaultKey | ConvertFrom-Json).value
}
$OutputConfig | Add-Member -MemberType NoteProperty -Name $setting.name -Value $value
}
$OutputConfig | ConvertTo-Json
In order to use that, simply copy the content into a file with ps1
extension (like fetchFuncSettings.ps1
) and ivnoke it with correct parameters, in example:
.\fetchFuncSettings.ps1 -rgName myFunctionAppResourceGroupName -fnName myFunctionAppName -kvName myKeyVaultName
The output should look like the following:
{
...
"MySetting": "MyValueFromKeyVault"
...
}
After that, you can just copy the output from the console and use in your local.settings.json
file accordingly.
Summary
Nowadays it may be a better idea to use Azure App Configuration service to share settings between functions, but if you are not using it yet, you may suffer from the same pain as I did.
That simple script saves me a lot of time during my daily work with Functions referencing to Key Vault. Hopefully it will help you to save some precious time as well.
Good luck 馃檪
Grzegorz
Thank you, for this script. It is really helpful 馃槈
Dawid Chr贸艣cielski
Cheers Grzegorz! 馃檪
Bruno
Very helpful! It saves me a lot of time, thanks a bunch!
Dawid Chr贸艣cielski
Thanks for the comment! Have a good time with functions 馃檪
Miko艂aj Wo藕niak
where should I transfer the money?
Dawid Chr贸艣cielski
https://www.savethechildren.org would be okay 馃槈
Arun kumar
Many thanks Dawid – very useful 馃檪