Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Configuration references in App Configuration #852

Open
itsdani opened this issue Dec 19, 2023 · 6 comments
Open

App Configuration references in App Configuration #852

itsdani opened this issue Dec 19, 2023 · 6 comments
Labels
enhancement New feature or request

Comments

@itsdani
Copy link

itsdani commented Dec 19, 2023

Currently App Configuration supports adding Azure Key Vault references, and the providers can resolve those values. Azure App Service configuration also supports references like this, but it works with both Key Vault references and App Configuration references.

We would like to have App Configuration references to other App Configuration values, so basically we would like to create aliases inside App Configuration.

The use case is that we have some configuration values that are used by multiple applications and we would like to specify these values at a single place (so if we need to change it, we don't have to find all the configs and modify all of them). An example of this could be the URL of a service endpoint that is used in multiple applications.
On the other hand, we would like to use hierarchic namespaces (or use another App Configuraton for each app) to group the configs of an app. So in the example, we would specify the URL in an app config, and in the application-specific config we would reference that one value as the single source of truth.

Example App Config reference:

{
    "key": "my-application:weather-api-url",
    "label": null,
    "value": "{\"uri\":\"https://my-app-configuration.azconfig.io/configs/weather-api-url\"}",
    "content_type": "application/vnd.microsoft.appconfig.appconfigref+json;charset=utf-8",
    "tags": {}
}
Main config value
{
    "key": "weather-api-url",
    "label": null,
    "value": "https://weather-service.com/api/",
    "content_type": "",
    "tags": {}
}
Similar Key Vault reference
{
    "key": "my-application:weather-api-url",
    "label": null,
    "value": "{\"uri\":\"https://my-keyvault.vault.azure.net/secrets/weather-api-url\"}",
    "content_type": "application/vnd.microsoft.appconfig.keyvaultref+json;charset=utf-8",
    "tags": {}
}

Compared to a Key Vault reference, the content type would use appconfigref instead of keyvaultref, and the uri in the value would point to an App Config value.

@RichardChen820
Copy link
Contributor

RichardChen820 commented Dec 26, 2023

@itsdani An App configuration is intended to centralize the management of configurations. Your apps could refer to a single config item for the same value.

If you want to group your configurations for multiple apps, you could consider to use keyPrefix or label . https://learn.microsoft.com/en-us/azure/azure-app-configuration/howto-best-practices#key-groupings

Give label grouping as an example, you could label the common configuration that can be used across all apps with "common"

{
   “key”: “weather-api-url",
   "label": "common"
   "value": "https://weather-service.com/api",
   "content_type": "",
    "tags": {}
}

Can label the app-specific configuration with appName.

{
   “key”: “api-version",
   "label": "app1"
   "value": "1.0",
   "content_type": "",
    "tags": {}
}

{
   “key”: “api-version",
   "label": "app2"
   "value": "2.0",
   "content_type": "",
    "tags": {}
}

In app1, you could select the common and app1 label.

.Select(key="*", label="common")
.Select(key="*", label="app1")

In app2, you could select the common and app2 label.

.Select(key="*", label="common")
.Select(key="*", label="app2")

@drago-draganov
Copy link
Contributor

@itsdani

Thank you for your suggestion! AppConfiguration is indeed looking into enabling internal and external configuration references. I can think of multiple scenarios where these can be quite useful.

Though, I don't have ETA at the moment, I would like to share a few thoughts regarding that:

  • Reference of a single key-value (ex. key=app1/setting1) - this is simple and straightforward to resolve. The final key name is local, while the value is where the reference points (1 to 1 mapping).
  • Reference of a set (ex. key=default/*) - this is bit more complicated. To follow the approach above, the final key names should be composition between the local key plus referenced keys. It's unlikely that simple concatenation will do it. Perhaps some prefix trim is necessary. The caller may not necessarily anticipate the final outcome.
  • Circular references - self-explanatory. Detection and error handling at setup.
  • Reference to a reference chain - breaking of the chain. Depth.
  • Reference to non-existing/deleted setting.
  • Dynamic refresh on referenced value changes.

Let me know your thoughts as well.

On a side note, regarding simplified configuration composition, have you checked AppConfiguration Snapshots? It may help to address certain hierarchical models as well.

@RichardChen820
Copy link
Contributor

RichardChen820 commented Jan 2, 2024

Instead of using label, keyPrefix should be suitable for hierarchic namespaces given that we don't support configuration reference yet.

You could group the common configuration that can be used across all apps with "common" prefix

{
   “key”: “common/weather-api-url",
   "label": null
   "value": "https://weather-service.com/api",
   "content_type": "",
    "tags": {}
}

Can group the app-specific configuration with appName.

{
   “key”: “app1/api-version",
   "label": null
   "value": "1.0",
   "content_type": "",
    "tags": {}
}

{
   “key”: “app2/api-version",
   "label": null
   "value": "2.0",
   "content_type": "",
    "tags": {}
}

In app1, you could select the common and app1.

.Select(key="common/*")
.Select(key="app1/*")
.TrimKeyPrefix("common/")
.TrimKeyPrefix("app1/")

In app2, you could select the common and app2 .

.Select(key="common/*")
.Select(key="app2/*")
.TrimKeyPrefix("common/")
.TrimKeyPrefix("app2/")

@RichardChen820
Copy link
Contributor

@itsdani

Thank you for your suggestion! AppConfiguration is indeed looking into enabling internal and external configuration references. I can think of multiple scenarios where these can be quite useful.

Though, I don't have ETA at the moment, I would like to share a few thoughts regarding that:

  • Reference of a single key-value (ex. key=app1/setting1) - this is simple and straightforward to resolve. The final key name is local, while the value is where the reference points (1 to 1 mapping).
  • Reference of a set (ex. key=default/*) - this is bit more complicated. To follow the approach above, the final key names should be composition between the local key plus referenced keys. It's unlikely that simple concatenation will do it. Perhaps some prefix trim is necessary. The caller may not necessarily anticipate the final outcome.
  • Circular references - self-explanatory. Detection and error handling at setup.
  • Reference to a reference chain - breaking of the chain. Depth.
  • Reference to non-existing/deleted setting.
  • Dynamic refresh on referenced value changes.

Let me know your thoughts as well.

On a side note, regarding simplified configuration composition, have you checked AppConfiguration Snapshots? It may help to address certain hierarchical models as well.

If supports external configuration reference, need to consider the access permission.

@drago-draganov
Copy link
Contributor

If supports external configuration reference, need to consider the access permission.

Based on how KeyVault references are resolved, the access control is independent with identity provided by the caller (ex. configuration providers). It makes sense configuration references to follow similar logic and security isolation.

@zhenlan zhenlan added the enhancement New feature or request label Jan 9, 2024
@itsdani
Copy link
Author

itsdani commented Jan 10, 2024

Thanks for the suggestions!
I'm glad to hear this is in the plans for the future 👍

We have thought about using labels for application-grouping, but we would like to reserve labels for environments (prod/staging/etc). Another issue is that we might want to use application-specific naming for the variables instead of using the common name everywhere (although this might be avoidable), and the config references would be perfect for this.

For now we will most likely keep common values in a key vault and use key vault references for the applications where needed.

Another thing to consider with references and snapshots is that the snapshot currently doesn't save the value of the reference, but the reference itself, which can cause unexpected changes in an otherwise immutable snapshot. In a key vault reference this can be mitigated by using references to fixed versions, although it's a bit inconvenient. I'm not sure how an app-config reference should work with snapshots.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants