Strategy to avoid storing secret web.config settings on github - web-config

I got a .net framework solution that has secret settings (API keys, connectionstrings etc) in a web.config.
The solution code lives at github.com.
I want to avoid having those secret settings at github at all.
I got a teamcity build server, that has those settings and merges them into the web.config at build time for the different enviroments, just before deploy time. This works great.
But I need ideas of how to handle those settings for developing locally, where the teamcity server (of course) does not build and merges settings.
Could it maybe be possible to inject some code i global.asax on Application_Start, to fetch the settings from a secure place and set the settings there?
Or maybe have a different config file just for development that is only loaded when developing and is not committed in github?
Or is there some other smart way that I can't think of?

I found a way through powershell and the 'file' reference in web.config and made a Blog post about it: https://codebuildplay.wordpress.com/2018/11/30/how-to-store-settings-in-teamcity-and-merging-into-a-net-config/

Related

Using VSTS Release Management, how can I modify the configuration of an Azure Web App for each environment?

I'm using Visual Studio Team Services and I'm trying to set up Release Management to allow automated deployments for our Azure Web App to multiple environments. I would like the same source to be deployed to each environment, but with modified configuration settings.
I was hoping that I could create a single Build for my application, and then modify the configuration at deployment time for each environment. I'm aware that this can be done for appSettings and connectionStrings (either through Tokenization, or even managing those settings via the Azure portal), but I'd like to be able to make more general changes to the web.config file. For example, I want to be able to:
Update 'simple' settings such as appSettings/connectionStrings
Update multiple attributes on elements (like httpErrors)
Insert or rewrite sections of the config file itself (for example to add IIS rewrite rules, or to remove unwanted HTTP handlers for production)
Currently we achieve this by using config file transformations and separate publish profiles for each environment (manual deployment). I can't see a way to re-use this if I want a single release pipeline.
I'm hoping someone can help point me in the right direction. I'm also happy to accept alternative solutions - ultimately I just want to be able to deploy the same source (e.g. from the same commit in source control) to multiple environments, with different configuration, while keeping some kind of flow from dev, to test, to eventually production.
You can use Tokenization Task to update the files base on the environment variables.
More similar extensions: Replace Tokens and Colin's ALM Corner Build & Release Tools.

Environment specific EF6 Code First Migrations using VSTS Release

