In IIS, how should environment/site-specific WEB.CONFIG settings be preserved, when using MSDeploy? - iis

Background
I work in QA at a software company.
We have about a half a dozen different web applications, each of which may require, at any given site, some customised settings added to its web.config file.
These can range from which Oracle database/schema(s) the app connects to, to how many search results to cache, to which hierarchy to use when sorting items on a web page.
We make use of Microsoft's Deploy package, to get the new releases installed/updated on client sites.
When we put out a new release, some of these customised settings may have been added to or removed from the given web app's web.config file, but using Deploy to import the new release over the top of the old one will clobber any customisations that may have been made.
Alternatives
There are ways of handling this manually, such as merging via a plain text comparison of the old and new web.config files, but these are cumbersome and prone to human error.
I was reading about transformations and thought they could be of some use.
There is also the capability to use external files (tip #8) which seems like a good way to go.
Improvement?
Should our programmers be providing some sort of semi-automated merge facility for this web.config file? Does the Deploy package provide this somehow?
Should we be making use of the external config files, as a best practice?
Is the concept of customising this web.config file at each site so fundamentally flawed that the whole thing needs to be re-thought?

Microsoft provides Web.config transformations as the de-facto way to do this. You can create different deployment configurations within Visual Studio and the web projects. Then when you build or your build server builds with that particular configuration the web.config is transformed to contain the settings you want to see.
View more about web.config transforms here.

Related

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.

Trouble syncing file-based templates to database using MSM and config bootstrap

Had started my typical EE build (using a bootstrapped config) for a client when they announced they wanted another additional site using the MSM module (le sigh).
So added the MSM module, I commented out the $config['site_url'] and $config['cp_url'] and set those in index.php instead using $assign_to_config.
That's when I discovered this bug where MSM config file settings are not recognized, which is a pain but I can work around it. However, I noticed that when I created the secondary site, it wouldn't recognise my custom location for add-ons and so I had to add that to index.php as well to $assign_to_config['third_party_path'] = "../assets/third_party/";.
Then I discovered that when I create or modify a template file, it won't automatically sync and so I need to manually do that each time which is a real PITA.
Why would my templates not be syncing to the database? Is this related to the MSM config bug?
While I haven't tried bootstrapping the third party path yet, I've definitely been able to bootstrap the template path for MSM sites... What bootstrap method are you using?
Are your sites on subdomains or subfolders? I've only had experience with subfolders so perhaps that makes a difference (although it shouldn't).
Could you maybe walk through in a bit more detail what's happening? Your first site (site_id = 1) templates sync automatically from filesystem edits, but your second site does not? Yet if you go to CP > Design > Synchronize Templates, that works?
The $assign_to_config portion of MSM setup is definitely a weakspot when it comes to bootstrapping... I wonder if we need to work up an additional bootstrap for MSM+CP environment, where it looks at the cp cookie ($_COOKIE['exp_cp_last_site_id']), and sets values based on that.
It may be helpful if you let us know which bootstrap you are using. For example, if you look at this bootstrap the site_url and cp_url are set using the HTTP_HOST server variable, so this shouldn't clash with your MSM install (and multiple domains) at all.
Perhaps you could try using that boostrap file instead, and see if it fixes your issue with template syncing?
Finally, if you're going to use the EE template manager, you don't really need to store templates as files. Conversely, if you want to save templates as files, it's probably much easier editing them using Sublime Text or another editor, rather than the clunky built-in editor (which is really only useful for small/simple changes).

How to include config file in WSP?

I use NLog for logging and now I'm trying to also use it for my SharePoint solution.
How do I instruct WSPBuilder to include NLog.config in WSP and place it in the same folder as solution dll?
EDIT:
Okay, another option is to put it as Web.nlog in SharePoint 80 directory.
Do I need a separate feature for this? What should I write in elements.xml?
I don't think this can't be done - I assume for security reasons.
DLLs can only be deployed to GAC (signed assemblies only) or to the bin directory of the web application (deployed via the solution manifest, along with any required CAS policies).
If you want extra files alongside the assembly in the bin directory, you'll need to copy them manually.
Does NLog.config need to be a separate file, or can the settings be integrated into the web.config file? If you can integrate the settings into the web.config file, you can add a feature receiver and write the necessary settings during the FeatureActivated or FeatureInstalling event to web.config using SPWebConfigModifications (just google for it). You should also make sure to remove the settings in FeatureDeactivating or FeatureUninstalled event.
You should also take a look here :
http://msdn.microsoft.com/en-us/library/ee413935.aspx
I would also ask these questions :
Is the configuration the same for all the farm ? Only one web application ?
Can you programmaticaly specify NLog configuration ?
Depending on your answers, I will suggest one or more solutions.
The disadvantages with the web.config are
Configuration is deployed on all SharePoint servers (the feature take care of that, but you have to keep that in mind in case of inconsistant behavior)
If you want to modify settings there is no easy way
Each time you modify settings, it will recycle application pool.

