Changing/retrieving configuration settings on role start (Azure) - azure

I'm trying to make a service to more easily configure configuration values on Azure applications. Right now, if I want to change a setting that it the same over 7 different environments, I have to change it in 7 different .cscfg files.
My thought is I can create a webservice, that the application will query for its configuration values. The webservice will look in a storage place, like Azure Tables, and return the correct configuration values.
I've been able to integrate this into a deployment script pretty easily (package the app, get the settings, change the cscfg file, deploy). The problem with that is every time you want to change a setting, you have to redeploy.
Finally the question - Is there a way I can retrieve the configuration settings after the application starts, on role start? It would of course need a base set of settings for the app to start. Retrieving the settings from the web service on application start would be good. Any way that I don't have to redeploy the application and that it will retrieve them automatically will work.
Thanks in advance!

Just use the .cscfg for the minimum set (common to all environment) of configurable settings. The use your web services for rest of the configurations. And don't modify your .cscfg. Just have a settings provider that retrieves settings from web service (via polling or message signalling - pub/sub model). And have a reinitialize settings procedure in place for this settings provider and all the services/components that rely on configurable settings.

Related

How to share application settings between app services in Azure?

I have several App Services in Azure: development, test, and production. I would like to share some application settings between them like variable sets in Octopus.
Let's say I have a key A which should be same in all App Services. I would like to set its value in one place but seems that I have to configure it to each App Service. When A is changed, I have to change it to everywhere instead of having one common place to change it. Is there some way to do this?
No built-in way, app settings are part of the App Service resource.
You will need to put the settings in a common database or file.
Azure Key Vault can be used for sensitive settings and table storage/blob storage works well for other settings. Azure SQL is also an option.
Your app will then need to load these settings at startup.
This is also a documented cloud design pattern: https://learn.microsoft.com/en-us/azure/architecture/patterns/external-configuration-store

What causes azure websites to ignore settings from web.config?

My web.config contains multiple entries in "appSettings" (e.g.: twilio account key). One of these is for the asp.net chart control. It's the configuration part that states where the images the control generates are to be stored.
All of these settings work on my development machine. That is, i can connect to twilio and the chart control stores image in memory (as it should, according to the settings).
When i publish the site to my azure website (using vs), all of the settings work, apart from the chart control one. The chart control behaves as if the setting isn't even there. (it defaults to c:\TempImageFiles for storage).
I looked into the published version of the web.config and the setting is there. Only, it's beeing ignored.
My next attempt was to add that setting using the portal. (It's possible to add appSettings for a web app using the portal). I copied the exact same setting from web.config into the portal settings. This worked, so there is nothing wrong with what's in the settings.
So my question is: Why are some (at least this one) settings from web.config ignored when the app runs inside an azure web app?
You might have an app setting defined in the Web App's configuration with an identical name that overrides the web.config setting. This is typically done to have production settings stored in Azure instead of Web.config.
You can confirm if this is the case by opening your Web App's blade in the new portal, and checking the Application Settings tab there.
azure websites / azure web app service are typical web applications running on top of azure PaaS infrastructure. So whatever storage allocated to the service is accessible from the app. But it cannot be the typical C: or D: where in a regular server the app may have complete access. Mostly the C: space is allocated for IIS hosting. D:\local is something you can utilize as the app will have complete read and write access.
Please refer azure web app service sandbox details here.
If you are accessing the path via code try using Server.MapPath property to get access to the path. options like Path.GetTempPath() will not work.
One point to note is, any local storage in azure PaaS services is to be treated like a temporary storage. Whenever the site, service or role recycles the storage will be gone a fresh storage will be assigned.

Azure Websites Application Insights - switching config

I have an Azure Website. For the sake of this question, the production version of the website runs on example.com, and a test version of the website runs on sandbox.example.com.
The only difference between the two is that they have different configuration.
At present, they are running under different websites, and I deploy the same website to each azure website via git.
I'd like to separate out the Application Insights data. Is there a technique or process that anyone uses - apart from editing the ApplicationInsights.config file in the sandbox environment post deploy?
Or would using a deployment slot handle this in some way?
There was a new blog post about exactly this today: Application Insights Support for Multiple Environments, Stamps and App Versions.
The destination of the telemetry is determined by the instrumentation
key (iKey), which is sent along with every telemetry message. In the
Application Insights portal, similar events and metrics with the same
iKey are aggregated to give you charts of average durations, event
counts, the sum of users, and so on. The iKey appears in two places in
your project. One is in ApplicationInsights.config:
<InstrumentationKey>94843456-2345-3456-4567-324562759284</InstrumentationKey>
If your application has web pages, the iKey also appears in a script
in the head of every web page. Usually, it’s only coded once in a
master page such as Views\Shared\_Layout.cshtml.
To direct telemetry to different application resources, we can create
several resources with different iKeys. Then we only have to change
the iKeys in the application at each transition in its lifecycle –
along with other configuration data such as connection strings,
certificates, and subscriptions.
The article then goes on how to do this in code, confg, etc:
1) Add iKey as a property in Web.config:
2) Instead of using the iKey from ApplicationInsights.config, we’ll
set it in the code. In global.asax.cs.
To avoid confusion, remove the <InstrumentationKey> node from
ApplicationInsights.config.
3) Configure the web pages to pick up instrumentationKey: "#Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey". This is
the script usually found in View\Shared\_Layout.cshtml.
4) Don’t forget to update your Web.config with appropriate iKey
configuration during the deployment process. You might devise a way of
setting it appropriately as part of your build, but I’ll leave that to
you.
Found this semi-related question: How to support multiple Azure subscriptions for a single application with application insights this is for using by cloud services, and it works!
Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey = ConfigurationManager.AppSettings["appInsightsKey"];
I have done this in my unity registertypes method, it works there.
In the Azure portal for websites, on the config tab there is a section called App Settings. You can put your different configuration settings here. When publishing, azure will inject those settings into web.config.
Then just use WebConfigurationManager.AppSettings as you would normally and it will pull the injected values.

