Secret Management in .Net Core Application using Azure Key Vault and Azure DevOps Service — PART 3
This is the last article in 3 parts series of secret management in .Net Core. Previously in Part1 and Part2 we have discussed about how to manage application secrets in development and production environment using Secret Manager and Azure Key Vault. In this final discussion we will focus on managing secrets in Azure DevOps pipelines with release variables, variable group and how to integrate pipelines with Azure Key Vault.
Demo Project Setup
To start with I have moved the sample project to Azure DevOps Repos and created a build and release pipeline.
Also I have created the required infrastructure in Azure. It includes App Service, SQL Server, SQL database and Key Vault.
I have executed the pipelines and run the demo app and it working fine:
Storing secrets in Release Pipeline Variable
In Part2 of the series we have removed connection string from the appsettings.json and access them through secret manager in development environment and through Azure Key Vault in production. But what about other application settings which we may need to provide during the time of deployment. These settings need to configured in release pipelines. To do so we will use features provided by Azure DevOps service.
As we can see there are no values provided for “ConnectionStrings”. Also, there is another setting added i.e. “KeyVaultName”. This will provide the uri for azure key vault.
This “KeyVaultName” setting is used in Program.cs file to provide the root uri for key vault:
We will see how we can provide this value from Azure DevOps pipelines.
For the demo I have changed the value for appsettings “KeyVaultName” to “https://localhost.vault.azure.net/” in code, deployed it and now the application has stopped working.
Now we will update this value through release pipeline variable
First we will go to the release tab in Azure DevOps Service project:
Next we will click on Edit button to make changes to release pipeline:
Now we will got to Variables tab:
We will add a new variable here:
We will add the variable with name “KeyVaultName” and then add the actual uri of Azure Key Vault
When we hover on the variable we can see this lock icon, it will mask the value of secret:
Now click the Save button and Create the Create release:
New release will deploy the code again to App Service with updated config values:
Now when we open the application again in browser we will see its up and running:
To view the changes we go to App Service Configuration tab:
Here we can see Application settings value contains “KeyVaultName” but its value is hidden. We need to click the Value to verify.
As we can see the actual value of key vault uri is updated.
Using Pipeline variable groups for storing Secrets
The approach above can be useful for variable which doesn't require high degree of security and can be changed by anyone. But there is more centralized approach available in Azure DevOps Service to manage the secrets in pipelines i.e. pipeline variable groups.
Go to library tab in Azure DevOps Service under the pipelines. This is where we can create a group of variable which can be used across multiple pipelines:
Lets create a variable group and give it a name “SecretsGroup” and create a variable in it:
The name of variable is different than one we provided previously but it contains the actual value of secret.
Next to the secret value there is a lock button it is used to store the value as encrypted secret.
Now apart from sharing secrets across the pipelines, we can also set security on the library so that we can provide service principals to roles that range from being able to manage security items to only reading them to the user role, which only allows for consuming library items in a pipeline
Now Save this variable group and the new secret.
Lets got back to the release pipeline and click on Variables tab:
Next click on variable groups
Now we need to link the variable group to this particular release pipeline.
Point to note here is we can have multiple variable groups here and we can scope their access to the entire release or a particular stage. Now click link and Save the changes
Now the secrets and variable group are available to the pipeline. Next we will go back to the task tab of the pipeline
We will edit the configuration of App Service, and will update the App Settings value with new Key we created in secret groups which will have a different name than pipeline secrets.
We will Save this and lets update the application in AzureApp Service.
As you can see we have updated the Application Settings in App Service Configurations and provided in correct value. Due to this change the application will stop working.
Next we will create a new release pipeline again, which redeploy the application to App Service and override the application configuration settings
Once the release is complete we can refresh the application settings in Azure and see the value of “KeyVaultName” is updated and now when we run the application it will start working.
Linking Azure Key Vault with Azure DevOps Service
So far we have seen 2 ways to store secret values encrypted in Azure pipelines. This is great for keeping the values out of configuration files Now we will look at the how can we leverage key vault where values are pulled dynamicaaly in to the settings.
First we need to create a new secret in Azure Key Vault which can be accessed by Azure DevOps. So we will open the Secrets tab in secure-secret-vault the key vault which we created.
Next we will generate a new secret by click Generate/Import
Next we will add the name as “KeyVaultNameFromVault”. We would like to keep different name so that we can differentiate between settings.
After providing name and value for the secret we will hit the create button to create the secret.
We can see now a new secret is created and available in vault.
Now to test this scenario we will delete the existing settings from Application Settings and hit save.
With no configuration available application will stop working.
Next we will go to the library tab and open our variable group.
Within the variable group we can see the button to enable linking of Azure Key Vault secrets as variables in Azure DevOps.
Doing this will erase any variables that exist in the variable group.
There is a service connection to the Azure subscription that was created for the pipeline so let’s use that to authenticate.
Now lets select the key vault with the secret we want.
Vault will ask for the authorization which we provide. A pop up window will open to provide credentials. This will enable the get and list permissions on the key vault secrets for the service principal used by the Azure DevOps service connection.
Once the credentials are authenticated it will allow us to select the vault secrets through this Add button.
This will now become the variable for the pipelines that use the variable group
Next we will save these changes.
Now we will go back to the release pipeline and edit it again. We will change the variable name in App settings section and provide the name as per the new secret created in key vault. Next save the changes done to the pipeline.
Once the changes are saved we will create a new release and wait for it to deploy.
After the deployment is complete we can check Application settings section in App service configuration that the value for KeyVaultName is again available with the value configured in key vault. This way eve of the people have access to change pipelines variable still the values can be enforced from key vault.
Linking Azure Key Vault with Azure DevOps Service using Key Vault Task
Lets see another way to to get the secret value from key vault during a pipeline using key vault task. Go back to Azure DevOps and open the Library tab and delink Key Vault from this variable group.
Delinking means it will erase all the key vault variable previously saved in this variable group.
Once delink the key vault from variable group we will just a dummy value here.
Now we will again edit the pipeline and go back to the task.
Now here we will add the new task which is Azure Key Vault task to update the settings here.
first we will select the service connection to Azure and select the Key vault. Remember service connection has required permissions for secrets. In the secret filter we can limit it to one secret or multiple secrets that are relevant to this pipeline.
Now lets the delete the application settings value in app service and application will stop working.
Now back in Azure DevOps we will create a new release and we will let this run
Once its done lets go back to the app service and refresh the application settings page. Now we can see the app settings name and value is available now with new value from Azure Key vault.
Lets refresh the application page and as we can see the application is up and running again.
So this will bring us to end of the series on Secret management with ASP.NET Core, Azure Key vault and Azure DevOps. We have seen different ways how can we manage our secrets in development and production environments.