Anyone know good rule of thumb for what's in .CSDEF versus .CSCFG? - azure

I was surprised by a few questions on the 532 and 533 exam that more or less wanted to me to recall exactly what settings were in which configuration files for Cloud Services. I think at the basic level this is a pretty tough thing to discern without documentation in front of me.
For example: Scaling the instance count for a given Role is defined in the .csdef file, but the instance size for a Role is in .cscfg. It's not obvious to me why one versus the other is appropriate.
Anyone have any useful tips for remembering/recalling what goes where?

The main difference is that you can upload a new service configuration file (.cscfg) without redeploying the cloud service so configuration values can be changed without any downtime. There aren't many configuration settings that can go to the service configuration file (.cscfg) so just remember them and assume that all other settings go to the service definition file (.csdef).
Here's a great article on the subject: What is the Cloud Service Model and how do I package it?

Any on-the-fly changeable settings are in the configuration file. The definition file has several items that may only be changed with a re-deployment, along with a user-defined list of settings you'll want to change on-the-fly (the list itself is static, but the values are changeable).
You might be able to argue that some settings should go in the configuration file vs the definition file (e.g. a role's vm size), but these are not changeable.
Schemas are fully published for both the configuration file and the definition file.

Related

Should Azure ServiceConfiguration.Cloud.cscfg be checked into source control?

I've started working on an Azure project. In terms of config, I currently have three files: ServiceConfiguration.Cloud.cscfg, ServiceConfiguration.Local.cscfg and ServiceDefinition.csdef.
ServiceDefinition.csdef is the template file for the csfg files. ServiceConfiguration.Cloud.cscfg contains all the actual Azure configuration, including DB passwords, SAS keys etc.
Should ServiceConfiguration.Cloud.cscfg be checked into source control? I wouldn't have thought so but a quick search on github for the file shows that it is.
If it should be checked in, how should the sensitive password data be managed?
I typically check in the configurations. The reason is that the behavior of your application will change dramatically depending on these configurations. For example -> number of roles for a distributed application directly affects how you process incoming messages and the vmsize directly affects how much memory you have. You may encounter issues debugging problems if each developer is using a different configuration. This standardizes your deployment.
Anything with plain-text password information shouldn't be checked into a public repo unless you want people to have access to that information.
You can add this file to the .gitignore file and prevent it from being checked in.
Provide a different ServiceConfiguration.Cloud.cscfg named something like ServiceConfiguration.Cloud.cscfg.template with all the config info of your cloud service minus the password values. If someone forks your project they need to use that and fill in the appropriate values and rename the file.
Do this and change all your passwords to something else. Even if you delete this file from the repo, it still exists in the history and anyone can view it.

Azure localisation - how to take resource files out of your packaged application?

I have a localised site reading from your standard .resx resource files. Everything works fine, however I am deploying to Azure. The .resx files are packaged along with the rest of the site and deployed onto each role instance. Meaning if I want to make a change to something I need to redeploy the entire package to Azure again and suffer a rolling update.
Is there a way I can get my site to read resource files from a single static location, such as blob storage? Is this a good idea or should I just do my best to get it right first time?
Thank you!
Well rolling updates aren't the end of the world. If your site is hosted with multiple running instances, each instance will be taken out of the load-balanced loop, brought down and updated in sequence, so your users shouldn't experience any real down time.
One option though would be to move to a non-resx based localization setup. you can write your own ResourceProvider to override the built in one. Rick Strahl had a nice example of reading resource information from a database.
http://www.west-wind.com/weblog/posts/2009/Apr/01/Updated-WestwindGlobalization-Data-Driven-Resource-Provider-for-ASPNET

Azure cloud service project configuration (.csdef and .cscfg) in multiple environments

Currently we have a development cloud services (acme-dev-service) and a production cloud service (acme-prod-service). Our current setup in our solution has a cloud service project called acme.application that uses transformation of the .cscfg and .csdef files for deploying the project to the two environments (production and development). I don’t like the transformation method because it feels like a bit of a hack to me. So after doing some research it seems that you can have multiple configuration files which solves some of the issue but I am running into problems because you are only allowed one service definition. This doesn’t work for us because the production environment requires extra certificates as well as different hostHeader bindings than our dev environment does.
So it seems we cant really get away from using the transformations. So I guess my question boils down to am I looking at the Azure Service Project files in the wrong light? Should we really be mapping one Azure Project to one Azure cloud service? Should I have an Azure project for Production and a second Azure Project for Development?
Is there a better way to do this? Or a best practice for working with multiple environments in Azure?
The CSDefinition file is the real kicker here. If you have a value you need to be different between two environments (dev/test/stage/production, etc.) then you really have three options:
1) Manually modify the value before a deployment. Errr....Okay....you have two options.
1) Tap into the MS Build process and determine which cloud configuration you have selected (the one used to determine which version of the .cscfg file will be used) and then have the build modify the .csdef after the build and prior to packaging (there is a time when the file has been copied to a different directory just before packaging and this is where you want to make the change). This can be tricky, though I've seen it done and have even done so myself in the early SDK days. Here is a blog post explaining one example where he's using WebConfigTransformRunner to do just that: http://fabriccontroller.net/blog/posts/apply-xdt-transforms-to-your-servicedefinition-csdef-file/. I don't really think this is your best option because it is opaque. It's not evident what is going on and someone who comes along after you to maintain the code will not know about this little gem and will spend forever trying to figure out why some value they put into the csdef somewhere is somehow getting overwritten after they publish to a different environment.
2) Use the two Azure Project approach you mentioned. You can set up build definitions in your Build tool of choice that determine which of the Azure projects you want to build and publish. Personally I think this is the best way to deal with different .csdef files. It's straight forward and doesn't require modifying the csproj files. I'm not opposed to csproj file changing, it's just not overly obvious it was done and, speaking as someone who has inherited things like that, it's not easy to find when people do that kind of thing and they aren't around to tell you about it.