Azure web/worker role read configuration settings

What is the best way/recommended way to read settings from a worker/web role?
Is it:
CloudConfigurationManager.GetSetting("ConnectionString") (this I'm using)
or
RoleEnvironment.GetConfigurationSettingValue("ConnectionString")
Although both work fine ...
From the documentation for CloudConfigurationManager.GetSetting:
The GetSetting method reads the configuration setting value from the
appropriate configuration store. If the application is running as a
.NET Web application, the GetSetting method will return the setting
value from the Web.config or app.config file. If the application is
running in Windows Azure Cloud Service or in a Windows Azure Website,
the GetSetting will return the setting value from the
ServiceConfiguration.cscfg.
From above, it is clear that the function CloudConfigurationManager.GetSetting reads either from service configuration (ServiceConfiguration.cscfg) file or application configuration file (App.config/Web.config) depending on where the application is running.
RoleEnvironment.GetConfigurationSettingValue will only read from the service configuration file.
If your application component is used in both cloud and non-cloud applications, use CloudConfigurationManager.GetSetting so that you don't have to make any changes in the code. If your component would run only in the cloud, then I guess you could use either one.

Is it possible to update configuration settings programmatically?

We are experimenting with deploying an MVC app as an Azure web role. Currently the app is being hosted locally on our server. It has a few appSettings in Web.Config that can be changed by the users as part of the "Administration" module of the application.
I know this isn't a good practice for Azure because there will potentially be multiple instances of the application running with multiple Web.Configs, which makes updating them all a nightmare (if not impossible). My understanding is that the ConfigurationSettings specified in the service definition should be used instead of Web.Config so that settings are defined globally in one place that all the instances of the application can access.
My question is is it possible to programmatically update ConfigurationSettings similar to the way we update Web.Config settings, or would it be better for us to move those settings into a database or something else?
Yes, but unfortunately it is definitely not simple to do.
Follow this URL: http://msdn.microsoft.com/en-us/library/windowsazure/ee460809.aspx
It talks about a Svc Management API call that you can make to read/write the Service Configuration. It is a 64-base string which you'll need to decode, find XML flags in it that you want to change and re-encode it back and send it back to the API.
Not pleasant, but doable.

Resources