Using Configuration Split to have dev-only configuration in Drupal 8

The problem

If you are using Drupal’s Configuration Management subsystem to deploy configuration out to the production environment, you’ll run into a problem where the configuration .yml files contain your development settings.  To avoid this you’ll need to use the Configuration Split module

I couldn’t find any good documentation for this, so I had to figure it out by trial and error.  Here’s the results of my investigations.

Development-only modules

In the simplest scenario, we want to enable a few extra modules on development environments (Devel, Kint, Stage File Proxy, Views UI, etc.), but not have these modules enabled on production.  For this we’ll need to create a new Configuration Split Setting for the development environments.

But first:

  1. Ensure that you have no config overrides.
  2. Enable Configuration Split module in a local environment.
  3. Export config, commit and deploy to the live environment as you usually would.
  4. Enable and configure all your development modules in the local environment.

Create a Configuration Split

Navigate to:

Administration » Configuration » Development » Synchronize » Configuration Split Setting » Add configuration split setting

Creating a new split configuration.

There’s a few things that will help you keep your sanity, but aren’t covered in the help text:

  • Keep the Machine name the same as the Folder.
  • The Folder is relative to the Drupal root (it does say this in the help text, I just skimmed right past it the first time).
  • Active should be checked (more on this later).

And add your development modules to the Blacklist.  Stuff listed here will be ignored from the main configuration.  No need to also select their configuration, you only need to select the modules.  Disregard the Greylist (More on this later).

Export your configuration

From this point on, you will never have drush cex again.  For the first time that you export your configuration, use this:

# Create the directory.
mkdir sites/default/config_dev
# Export the development configuration
drush csex config_dev
# Export the main configuration
drush csex

Greylists

As mentioned in the help text, this isn’t a great name, but it’s basically used for configuration that should have different values in different environments.  E.g. Payment processing configuration, Stage File Proxy URLs, Solr URLs, etc..

I’m not a fan of using Config Split for this.  I prefer to keep all this in settings.php.  Then it’s all in one place, you can easily see all the variations between environments, and if you need to make a change you’ll be less likely to forget something.

At the top of settings.php you’ll need some logic to determine which environment you’re in.  We almost exclusively use Pantheon, so we’ve got the following:

// The environment the current site is running on.
// Possible values: local, dev, test, live.
// Configuration further in this file sets different settings for different
// environments.
if (defined('PANTHEON_ENVIRONMENT')) {
 switch (PANTHEON_ENVIRONMENT) {
    case 'kalabox':
      $config['server_environment'] = 'local';
      break;

    case 'dev':
    case 'test':
    case 'live':
      $config['server_environment'] = PANTHEON_ENVIRONMENT;
      break;

    // Multidevs.
    default:
     $config['server_environment'] = 'dev';
 }
}
else {
 $config['server_environment'] = 'local';
}

Pantheon only supports sites/default/settings.php.  But if you are hosted elsewhere, then another method is to use different sites directories for different environments.   

Enabling the split configuration in development environments, but not production

Remember that active checkbox from above?  That’s what defines whether the configuration split is enabled or not.  The trick is that we want to have that setting be different on different environments.  This can be done in settings.php, leveraging the code block above.

// Use development config in dev environments.
if (in_array($config['server_environment'], ['live', 'test'])) {
 $config['config_split.config_split.config_dev']['status'] = FALSE;
}
else {
 $config['config_split.config_split.config_dev']['status'] = TRUE;
}

Make sure to use the same machine name as you configured previously.

Development Workflow

Three things to note:

  1. You don’t need to use any of the following Drush commands, you can still use the UI at:
    Administration » Configuration Development » Synchronize
  2. If you prefer Drupal Console, there’s equivalent commands.
  3. At the time of this writing Pantheon uses 8.1.3.  If you have Drush >= 8.1.10 you’ll be able to use the old cex and cim commands.

Pulling a database from production to a dev environment

The first step is to get the database.  How to do that depends on your hosting and local environments.  We’re fans of Kalabox, and the command is real simple:

kbox pull

Then import configuration

# Clear caches
drush cr
# Then import the development configuration only.
drush csim config_dev
# Check for config overrides from production, and get those back into code.
drush csex

Pushing configuration from dev to production

In the dev environment

After you made some configuration changes:

# Export the configuration.  
# This will update both config and config_dev.
drush csex

In the pre-production / production environment

# Import configuration.
# This will import config; and if active in settings.php, config_dev
drush csim

Next Steps

The above should be able to handle 95% of Drupal sites.  But if you’ve got more complicated requirements, you can always add more splits.

Automate all the things

Running a set of magic commands every time you push code or move a database from one environment to another is error prone, and a bit of a time waste.  You can automate all of this using Pantheon’s Quicksilver.  On Kalabox the automation is a bit trickier (you’d need to create a custom plugin, which isn’t a well-tread path), but we have high hopes for its successor: Lando (currently in alpha).