Search code examples
javaspring-bootazurespring-cloud

Override properties from Azure App Configuration Store


TL;DR

How to have system properties on CLI or environment variables override properties that are provided by an Azure App Configuration Store? Or is this maybe not possible at all?

Longer story

Let us assume a property named app.prop. Let us further assume the following entry in application.yml or in application-<profile>.yml:

app:
    prop: Default

Usually, you are able to start the Spring Boot application and provide a system property (e.g. -Dapp.prop=SYS) or an environment variable (e.g. export APP_PROP=ENV) with the effect that the latter overrides the value of the YML config files. If you - for example - provided the environment variable, your application has the value ENV for the property app.prop.

When reading the same property from an Azure App Configuration Store, you can provide a system property or an environment variable as you like. But the value is not overridden anymore; it is the value that is stored in the Azure App Configuration Store.

Some code

I am using Spring Boot version 2.5.7:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.7</version>
</parent>

Further, I am using the following library for accessing the Azure App Configuration Store:

<properties>
    <azure-spring-cloud.version>2.7.0</azure-spring-cloud.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.azure.spring</groupId>
            <artifactId>azure-spring-cloud-dependencies</artifactId>
            <version>${azure-spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>azure-spring-cloud-appconfiguration-config</artifactId>
    </dependency>
</dependencies>

Additionally, for starting the application, I am providing the following property:

spring.cloud.azure.appconfiguration.stores[0].connection-string = ...

This all works very well. In the Azure App Configuration Store, I have the following property:

app.prop = Azure

If now starting the application with the following environment variable APP_PROP = ENV, the value of the property app.prop is still Azure, and not ENV.

Is there any setting missing, so that I can have the same behavior that I had without the above mentioned library?

Actually, I searched a lot, but did not find anything except for some statements regarding overriding values of remote properties in the Spring Cloud documentation, which is not really my case (I am using Azure App Configuration Store).


Solution

  • The whole point of using Azure App Configuration is to store your config in one place and easily manage it without redeploying / restarting the app. Therefore I don't think this is should be even possible.

    I would recommend to use labels to load specific version of your prop based on labels data. Few cases:

    1. If you need this property only locally, don't specify it in App Configuration.
    2. If you need multiple versions of it, then just create same property with multiple labels and use your spring.profile (or other conf-property) to distinguish the version.
    3. If you need to load multiple versions of it, load multiple labels:
      As described here: https://learn.microsoft.com/en-us/java/api/overview/azure/spring-cloud-starter-appconfiguration-config-readme?view=azure-java-stable#load-from-multiple-labels

    You can use this sample to see how it works: https://github.com/Azure/azure-sdk-for-java/tree/azure-spring-boot_3.6.0/sdk/appconfiguration/spring-cloud-starter-azure-appconfiguration-config