Drupal 8 configuration management workflow for multisites

I’m going to document how I handle a project at work with many, many (150+) multisites using Drupal 8 and configuration management. When thinking of what to write for this post, I pretended that this is the blog post I wish I read at the beginning of the migration process from Drupal 7 to Drupal 8.

This took a lot of research, trial, and error to come to this workflow but it seems to work really well right now and I’m sure will be helpful to someone else looking to take advantage of configuration management in Drupal 8.

We used to use Features with Drupal 7 to enable/disable features across our sites. For a while I kept trying to fit D8’s configuration system into that old paradigm. If you are doing the same, clear your mind and start fresh, it won’t serve you to think about how things were done in Drupal 7.

90% of our sites will use a similar configuration. But there’s a small subset of sites that require a special content type and other functionality around that content type (views, permissions, etc).

So we needed a solution that that provided a base configuration that would be shared across all sites, then individual functionality could be enabled per site, similar to the table below.

SiteFeature 1Feature 2Feature 3
Office of Business RelationsX

After much trial and error, the setup that ended up working for us is

  • Setting up a “default” configuration
    • New multisites are installed from this and changing the default configuration will result in all sites being updated with this new configuration
  • Use config_split module for additional configuration/features
    • These are additional configuration items that can be added per site. For example, if there’s a content type that is needed on only a subset of sites, a feature split is needed
    • This module also allows for environment-specific splits which can be enabled on a particular environment, for example if you want a different configuration on your development environment.

Under the hood, there’s no difference between site splits and feature splits, it’s just a helpful way to categorize use cases. It’s helpful for me to understand it as: Site splits are typically one to one, whereas feature splits are usually enabled on many sites.

Set up the “default” configuration

By default, when you export configuration using drush cex it will export to the default configuration location that is set in settings.php which if it isn’t set is config/default.

Go through the normal build steps of a Drupal site, the important things are

  • Set up content types/paragraphs/blocks the way you’d like
  • Configure image/media styles
  • Get a theme

Once the site is (mostly) set up the way you want, export the site’s configuration using drush cex. There are ways to update this default configuration so if it needs tweaking in the future, that is still possible.

Here’s the process used to make configuration changes to the default configuration:

  1. Make local environment is up to date, by pulling the latest of each branch.
  2. Checkout the develop branch
  3. Run drush cim to make sure config is synced with the code
  4. Login to a site with no config_splits active (a 100% default configuration site)
  5. Make the change to the field that you wish to see (for example adding a new field or modifying an existing field)
  6. Run drush config:status and review the changes you’ve made to see if they make sense
    1. For example, if you added a field, you should see config updates that have to do with that field
      1. Export the configuration changes by running drush cex
      2. Run drush config:status to make sure there are “No differences between sync and DB”
      3. Clear cache, then check the site to make sure it’s all good
      4. Commit those changes

Note: Using the default configuration directory also makes it so you can use the default config when installing new multisites under the “Use existing configuration” option shown below.

Create config splits

Since in my case, we were migrating from a previous version of Drupal, I had a bit of an idea of what things can be split out of the default configuration which was a major benefit. If this was a brand new project, there may be some difficulty in learning what needs to be split away from the default configuration until you’re more comfortable with the workflow.

Here’s the process that is used to create config splits locally for a new content type that is used on some sites but not all sites. Replace occurrences of new-content-type with your specific use case.

  1. Ensure that the config locally is synced to the latest version of config in your repository. When running drush config:status it should display No difference between DB and sync directory
  2. Create a config/feature/new-content-type directory for the new content type configuration
  3. Create the new content type
  4. Run drush config:status, this should display all the configuration keys that creating the content type modified, these are the keys that we want to split away from the default configuration. 
  5. Create config split using the UI ensuring the split directory I specify matches with the directory in step 2. (E.g: ../config/feature/new-content-type)
  6. Paste the values from drush config:status in the Complete Split “Additional Values” field and Save
  7. Run drush config-split:export new-content-type  Use the machine name for the config split
  8. Run drush config:status. There should be config_split.config_split.new_content_type.
  9. Run drush cex to put config_split.config_split.new_content_type into the default config.
  10. Since this should only be enabled on certain sites, disable the split by default by setting status: false within config_split.config_split.new_content_type
  11. Go back to /admin/config/development/configuration and revert back to config in config/default (Import all) or drush cim
  12. Add an entry into the settings.php file for the site you want to enable the split on $config['config_split.config_split.new_content_type']['status'] = true;
  13. Test the changes locally for the site you enabled it for
  14. Run ./drall.php cim -y
  15. Go to the New Site and run drush config-split:import new_content_type

Advice for starting

If you’re used to the Features module in Drupal 7, this is quite different but offers the same functionality in an overall more consistent way. I honestly prefer this method to managing configuration than using the Features module but it took me many months to feel that way.

At first it feels very foreign, confusing, and sometimes frustrating. A lot of the free video tutorials out there seem like they don’t exactly cover what you’re looking for but I would recommend sticking with it. Eventually as you become familiar with how the configuration system operates (and it’s quirks), you’ll be confidently managing your configuration.

Additional considerations:

  • With the @sites drush variable being removed, you will need a tool to execute drush commands on all of your multisites. After updating config, this tool will help import the config on your existing multisites.

Related Post

What do you think?