While working with Azure Functions quite often we need to interact with SQL database, message queuing service or authenticate to an API. Azure Function App Service has application settings where we can store the connection strings or other credentials. Then it’s easy to read and use those settings directly in the Azure Function code. While our Azure solutions become more complex, we naturally need more control over how and where to store the credentials securely. Azure Key Vault provides us a centralized repository for your keys and secrets (passwords, connection strings, API keys, etc.).
In this post, I’d like to show you how to put a SQL server connection string to Azure Key Vault secret and use it in Azure Function. Thanks to the Managed Service Identities this setup has become much easier and more straightforward as before.
Azure Key Vault is a secured place, so before our Azure Function App can ask a secret from the Key Vault a few other things are necessary to set up. Firstly, we’ll need to enable system managed identity in Azure Function App and then we’ll need to add Access policy for this service in Azure Key Vault. The schema below describes all the ordered steps to achieve it.
Let’s look closer to those steps in the following chapters.
Enabling system managed identity in Azure Function App
Azure Key Vault can work only with cloud services having a system managed assigned identities. By other words, Key Vault does not know our Function App unless we enable identity on it.
Firstly, we’ve created the Azure Function App Service (we’ve called it functionapp-demo-mw). Now to enable the managed identity, open Azure Function App and on the Platform features tab and select Identity.
Then on the Identity settings, change the status to On and Save the changes.
From that moment, our Azure Function App has assigned system managed identity which is “visible” for Azure Key Vault.
Adding Key Vault Access Policy to Function App principal
Azure Key Vault cannot be used by another cloud service unless an access policy is defined for that service.
In our demo, I’ve created Azure Key Vault called keyvault-demo-mw. Now we’re going to define access policy so our Function App service can retrieve the secret from the Key Vault.
Firstly, open the Azure Key Vault service and from the Settings menu select Access policies. Then select + Add new access policy.
Then choose Select principal and search for the name of the Function App (functionapp-demo-mw in our case). Thanks to the identity we’ve assigned to Azure Function App before, the functionapp-demo-mw appears in the list of principals so we can select it and assign permissions.
Once your principal is selected choose the Secret permissions menu. In our case, we’ll only need to get the secret from the Key Vault (concretely read our connection string). Therefore, check Get permission only and then select OK.
At the end, select Save to store the new functionapp-demo-mw access policy.
Adding secret to Azure Key Vault
Adding a secret to Azure Key Vault is straightforward. From the Key Vault, Settings menu select Secrets and then select + Generate/Import secret.
For Key Vault secret two values are required – name and the value. In our case we’ve called our secret OrderManagementDbConnectionString and as a value we put our SQL server connection string. Select Create to save the secret.
By default, the secret is Enabled so it’s ready to use. Once the secret is created, we’ll need to get its URI (a unique location identifying the secret). Go to the Settings menu and select Secrets. We’ll find here our recently added secret (OrderManagementDbConnectionString). Select the secret and we’ll see it’s the only version in the list.
Select the current version of secret and copy its secret identifier. The identifier is an URI with pattern : https://<url_of_the_key_value>/<secret_name>/<secret_version>.
Now we have our secret identifier and Azure Function App get secret from Azure Key Vault so let’s use it in our Azure Function App.
Getting secret from Key Vault in Azure Function App
We’ll go back to our Azure Function App (functionapp-demo-mw) and on the Overview tab, select Configuration in Configured featured section.
Well, Select + New application settings. Put a name that describes the new setting (we’ve put OrderManagementConnectionString). At the end of the last year, Microsoft has added an option of sourcing Key Vault secrets directly from App Settings. This simplifies a lot the way how the secrets were used before. So, set the value of the setting to a secret reference in the following format:
We just need to replace secret_uri_with_version with the value we’ve previously copied from the secret in Azure Key Vault.
In our Azure Function we’ll just retrieve the value from the application settings and work with it the same way as it was directly a connection string stored in application settings.
// get value from appliction settings
var connectionString = Environment.GetEnvironmentVariable("OrderManagementConnectionString");
// create connection
SqlConnection connection = new SqlConnection(connectionString);
Finally, we’ll test our function. It returns a list of products from OrderManagement database.
The Azure Function has transparently obtained connection string via @Microsoft.KeyVault sourcing directive in the application settings. There is no need to install all the NuGet packages and write a code to retrieve a secret from KeyVault.
Azure Key Vault is a good place to keep our application credentials in a secured and centralized manner. Moving the secrets to Key Vault becomes even more important while our Azure solution is growing. The way how we can use the secrets in our applications through the secret sourcing enables a developer to concentrate on the essential work rather than doing a lot of infrastructure coding.