I have a project that uses Entity Framework 6.x, ASP .NET WebApi 5.x. Data Access is in a secondary project inside the solution. I want to use VSTS (aka Visual Studio Online) to build and release it as a website to environments for integration/dev, qa, stage, and production. There are some great videos on Channel 9 that deal with the generic high-level description. (for example https://channel9.msdn.com/Series/DevOps-Release-Management and https://channel9.msdn.com/Series/DevOps-Fundamentals/Infrastructure-as-Code) There are all kinds of articles and videos about how to do migrations from inside Visual Studio including generating scripts.
Searching around the web I don't even find any older resources or concrete examples of continuous deployment with code first migrations. There must be examples and best practices for methods other than auto-migrations or SQL scripts.
I have configured a Web Deployment Package publish profile. I use it via the PublishProfile msbuild.exe directive. The package is added to the artifacts and then deployed by the Azure Web App Deployment task in each Release environment. However once this package is built, I don't know of a way of changing the connection string in the build package for each time it is released to an environment.
There is probably something I am overlooking, but how should environment specific migrations be done with via VSTS Release?
For Code First Migration, you can "Write App_Start code to run Migrations" or "Write Web.config transforms to configure the MigrateDatabaseToLatestVersion initializer to run", refer to this article for details: http://blogs.msdn.com/b/webdev/archive/2014/04/09/ef-code-first-migrations-deployment-to-an-azure-cloud-service.aspx
For the connection string transformation with profile, you need to add a web.config file for the publish profile and then enter the connection string in this web.config. Refer to this link for details: http://awaitwisdom.com/publish-profile-config-transform/
I hate to answer my own questions here but, ultimately my research took me to the conclusion I am posting at length here. In sort, Web.config and Parameters.xml require some custom scripting that will require you to maintain your own deployment automation. These routes will still require you to additionally create your resource groups or manage them manually.
To avoid these complications and cobbling tools and scripts together, the whole operation can be achieved with two JSON files. These JSON deployment templates allow you to create or update your resource group when your deployment runs. They also allow you to automate setting appsettings and connectionstrings that overwrite your Web.config values in the same manner as you can through the Azure Portal.
the steps: (1) Add the two JSON files to the project setting the name of you connection string on line 88 (2) Add a Azure Resource Group Deployment task to the Release environment. (3) Set Template (WebSite.json) and Template Parameters (WebSite.parameters.json) paths in the task. (4) Set Override Template parameters to -hostingPlanName "myHostingPlan" -webSiteName "myWebsiteName" -connectionString "the-actual-connection-string" (5) make sure you are using the same website name in your Azure App Deployment task.
This does depend on having your code first migrations run via App_Start or something similar. I took the first part of #Eddie's suggestion since App_Start is easy to deal with and doesn't seem to run too often.
As a bonus you can add environment variables for any of this configuration so you can clone the environment and then just change the variables. This ultimately makes your application or api connection string a Release variable.

Best way to manage IIS configuration in IIS7

We're moving our sites to use IIS7 and want some advice on the best way to manage the IIS settings.
We want to be able to put the settings into source control so they can be easily accessed by developers when they set up their local machine and be included in the package that gets deployed the the environments.
We have a branch for each team so we would prefer a text based format that can easily be merged when changes are forward integrated from the main branch.
We have six sites and would like the configuration for each site to live with the code for each site.
Our solution for IIS6 was to have metabase fragments checked into source control and automated through the WMI interface at deploy time. It doesn't seem like IIS7 has the same functionality.

What is a typical workflow to put my local MVC3 project on to a "live server"?

I develop on my local machine with VS2010 and SQL Server. Naturally, my web.config points to my local SQL Server and I can debug/development and all is well. Unfortunately, I am not entirely sure on how to go about deploying my code to a live server.
Currently, my live server consists of a virtual machine (my site is accessible from the internet). When I'm ready to put my changes on the live server I publish my app (right click on solution explorer -> publish). Then I go to the directory it publishes to and dump all the files into a network share that goes to my site on the live server. On the initial copy over, I have to manually edit the web.config so that the connection string points to the SQL Server on the live server instead of my local machine. So this is my first stumbling block. How can I easily manage development settings and "live" settings in the web.config?
Now, I also use version control (Kiln). Can I possibly tag a changeset and have it automatically deployed to my live server somehow? Let's say someone submits a bug and I fix it. I push my changeset and now Kiln has the latest version of my code with the bug fix. What's the best way to get these changes on to a live server?
I'm unable to find any documentation that covers the entire workflow but I feel like there has go to be a better way. Surely, something like this can be accomplished without having to manually edit the web.config everytime I publish and pray to the computer Gods that I didn't miss something in the connection string.
It's just me so I have complete control over all of my environments, including the server and what's accessible via the internet, and anything is possible if only I knew what to do.
How can I easily manage development settings and "live" settings in the web.config?
Re: With VS 2010 web.config transformations, it is quite easy. Please take a look at this blog:
http://blogs.msdn.com/b/webdevtools/archive/2009/05/04/web-deployment-web-config-transformation.aspx
For VS 2008 or older, we used to have multiple config file based on environment and we used to create Debug/Release/DevTest/UAT/PROD release configuration and then in the post build event we used to replace the web.config with the release configuration based config. For example - if you build the project using "Prod" release configuration then we copy the PROD web.config to the publishing folder.
Now, I also use version control (Kiln).
Can I possibly tag a changeset and have it automatically deployed to my live server somehow? Let's say someone submits a bug and I fix it. I push my changeset and now Kiln has the latest version of my code with the bug fix. What's the best way to get these changes on to a live server?
Re: Source control and publishing to live server are two different things. The first question you are asking here related to how you manage multiple releases and have control over bug fixes for each release. The way I would do it is I will have PROD branch in my source control which will be the first release and for every major release I will sub branch it to have more control over e-fixes.
For the other question about how to get it to live server, it depends on your environment. We do it differently based on how customer environment is setup. If they have given us the FTP, we use that or otherwise we package the application into an MSI and then deploy it to UAT.. Until UAT signoff is done, we keep on updating the MSI. Once signoff received, the MSI goes to PROD.
Hope this helps.

Web.config Versioning

Currently I am using a shared database model for our development. I know, it's better to use local development databases to do database versioning the right way without one developer breaking everyone else's code. So that's what I'm trying to get to. I have a question about the web.config file though. How do I ensure that once every dev has his own local development database, he doesn't have to manually change the DB connection string every time he gets an update from source control? What's the best way to do this?
For example, say Johnny Dev commits his web.config that holds a connection string like this:
server=JohnnysBox;database=JohnnyAppDev1;
So now Susie Dev gets an update and she has to change her connection string to this:
server=SUE;database=development;
So now Susie and Johnny keep committing their own connection strings to the web.config file, and every time they get an update, they have to change the connection strings in all applications.
What's the best way to handle this situation so that devs don't mess up each others' connection string settings, but can push other kinds of config file changes to all the other devs when necessary (like a new app setting)?
It's only a partial solution, but you could have all the developers create an alias for their own SQL server using cliconfg.
Then the web.config in source control will have eg:
server=LocalServerAlias;database=development
For configuration or settings files, what you need to version is:
a template files (server=#USER_NAME#;database=#DATABASE_NAME#;)
one or several value files
one script able to replace the variables by the right values
What we do here is to never commit the web.config file to source control. Instead, we commit a web.config.sample file, and each developer merges changes in that file into their own personal web.config file. It's each developer's responsibility to handle those merges.
The way I deal with this is to just not check in developer-specific changes to config files.
When a config change needs to be checked in, I start from a 'clean' config file and make the needed changes, then check in. When everyone else does a get latest, they can merge these changes into their local versions.
The solution we came up with at my office was that we specifically exclude the web.config from version control, but only in the www folder. This allows developers to make whatever changes they need locally.
In a separate folder, we have a "master" copy of the web.config which is version controlled. As new sections, keys, etc. are added, it's the developer's responsibility to update the master copy.
You can create multiple Web.config files depending on the environment the application is running in. Using the transformation syntax you can modify the main Web.config to include or comply with your own local settings.
http://msdn.microsoft.com/en-us/library/dd465326(VS.100).aspx
Afterwards, exclude this custom Web.xxx.config from your repository.
We branch the web.config. So, i've got one called Mattweb.config and I can change it at will, and it replaces the web.config ON MY LOCAL MACHINE ONLY with the contents of Mattweb.config. It's requires no intervention by me.
We also branch the "real" web.config, so that I can compare with my own local version to see if any appsettings were added or any other types of changes. Then I just update my Mattweb.config file and all is well again.
Use (local) as the sql server name and it always refers to the local server. This should be the default value in the web.config you check into source control.
For production "installs", your installer should ask the user if they want to use a remote sql server and if so, update the web.config files as part of the install process.