In Azure, where does the cscfg file come from?

So in Azure, I created a cloud service, and now I want to upload a deployment. It asks for a package (sure, that's easy, a zip file) and a configuration file (.cscfg file). I understand that the .cscfg file is supposed to define the roles, network configuration, etc.
But I don't have a cscfg file. Where are they supposed to originate? Do I have to write one by hand? The documentation for that is substandard at best. Is there any way to generate one? Or do a deployment somehow that bypasses this step? My approach must be wrong on some level (unless I really do have to write one by hand, but I somehow doubt that is a typical case).
You can either rely on Visual Studio to create it or manually create with command line tools.
http://www.microsoft.com/en-us/download/details.aspx?id=15658
You can also create using msbuild:
http://msdn.microsoft.com/en-us/library/windowsazure/hh535755.aspx

Is it possible to easily modify the log4net section in the config file of several running applications remotely?

Our product consists of client, server and agents. Each deployed on different machines. The QA is having a hard time to manipulate the log4net sections in the respective config files. Right now, they have to have remote desktops to all the relevant machines and open notepad in each of them and then edit the files one at a time switching between different machines as they proceed. A real pain in the ass.
Can anyone suggest a better solution to this problem?
Thanks.
You could store the log4net configuration in a database (you could then even consider to create a web interface that allows your QA team to modify the configuration). You have to figure out how your applications pick up the new configuration (e.g. you have some remote Admin interface that allows you to tell your applications to use the new configuration).
On start-up you load the configuration from there. Maybe it is advisable to have some backup configuration in a file that is loaded first in case loading from the database fails. The default configuration would be for instance so that the QA team gets an email if loading the configuration from the database fails.
Another option would be to store all log4net configuration files on a network share... create an application setting that tells your application where to find the log4net configuration and call the Configure() method accordingly. Again the question is how your applications pick up the new configuration.
Not sure if ConfigureAndWatch() would behave as expected if the configuration files is on a network share. If so that would be quite an easy option to implement.

Resources