I also use CruiseControl for deployment, except that I've just created some batch files which use robocopy to mirror directories from the build server into the correct environment. I then setup a CruiseControl project which just has an exec task in it.
For me, deployment must always pass through the multiple stages, so into dev, into qa and then live so I have three sets of web.config files: web.config (local user), web.config.dev, web.config.qa and web.config.live - my deployment scripts are set to delete the web.config and rename web.config.whatever to the correct version. If you attempt to access the other configs via HTTP, the ASP.Net process denies access. For Windows Services and applications I use the same approach - I have a WindowsServiceName.exe.config.dev etc, which I get the developers to set to be output to the output directory so they get included in the deployment. The deployment script is slightly different though, since it stops the Windows services before deployment. For my team, anyone can force deployment to the development environment, but only certain users can deploy to the other environments. I'm waiting on the security features of CruiseControl (or at least, for me to understand them) before I add those scripts as projects in CruiseControl, but that will be pretty good. What I haven't got is a decent patching process, so I'm very interested in that aspect of what you're doing.