How do you handle code promotion in a Sharepoint environment?

In a typical enterprise scenario with in-house development, you might have dev, staging, and production environments. You might use SVN to contain ongoing development work in a trunk, with patches being stored in branches, and your released code going into appropriately named tags. Migrating binaries from one environment to the next may be as simple as copying them to middle-ware servers, GAC'ing things that need to be GAC'ed, etc. In coordination with new revisions of binaries, databases are updated, usually by adding stored procedures, views, and adding/adjusting table schema.
In a Sharepoint environment, you might use a similar version control scheme. Custom code (assemblies) ends up in features that get installed either manually or via various setup programs. However, some of what needs to be promoted from dev to staging, and then onto production might be database content that supports the custom code bits.
If you've managed an enterprise Sharepoint environment, please share thoughts on how you manage promotion of code and content changes between environments, while protecting your work and your users, and keeping your sanity.
I assume when you talk about database content you are referring to the actual contents contained in a site a or a list.
Probably the best way to do this is to use the stsadm import and export commands to export and import content from one environment to another. (Don't use backup/restore when going from one environment to another.)
For any file changes (assemblies, aspx) you can use Features and then keep track of the installers. You would install the feature and do an upgrade to push changes.
There's no easy way to sync the data...you can use stsadm import/export commands as John pointed out. But this may not be straight-forward, especially if the servers are configured differently.
There's also Data Sync Studio product (http://www.simego.net/DataSync_Studio.aspx) you can try.
Depending on what form the database content takes, I would keep the creation of it in code so it's all in one place (your Visual Studio project) and can also be managed via source control. Deployment of the content could either be via a console application or even better feature receiver.
You might also like to read this blog post and look at the tool mentioned there for another approach.
The best resource I can point you to is Eric's paper:
http://msdn.microsoft.com/en-us/library/bb428899.aspx
I was part of a team working to better the story around development of WSS and MOSS solutions with TFS, but I don't know where that stands.

What files are you allowed to modify in SharePoint 2007?

What files can we modify so that our solution is still supported by Microsoft?
Is it allowed to customize error pages?
Can we modify the web.config files to use custom HTTPHandlers?
You can certainly edit the web.config file for your sites. The one thing that you should be aware of, however, is that when you start editing files manually on the file system, you will have to remember to manually make those changes across all servers in the farm (assuming a farm exists). In addition to this, when you edit files in the 12 hive, it's important to understand that you will be making a change to all SharePoint sites hosted on the server(s) for which the files were edited.
Personally, if I were going to create a custom error page, I would simply add a <customErrors> section to my web.config. I avoid editing any existing files in the 12 hive, but I have added files (though it's rare).
The customization of the error page is not very easy (or flexible). You can see an example here:
http://blogs.msdn.com/jingmeili/archive/2007/04/08/how-to-create-your-own-custom-404-error-page-and-handle-redirect-in-sharepoint-2007-moss.aspx
The web.config can be changed. I used my own HttpModules in addition to the original ones, but I haven't used custom HttpHandlers. IMO it should work if you don't change the original handler (i.e. if you add your handler for a specific type of file not handled by SP).
do not modify any pre-installed files in the 12 hive (Program Files\Common Files\Microsoft Shared\Web Server Extensions\12)... a service pack may update and overwrite any changes.
Anything in the Content Database (Masterpage, Stylesheets list in ~Catalogs) is available to modify (I would add, instead of update, in case a service pack changes anything) as it sits atop the file system, and is instantly available to any members of the web farm (newly added servers).
Any custom features, added to the 12 hive in the features folder, in a custom/non-microsoft folder (that is, inside the 12\feature folder, do not modify any preinstalled files, but feel free to add a folder for your feature and work within).
Custom features can be developed using the Visual Studio Extensions (VSeWSS), currently available for Visual Studio 2005/2008... benefit being that the output is a feature package (.WSP file) which is designed to be portable across SharePoint. Additionally, the .WSP files are just CAB files with a different extension, offering the ability to be explored by simply renaming them.
For site definitions, Microsoft has a good article about what is supported and unsupported. In short, the only change you can make to the out-of-the-box site definitions is changing the entry in the webtemp.xml file to hidden in order to prevent the site definition from appearing in the site template list. This is something many may be interested in doing.
You may also, of course, copy existing definitions and rename them in order to create new ones.
The complete list of supported and unsupported scenarios for working with custom site definitions can be found here:
http://support.microsoft.com/default.aspx?scid=kb;en-us;898631
Here is the closest I can find to a official response from Microsoft:
http://technet.microsoft.com/en-us/library/cc263010.aspx

Resources