laptop and beach ball - visual

Config management in Drupal 8: the set-up (part 2/3)

Niels A
Drupal 8
Drupal

In the first part of this three-piece blogpost, we explained the existing options for managing your configuration across environments. We also shed some light on grey areas between configuration and content. In this part, I’ll be showing you how to set it all up.
 

Back to part 1     Skip to part 3

 

Setting up configuration management

Configuring the splits

Start by installing the config split module, available here.

We like to keep our splits simple and clear. Currently, have four splits:

  • Blacklist: A split that doesn’t have a folder configured, so it doesn’t end up in our Git repository. This split usually has the same configuration as the config ignore module. The reason why will be explained in the part about config ignore.
  • Dev: A split that is used for our development environment-only configuration
  • Staging: A split that is used for our staging environment-only configuration
  • Live: A split that is used for our live environment only-configuration

Our blacklist configuration looks like this:

Blacklist configuration

If you don’t fill in the folder name, the Config Split module will export the config to a table in the database. That way, it doesn’t pollute your Git commits. For our other splits we use a folder outside our docroot for security reasons - e.g. for a dev split: ../config/splits/dev

Another important value here is the weight of the split. This weight will be used when multiple splits are active. The weight defines the order in which conflicting settings from splits get resolved. I will explain this in the part about the settings files, a little further down this post.

For the active checkbox you can choose whatever you want, because we’ll overwrite it later using the settings.php file. 

We’ve only been actively using the complete split configuration because it is pretty straightforward in how it handles your configuration. The additional configuration is handy because you can use wildcards. In the case of our blacklist, for example, we wanted to exclude everything from webform by using “webform.*”

We haven’t come across any use cases where we needed the conditional split, because we have a split active on every environment or the environment just needs the configuration from the sync folder.

Conditional split configuration

If you were to use it, the following use case would be perfect for it. For instance, you have some configuration you need on all environments but you want it to be different on one environment. In our example we want a different email to be set in the reroute e-mail settings on the staging environment. You would change it in the interface and then do a “drush csex staging” to export it to the config split staging folder. This will allow the config file to be present in the sync folder and in the split folder. 


Configuring ignore

 

First, install the config ignore module.

The important thing to know about this module is that it only ignores config on import. This is why we have currently set up a blacklist split. A new module called Config Export Ignore (available here) is also at your disposal, but we haven’t used it in our workflow because it doesn’t have a stable release yet. We will look into this in the future though, because the “blacklist” split feels like a hack in some way.

Our default config ignore settings look like this:

config ignore settings screenshot

As you can see, you can also add some special rules to your ignore settings. The only downside is that config split does not support these special rules. You’ll have to tweak your blacklist split a little bit and make your peace with the added files in your repo, until we find or create a solution for this. 


The settings files

To get this working across all environments, you need to have a settings file that is aware of its environment. This can be done using an environment variable that you check or use different files that get deployed based on the environment. There you set which config should be active on which environment. Sometimes it happens that you need multiple splits to be active on a single environment. You need to consider these splits as layers of config that you want to manage across environments. 

Our settings.php file on our development environment is identical to our local environment. It contains the following lines:

// Set your config directory outside of your docroot for security
$config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sync';

// Configure config split directory
$config['config_split.config_split.blacklist']['status'] = TRUE;
$config['config_split.config_split.dev']['status'] = TRUE;
$config['config_split.config_split.staging']['status'] = TRUE;
$config['config_split.config_split.live']['status'] = FALSE;

You might think that setting the staging split to true on the dev/local environment might be a mistake, but this is very intentional. As we are mostly using the complete split settings, this means that a config file can only be in one place. So we leverage the weight of the splits to also have certain staging config on our dev/local environment active. 
For instance, if we only want the reroute e-mail module to be active on local/dev/staging environments, we would add it to the complete split settings of the staging split.

Our settings.php for our staging environment will look as follows:

// Set your config directory outside of your docroot for security
$config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sync';

// Configure config split directory
$config['config_split.config_split.blacklist']['status'] = TRUE;
$config['config_split.config_split.dev']['status'] = FALSE;
$config['config_split.config_split.staging']['status'] = TRUE;
$config['config_split.config_split.live']['status'] = FALSE;

Consequently, the settings.php for our live environment looks like this:

// Set your config directory outside of your docroot for security
$config_directories[CONFIG_SYNC_DIRECTORY] = '../config/sync';

// Configure config split directory
$config['config_split.config_split.blacklist']['status'] = TRUE;
$config['config_split.config_split.dev']['status'] = FALSE;
$config['config_split.config_split.staging']['status'] = FALSE;
$config['config_split.config_split.live']['status'] = TRUE;

Our Rocketship install profile (blog post in Dutch) has all these things preconfigured, which enables us to create more value for our clients.


Deploying changes

When you want to deploy changes to your environments, the only thing you need to do is make sure the config files that you’ve exported using ‘drush config-export’ are on the environment you want to deploy. Using a versioning system like Git can greatly help you manage those files across environments. 

When you are ready to deploy your changes, just run the “drush config-import” command on that environment. Settings up drush aliases can save you a lot of time when you want to execute drush commands on remote environments. Read more about them here on this Drupal.org page.

Once you have this in place, you’ll be able to easily manage your configuration across environments. Go check out part 3 if you want to explore a couple of real world use cases and issues we’ve encountered.
 

Revisit part 1     Read part 3

Recommended articles
Drupal 8 migration strategies
Custom REST resources
Drupal 8 config management (part 1)
Dropsolid at Drupal Europe
Multiple Drush versions on one system