In the latest experiment we are exploring ways to have one (1) build for an Azure App Service type application, deployed to many (n) environments.

Context

Let's assume our POC has four environments:

  1. Development (DEV)
  2. System Test (ST)
  3. Load Test (LT)
  4. Release Candidate (RC)

If we use a web.config file for each environment, or use the default SetParameters.xml file generated by the build, we have duplication and need to re-build for each environment. No good, we want one build!

Options

We're exploring these options:

OPTION PROS CONS
Use a custom generated SetParameters.?.xml file for each environment, used by the Azure App Service (v3) task to update web.config. Configuration stored in source control Duplication of the SetParameter files
Tokenise (2) the SetParameters.?.xml during build and release Fine tune configurations using release variables Variable values stored in two places
Use release environment variables (1) that are substituted in the web.config file by the Azure App Service (v3) task. Integrated and simple. Configuration is not stored in source control

Slide8-1

Let's peek into the proposed flow we're investigating:

START

  • We start with a web.config file that has four application settings called realm, environment, magicvalue and poc. All values are set to "unknown".
    Web.config before

BUILD STEPS

  • Build task generates the SetParameters.xml file, which we ignore.
  • We copy all custom SetParameter files (SetParameters.[DEV|ST|LT|RC].xml) to the build artifacts staging directory at the end of the CI build. Each file is stored in source control and defines a value for poc and a __PROJECT__ token placeholder for environment.
    SetParameters Example

RELEASE STEPS

  • Define two release variables for realm and PROJECT, for each environment and assign a value.

  • Azure Key Vault task retrieves the secrets, which includes the magicvalue, and creates a temporary release variable.

  • Replace Tokens task scans the SetParameters files and replaces the __PROJECT__ token with the value of the environment specific PROJECT variable.

  • In the Deploy Azure App Service task enable the XML variable substitution option and point to the environment specific SetParameters file.

  • Custom SetParameter files allow users to store the configuration in soure control and point the Azure App Service task to the relevant environment specific file.
    SetParametersFile

  • As part of the deployment, the Deploy Azure App Service task substitutes the "unknown" defaults with the environment specific values.

For example:
Web.config after

So simple, what are we missing?

Another option, not covered by our experiment, is set set Azure Application Settings with a PowerShell script. See How to configure Azure Web Application settings via PowerShell for an example.

So, what are your thoughts? Ping me on @wschaub and I'll update this post with your feedback.

If you're looking for more detail, read - Colin's ALM Corner Build & Release Tools, Deploy: Azure Key Vault. Deploying Web Applications Using Team Build and Release Management, Replace Tokens, and Using Azure Key Vault Secrets for your VSTS Releases.

Special Thanks

THANK YOU to Dennis Hsu and Colin Dembovsky for their input