How to pull an Azure Keyvault Secret to an App Service using a Private Endpoint
Prerequisites
In order to use a private endpoint on our keyVault to pull secrets we need a few things.
- A Keyvault
- A Vnet with 2 subnets
- You can use 2 different Vnets, but you will need peer the 2 Vnets to allow traffic through it.
- An App Service
- We will not be configuring NSGs or UDRs as they can break the configuration if configured incorrectly and this is a simple 101 on the subject.
NOTE
We need an app service plan of Basic or higher to use Vnet integration. As documented here.
We also will be keeping everything in 1 region as to not require a gateway for our Vnet.
And we will not be customizing the DNS on the App service or Vnet.
Setup
We have our Vnet Setup
And our other services have just been deployed with no special configuration.
Creating a KeyVault Secret
- Open the Keyvault > Secrets > Generate/Import
- Enter your Secret name and Value > Create
Configuring the Keyvault
NOTE: Disabling public access may inhibit your ability to create secrets later. Allow from specific Vnets will be more flexable to work with.
NOTE 2: Disabling public access only blocks the public endpoint of the KeyVault. These settings do not apply to the Private Endpoint. So setting selected networks will not allow only certain IPs to the private endpoint.
- Open the KeyVault > Networking
- Disable Public Access and Apply
- Move to the ‘Private Endpoint connections’ Tab at the top of the section > Create
- Name your PE > Next
- Link the PE to the keyvault we want to connect to > Next
- Configure the Vnet and Subnet you want the private endpoint in and skip the rest > Next
- Leave the ‘Integrate with private DNS zone’ set to Yes > Next
- You can skip the Tags section unless you need it > Next
- Then Create the Private Endpoint
Setup Vnet Integration on the App Service
- Open your App Service > Network > Vnet Intergration > Add VNet
- Configure the Vnet intergration into the Vnet we setup previously. You also are able to create a subnet in this menu if it hasn’t been created.
- Vnet route all is not required for this as it will allow public IPs to bypass the Vnet, however the private DNS should return a local IP.
Grant App Service Permission to Pull Secrets
In order to grant permission we will be using System Assigned Managed Identity. It is slightly easier to configure than the User Assigned variant.
- Open the App Service > Identity > On > Save
- Open Keyvault > Access Control (AIM) > Add
- Search for “Secret” > And Select “Key Vault Secrets User” > Next
- Select “Managed Identity” > “+ Select Members” > App Service > select your App Service you turned Managed Identity on for > Select
- Select “Review + Assign” Twice
Create an App Setting to pull the KeyVault Value
NOTE: This is the value we will be adding to the App Service. Note if you add a version after the secret name it will not automatically pull a new value every 24 hours.
@Microsoft.KeyVault(SecretUri=https://<KeyvaultName>.vault.azure.net/secrets/<SecretName>/)
- Open your App Service > Configuration > “+ New application setting”
-
- For the name, use whatever you would like
- For the Value we need to use the following string updated for your values.
- @Microsoft.KeyVault(SecretUri=https://KeyvaultToSecure.vault.azure.net/secrets/MySecretToPull/)
- Please replace the keyvault name and secret name marked in bold for your values
- Hit “OK” To submit this change
- Click “Save” to apply the changes to the app service and restart the instance.
Finishing UP
At this point your App Service should restart and attempt to pull from the KeyVault. If everything has been followed. After refreshing the app settings you should see a little green checkmark next to your secret value showing it has been pulled successfully. If it’s a red X you can click the value and see the error it presents at the bottom of the new window.
Please note KeyVault secrets only update once every 24 hours. If you need to force a refresh of a Secret in the app service, the only option is to add a throwaway Configuration value to the app service and save it to force a restart. A normal app service restart does not make the app pull a new value and it will use the cached value. The setting can be any value you want, and you can update the value for future forced updates.