BuildMaster Documentation

Configuration Files

  • Last Modified: 2018-08-22

Many applications rely on configuration values that are stored in files that are stored alongside application executable files, such as web.config in .NET or .properties files in Java.

These configuration files often need to be managed independently from other files in a release package because their contents will change from environment to environment, and even contain sensitive data such as database connection strings, third-party service URLs, API keys, etc.

BuildMaster provides two strategies for managing configuration files: text-templating and configuration file assets.

Text-templating

Text-templating is the preferred method, and relies on the text templating in the Inedo Execution Engine, along with configuration variables and conditionals for environment-specific settings.

There are several advantages to using this method over configuration file assets:

  • Allows for the use of if/else conditionals, loops blocks, and access to all variable functions (i.e. $ArtifactPath(...))
  • More familiar to developers, and is how nearly all other build and deployment tools manage configuration file deployment
  • You can store the majority of your template in source control, alongside the code, and store only variables in BuildMaster

Configuration Files Assets

Configuration file assets stores multi-instance configuration files, and provides a multi-tabled editor to edit and compare these instances.

  • File contents are compared before deployment and will not deploy the file if the contents have not changed
  • Deployments are separately logged
  • Version history is maintained and allows for arbitrary comparison between instances and versions
  • You can "manually deploy" outside the scope of a deployment
  • Restrict certain instances from being viewed or edited using access controls

Naming

Configuration files should be named after the file they represent, e.g. web.config. These names are unique per application. In cases where there may be multiple files with the same name within an application, aliases may be used to uniquely identify them in the UI. When deploying a non-unique configuration file, make sure to specify the name of the output file directly.

Instances and Versions

Each configuration file contains at least one instance, and instances may be associated with an environment. A configuration file is versioned as a whole – meaning any changes made to any instances increments the version number. Instances should generally be named after the environment the file will be deployed to.

Security and Permissions

Permissions may be assigned to users by associating an environment to a configuration file instance and granting or restricting any of the following tasks:

  • Deploy
  • Edit Instance
  • View Instance

Template Instances

Configuration file templates are designed to simplify deployment of configuration file instances that contain virtually identical content except for minor, environment-specific differences. The item that contains the placeholders for substitution is referred to as the template, and the item that contains the substitution values is referred to as the template instance. BuildMaster supports three types of transform syntaxes:

Key-Value Pair

Template instances are specified as newline-separated key-value pairs, and each key-value pair is separated by an equals sign. Additional equals signs on the same line are permitted and included in the replacement value. If the value requires a newline, the $NewLine variable function may be used.

  • Template
  • Template Instance
  • Result
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
    <add key="Core.DbConnectionString" value="$ConnectionString" />
    <add key="IntegratedWebServer.Enabled" value="True" />
</appSettings>
ConnectionString=Data Source=localhost;Initial Catalog=BuildMaster;Integrated Security=SSPI;
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
    <add key="Core.DbConnectionString" value="Data Source=localhost;Initial Catalog=BuildMaster;Integrated Security=SSPI;" />
    <add key="IntegratedWebServer.Enabled" value="True" />
</appSettings>

XSLT

Templates or their instances may be used as XSLT stylesheets and XML data that will be automatically transformed before deployment. In most cases, "XSL Stylesheet as Template" is the desired transform option because the XML data would be stored in the template instances.

  • Data
  • Stylesheet
  • Result
<?xml version="1.0" ?>
<config>
    <connection>
        <value>https://example.org/v1/service1</value>
    </connection>
    <connection>
        <value>https://example.org/v1/service2</value>
    </connection>
    <connection>
        <value>https://example.org/v1/service3</value>
    </connection>
</config>
    
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/xhtml">

    <xsl:output method="xml" indent="yes" encoding="UTF-8" />

    <xsl:template match="/config">
        <html>
        <head>
            <title>Testing XML Example</title>
        </head>
        <body>
            <h1>Connections</h1>
            <ul>
                <xsl:apply-templates select="connection"></xsl:apply-templates>
            </ul>
        </body>
    </html>
</xsl:template>

<xsl:template match="connection">
    <li>
        <xsl:value-of select="value" />
    </li>
</xsl:template>

</xsl:stylesheet>
      
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Testing XML Example</title>
</head>
<body>
    <h1>Connections</h1>
    <ul>
        <li>https://example.org/v1/service1</li>
        <li>https://example.org/v1/service2</li>
        <li>https://example.org/v1/service3</li>
    </ul>
</body>
</html>
      

Variable Replacement

All configuration variables, runtime variables, and parameterless variable functions in context are considered when variable replacement occurs before deployment and follows the same resolution rules as configuration variable replacement.

Template file variables are treated as runtime variables when replacement occurs, and therefore override any configuration variables. In practice, it is not recommended to have template instance variables override existing configuration variables or variable functions. It is also not recommended to rely on runtime variables created during a deployment.

Empty/Missing Variables

Variables or functions that exist but do not have any value (e.g. $DeployableName when no deployable is in context) will be replaced with an empty string, and variables that do not exist will remain as literal strings. It is not recommended to have a configuration file that falls into either of these cases.

Escaping Variables

There are many cases where a configuration file needs to contain literal text that appears to be a variable name. In this case, escape any $ signs with another $, e.g. $$DoNotProcess.

Deployment

Automated Plan-Based Deployment

The most common method of deployment is the Deploy Configuration File operation (Deploy-ConfigFile in OtterScript). When this operation is executed during a deployment, the version of the configuration file instance associated with the release currently in context will be deployed to the target path. If there is an existing file at the target path, it will only be overwritten if its text contents are different than the configuration file text in BuildMaster, otherwise the operation effectively becomes a no-op.

Manual One-Off Deployment

Configuration files may also be deployed outside the context of a deployment. It is not generally recommended to deploy configuration files in this manner because much of the context associated with the plan-based deployment is lost (e.g. release number, package number). One-off deployments should be reserved for "emergency" cases that require a configuration change immediately without the overhead of the traditional release cycle.

History

Deployment history for configuration file instances is stored for configuration files deployed from BuildMaster. The instance, version number, user, and date of deployment is visible, as well as the ability to compare arbitrary versions to highlight what changes were made to an instance.

Association with Releases

A release may be associated with a specific version of a configuration, or if unspecified, associated with the latest version. By default, a release is associated with the latest configuration file version. When a release is deployed to the final stage in a pipeline, the current latest configuration file version will become associated with that release to preserve the contents at that point in time, facilitating future rollbacks if necessary.

Differences Between Configuration File Strategies

While using text templates is a powerful yet simple replacement for Configuration File Assets, there are some important differences:

  • Configuration file assets will compare file contents before deployment and will not deploy the file if the contents have not changed
  • Configuration file assets maintain version history and allow arbitrary comparison between instances and versions
  • Configuration file assets allow "manual deployment" outside the scope of a deployment
  • In contrast to configuration file assets, text templates allow the use of if/else conditionals, loops blocks, and access to all variable functions (i.e. $ArtifactPath(...))
  • Text templates only support OtterScript-style variable syntax (i.e. the legacy %-syntax and $-syntax are not supported)

Have a question? Try the Q&A Forum

Our documentation is now Open Source and on GitHub. We highly encourage our users to contribute and get involved! .