This SO is close but my question is about how to share configuration in Azure App Configuration across multiple apps. I get how this helps configure the app itself (how it works) but looking for advice on how to share settings across apps. Esp since there is no cross referencing in App Configuration service.
example: I have 3 app services. They all make calls to the same internal REST api in another service.
In the app configuration, I typically have an appSettings.json or App Service Configuration setting like:
"MyRestApi":{
"Url":"https://myRestApi-Dev.com/api",
"api1ControllerName" : "Home",
}
or better still (more obvious to ops than buried appSettings.json):
MyRestApi__Url = "https://myRestApi-Dev.com/api"
MyRestApi__api1ControllerName = "Home"
So each app would have this alongside many other settings. In Devops, I use pipelines library with common and per-environment group variables. I detect the dev/test/prod environment and override the url setting then apply that configuration to each deployed app.
In App Confirguration, I am encouraged to use "App:Setting:Subsetting" so it looks like I would have
in code
....
options
.Connect(settings.GetConnectionString("AppConfig"))
// Load configuration values with no label
.Select(KeyFilter.Any, LabelFilter.Null)
// Override with any configuration values specific to current hosting env
.Select(KeyFilter.Any, hostingContext.HostingEnvironment.EnvironmentName)
services.Configure<MyRestApiSettings>(Configuration.GetSection("App1:myRestApi")); //in app 1
services.Configure<MyRestApiSettings>(Configuration.GetSection("App2:myRestApi")); // in app 2
services.Configure<MyRestApiSettings>(Configuration.GetSection("App3:myRestApi")); // in app 3
in App Configuration
app1:MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Dev)
app1:MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Test)
app1:MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Prod)
app1:MyRestApi:api1ControllerName = "Home" (Label: null)
app2:MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Dev)
app2:MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Test)
app2:MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Prod)
app2:MyRestApi:api1ControllerName = "Home" (Label: null)
app3:MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Dev)
app3:MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Test)
app3:MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Prod)
app3:MyRestApi:api1ControllerName = "Home" (Label: null)
It seems like there is a lot of scope for typos.
So is it better to have :
MyRestApi:Url = "https://myRestApi-Dev.com/api" (Label: Dev)
MyRestApi:Url = "https://myRestApi-Test.com/api" (Label: Test)
MyRestApi:Url = "https://myRestApi-Prod.com/api" (Label: Prod)
MyRestApi:api1ControllerName = "Home" (Label: null)
and then use IOptions in the app to load "MyRestApi" into a settings object for the rest API?
services.Configure<MyRestApiSettings>(Configuration.GetSection("myRestApi")); // in all apps.
I prefer this but am I aiming for trouble down the line?
@MarkD, your approach will work. I am adding an alternative solution here.
You can put the shared configuration in a separate namespace (prefix), for example,
Key | value |
---|---|
Default:MyRestApi:Url | ... |
App1:MyRestApi:Url | ... |
App2:MyRestApi:SomethingElse | ... |
Then you load everything with prefix Default
first and override them with any app-specific settings, for example, here is my code for App1:
configBuilder.AddAzureAppConfiguration(options => {
options.Connect(configuration["connection_string"])
.Select("Default:*")
.Select("App1:*")
.TrimKeyPrefix("Default:")
.TrimKeyPrefix("App1:");
});
Note that I called TrimKeyPrefix
to remove those prefixes. With this, the rest of my application doesn't need to worry about the prefix and it has only one value for each configuration setting.