Transactionally update Azure App Configuration

Nick Lydon
2 min readJan 6, 2022

We’ve elected to use azure app configuration in order to be able to adjust settings without needing to redeploy the whole app. What we didn’t want to do, was adjust these values via a web UI. This would be risky, because we would lose change control and versioning history.

The ideal workflow would be:

  1. Commit the config changes to a repo.
  2. Open a pull request.
  3. Have an automated process (in our case an azure devops pipeline) push the new values to azure app config.

That last step presents some difficulties, as the API handles updates on an individual key-value pair basis. Ideally the whole config would be replaced in one atomic transaction, similar to a http put request. Otherwise there’s the risk that the app would pull a mixture of updated and outdated config. We also don’t want old, unused settings lingering in the app config, causing confusion for unlucky future developers.

The solution to these problems is to use what the documentation calls a sentinel key. The app watches this single key, and when the value is updated, it reloads all the config at once. This will allow us to delete all of the existing config values, set the new values one-by-one, and then finally update the sentinel to let the app know that all of the new values are ready to be fetched.

Let’s take a look at the pipeline:

The first task takes a unique value (in this case we use the incrementing build number), and passes it to a script, which writes it in a json file to disk. Here’s how the json looks like given the build number 123: {“AzureAppConfig:TriggerAllRefreshSentinel": 123}.

The second task pushes a json file containing KeyVault references, and the third task pushes the remaining non-secret app configuration values. The reason these need to be split is that a special content-type needs to be set for the KeyVault references. Notice that the two types of config need a different label applied. This is because the Strict flag causes the existing values with that label and key-prefix to be deleted (necessary to ensure that key-value pairs that we’ve removed from our json config files are also deleted from azure). If they shared a label, task three would delete all of the values that had just been set in task two!

Finally, the fourth task pushes the config file that was created in the first task. The watching app will now notice that this sentinel key’s value has changed and pull the rest of the config as a result.

The last piece of the puzzle is the actual configuration in code:

--

--

Nick Lydon

British software developer working as a freelancer in Berlin. Mainly dotnet, but happy to try new things! https://github.com/NickLydon