title: How does one achieve .NET Deployment Nirvana?
body: <p>Our company is nearing its "go live" date (and its getting a QA department date), and I'm trying to define the right operational processes to support this.  A big consideration of mine is how to avoid the deployment/configuration hell that has inevitably occurred.  Have any of you found a good solution for handing off builds to the non-programmers so that they could successfully install and configure it in a QA, staging, and production environment?</p>
  
  <p>A full environment for us is composed of a mixture of heterogeneous scheduled tasks, Windows services, and web sites, all of which can be scaled out through parallel deployment.  Thankfully, the means of configuration is consistent.  Unfortunately, it's all managed through .NET web/app.config files.  In my experience, QA and ops folks always mess up when trying to modify them (XML is surprisingly hard for most people to handle!)</p>
  
  <p>Here's the options I'm considering:</p>
  
  <h2>Using machine.config files</h2>
  
  <p>This is something I haven't done in practice, but it looks promising.  If we create a machine.config template containing every setting for every application that can vary by environment, this would allow an admin to make all changes to one file and deploy it to each machine in the environment.</p>
  
  <dl>
    <dt>Pros:</dt>
    <dd>This potentially reduces the number of steps necessary to deploy a system</dd>
    <dt>Cons:</dt>
    <dd>Having to somehow document configuration schema changes</dd>
    <dt>Unknowns:</dt>
    <dd>We make use of custom config sections and other configuration extensions that reference assemblies.  Would this require us to install our .NET assemblies in the machines' GACs?</dd>
  </dl>
  
  <h2>Perform config file manipulations in build process</h2>
  
  <p>If we set up the QA, staging, and production environments so they appear identical to our software (virtual servers and LANs, etc), QA should be able to transition ready software with no configuration changes directly to the staging environment, and staging to production.  With this setup, theoretically we could hand to QA pre-configured foo.config files that nobody needs to touch.</p>
  
  <dl>
    <dt>Pros:</dt>
    <dd>Engineering would be more adept at ensuring that configuration files are valid</dd>
    <dt>Cons:</dt>
    <dd>It may be considered poor security practice for engineering to be aware of production configurations (a poor argument, IMHO)</dd>
  </dl>
  
  <h2>Have a network-centralized settings repository</h2>
  
  <p>This one doesn't look attractive to me, because I tried this in three ways that were ultimately failures:</p>
  
  <ol>
  <li>At a prior company, we had the configuration settings in the database, but of course you can't put them all in there, since you need to configure the connection string <em>to</em> that database.  Also, it was just as difficult to ensure that the database got properly updated before deployment.</li>
  <li>Another approach we'd tried was to have a networked service that worked as sort of a centralized registry.  This almost worked, but there were always issues with local caching, ensuring that the URL to the config server was properly configured, and of course configuring the config server.</li>
  <li>Active Directory?  Ew!  Need I say more?</li>
  </ol>
  
  <h2>Thoughts?</h2>
  
  <p>How successful have you been with using the options I'm considering?  Are there any alternatives to these that have worked well for you?</p>