Skip to content
Go back

Azure Config as Code

Published:

If you’ve read any of my other posts, you’ll know that I am a fan of Azure App Configuration. I’ve specifically spoken about its use for Feature Flag management in my feature flag what and why and TBD feature flagging posts.

It is a great tool for managing both configuration and feature flags, and something that I have been working with development teams on recently to implement. Lately we’ve been discussing using it as the main store for an application, including tenant information that will be used with FinBuckle, and this raised some questions about how to properly manage it.

The Problems

Firstly, when managing it, you have to go into the Azure Portal, go to the resource and then manage the values directly. This is okay for a small number of values or if you have simple values. As mentioned, we want to use it for the main store for an application, and we therefore want to be able to store complex values just as JSON objects. On top of this, there is no real way to version within it, yes, you can take snapshots and add tags, but it’s not really version control.

Secondly, there is no way to control the network access, it’s open or closed, not ideal when you want to have it private but also be able to manage it.

These points make it feel not very enterprise-ready, whilst a brilliant tool. We also use API Management, and therefore use APIOps 🔗 and this is where the inspiration came from…

The Solution

I want to make managing App Configuration as easy as possible whilst supporting:

and making it enterprise-ready.

To do this, I created Azure Config as Code 🔗. This is a template that can be cloned into your own environment to help manage App Config in a code style.

What does it do?

It covers a few elements to enable you to properly manage your App Config:

Configuration as Code

Store your application configuration in version-controlled JSON files, which can then support complex values. A file is created for each environment, allowing you to separately manage each environment, as they will have different values.

The files are stored within a schema I have created which supports the following types:

The Feature Flag and Key Vault types are specific to support the import of Feature Flags, and Key Vault references, meaning all aspects can be stored in Git.

Flattening Complex Structures

From the configuration as code, it then is flattened into a KVSet format which can then be imported into App Config. As part of this, it can automatically flatten complex structures such as JSON objects and arrays to allow them to be stored in App Config safely. However, as they are stored as a complex object in Git, you can edit them properly and manage them. This takes something like:

{
    "key": "Finbuckle:MultiTenant:Stores:ConfigurationStore:Tenants",
    "value":
        [
            {
                "Id": "910eb0bf-6a57-454b-8458-f3e299591684",
                "Identifier": "910eb0bf-6a57-454b-8458-f3e299591684",
                "Name": "Test1",
                "Keys": [
                    {
                        "Name": "TestKey1",
                        "Value": "53d9262b-a83a-4f31-b4bc-213187a59eb2"
                    }
                ]
            },
            {
                "Id": "b987448b-5418-4ef8-8a71-f55ea16cf156",
                "Identifier": "b987448b-5418-4ef8-8a71-f55ea16cf156",
                "Name": "Test2",
                "Keys": [
                    {
                        "Name": "TestKey2",
                        "Value": "8327d419-f013-490e-8466-8fb6f0a5a15e"
                    }
                ]
            }
        ],
    "type": "json"
}

and converts it to the following KVSet object with serialised JSON Values:

{
    "key":  "Finbuckle:MultiTenant:Stores:ConfigurationStore:Tenants",
    "value":  "[{\"Id\":\"910eb0bf-6a57-454b-8458-f3e299591684\",\"Identifier\":\"910eb0bf-6a57-454b-8458-f3e299591684\",\"Name\":\"Test1\",\"Keys\":[{\"Name\":\"TestKey1\",\"Value\":\"53d9262b-a83a-4f31-b4bc-213187a59eb2\"}]},{\"Id\":\"b987448b-5418-4ef8-8a71-f55ea16cf156\",\"Identifier\":\"b987448b-5418-4ef8-8a71-f55ea16cf156\",\"Name\":\"Test2\",\"Keys\":[{\"Name\":\"TestKey2\",\"Value\":\"8327d419-f013-490e-8466-8fb6f0a5a15e\"}]}]",
    "content_type":  "application/json",
    "tags":  {
    }
}

Version Control and Rollback

The files are all stored in Git, so naturally you can use Git to version control them and track the changes, as well as support pull requests for proposed changes.

On top of this, the pipeline templates are set up to create an immutable rollback point by publishing the flattened KVSets as build artifacts. These can then be retained and used to rollback to previous versions as needed.

Network Access Control

Now, to say that this template fixes this is a bit of a stretch. Instead, what it does is setup the framework to allow you to implement this using your own DevOps Agents. Realistically, if you are working in a private environment, you will have, or want to have, private DevOps Agents within your network. This will allow them to access the App Config instances over private networking. The templates are also set in such a way to allow you to use a different pool for each stage/environment, and therefore allow you to have different access levels for each.

Dry Run and Approval

The pipelines also include a step to carry out a dry run import of the configuration. This then returns a list of what changes are going to be made, allowing a manual check before pushing. To further enhance this, a manual approval step is included to allow appropriate approvers to be notified and be required to approve the changes.

Get Started

If this is something that you are interested in using, you can head over to the GitHub Repo 🔗 and clone the repository.

From here you will need to update the pipeline variables to suit your environment. Use the dev.json file in the config folder as a guide for creating your own config files.

Import the pipelines into your DevOps environment, and you should be good to go.

Conclusion

This is a template that I have created to help the management of App Configuration in a code style. It doesn’t replace the Azure Portal, but it does make it a more enterprise-ready solution that can be managed using CI/CD.

I have some additional features that I plan to add to this over the coming weeks, so stay tuned! If there is something specific that you’d like to see it do, feel free to raise an issue on the GitHub repo.


Share this post on:

Next Post
Feature Flags in Trunk-Based Development