Config Split: A Guide to Conditional Configuration in Drupal 9

The config split module fills a critical gap in the Drupal core configuration management system. It allows for conditional configuration. What does that mean? Well, sometimes there are modules that you want to use for development (but not in production). Sometimes you need to configure services to point at different endpoints and/or use different credentials based on the environment you are working in (i.e. local/ci/dev/stage/prod). Maybe you have test content that you want to install during continuous integration (but no where else). Maybe you’re building a multisite platform and you don’t want all your sites to be named the same thing. All of these cases (and more) are easily handled by the configuration management system. However, the stock system doesn’t give you any sort of logic to vary your config. Never fear! Once again, the Drupal community provides a contributed solution to a core problem.

How does Config Split Work?

I really struggled to understand Config Split at first. It’s a really simple concept. It’s one of those things you look and go… surely it can’t be that easy. It really is (at least, to get started).

Config split requires a couple of things to implement:

  1. You have to define at least one split

  2. You have to configure that split

  3. You have to activate that split.

That’s pretty much all.

Config Split assumes you are doing some sort of conditional logic on your platform. Common examples of these are:

  • Environment: local / dev / stage / prod / ci

  • Install Profile

  • Site

But really, as long as you can programmatically determine “something” you could do a config split for it. Module splits? Theme splits? Day of the week splits? I mean sure, you totally could. I don’t recommend it. But you could!

Config Split provides a UI for you to define your splits.

Screen Shot 2020-08-05 at 9.17.21 PM.png

Basically, from here you need to:

  • name your split

  • define a folder to store the configuration (usually it’s config/<type of split>/<split name> — so the dev split would live in config/envs/dev)

  • uncheck the active box (more on this in a bit, just know that Config Splits should always be set to false)

There’s a ton of other config, but let’s pause there for a moment. Save the config for the split and export it. You should end up with a config file that more or less looks like this. The GovCon example here has a couple of modules in it already, but otherwise this is a pretty stock config split example.

The goal of a config split is to turn on some modules and/or install and/or override some configuration that is different from the config stored in your default configuration. You do not need to list out every single config file that you want to override. You do need to list out every module you want to enable via the split.

Config Split also provides the ability to flag config as an override (meaning it lives in both config default AND the split) or exclusive to the split. But you don’t have to worry about this right now!

Identifying and Activating Splits

Defining your splits is easy. Using splits is hard. This is where things start to get challenging, because a Config Split is only as useful as your ability to determine if it should be on or not!

Let’s use environment splits as an example. The GovCon repo has 4 environment splits:

Each one of these splits is defined as part of the default configuration for the site. So the YML files for the splits themselves live in config/default. The folder you define as part of the split tells Drupal where to find all the configuration that the split contains. So, when you turn on a split (e.g. local) and import configuration, Drupal first imports the definition of the split (which will enable any of the modules you’ve defined in the split). Then, you actually need to run another config import which will pick up any of the config files in the config split’s folder. (This is where it starts to get confusing).

So, how do we know which split to enable? Part of the reason I picked environment splits is because they’re pretty easy. If you happen to be an Acquia customer, we actually have an Environment Detector that you can pull into your codebase and use to determine which environment you’re in! BLT also does this automatically for you (and even activates the right splits).

If you aren’t an Acquia customer and/or you don’t use BLT, then you have a bit of lifting to do.

First, you have to use PHP to determine which environment you’re in. Most hosting providers provide some environment variables on their servers to help you do so. Just refer to your hosting docs.

Once you know what this looks like, you’ll need a basic switch statement. Based on the environment you are in, you’ll need a line of PHP sort of like this:

$config["config_split.config_split.ci"]['status'] = TRUE;

This line of PHP enables my CI split. Note that we are setting the split to TRUE here (which is why I had you set it to false earlier). Splits should only be enabled conditionally when the proper status is detected (otherwise, all your splits will be TRUE all the time and then all your splits will be on all the time. That sort of defeats the purpose!)

Impact of Configuration Management Strategy

I wrote recently on Drupal 9 Configuration Management Strategies and Config Split and its application are a big part of implementing those strategies. If you want to have environment specific config that changes based on the specific website you are on (meaning Site A’s dev environment has different config than Site A’s prod environment which has different config than Site B’s production environment) you can totally do that with Config Split as long as you can write the necessary logic to identify when the splits should be on or not.

However, I want to issue a strong warning here. Remember that just because you can do something that doesn’t necessarily mean that you should do that thing. Can you write a bunch of hyper specific logic and have a ton of splits? Yes. Does that make your platform super complex, difficult to update, impossible to test, and a giant pain in the ass? Also yes.

The rule of thumb with splits and a configuration management strategy in general is to keep it as broad and simple as possible:

  1. Keep as much of your configuration as possible in config/default (which applies broadly to all sites and environments)

  2. Keep the overrides simple (enabling a few modules, changing some simple configuration)

  3. Avoid entity configuration in splits (e.g. changing a content type)

  4. Minimize the number of splits: it’s generally assumed that environment splits are standard. If you also have site splits, don’t do nesting logic (so the dev split is ubiquitous for all sites on the platform, meaning that all sites that have their own config share the dev split, not a bespoke dev split for each site split).

  5. Automate testing for each split

Example Config Split Strategy

Here’s what we do on GovCon. Since GovCon is hosted at Acquia and we use BLT, all of the environment detection is handled by BLT for free out of the box. If you’re curious what that looks like, check out the config settings file. BLT also handles importing the configuration for us during our configuration management workflow.

Local Split

The local split enables a few modules (like DBlog, UI modules for Views / Webform, etc.) and contains overrides for config (like disabling the caching on the site). Note that our default content does NOT have these modules and config setup in them.

CI SPlit

The CI split is only used on this site to add some content for testing. There isn’t anything else fancy.

Cloud Splits

The dev / stage / prod splits are virtually identical and turn on the syslog and acquia connector modules and have a config override for the environment indicator. That’s all.

Note: this is a super common setup for me and it’s one I use on numerous customer builds. Obviously the splits will vary in specific implementation and complexity, but the basics are all in the GovCon repo.

Working with Config Split

Config Split goes from “really easy” to get started to “more difficult” to define logic and put into practice to “pretty freaking hard” to use successfully on a large development team. Anytime a developer begins work, it’s critical that that individual know where the work will ultimately live. Is it going in default content? Is it going in one or more splits? Are there variations on the feature that need to be build based on where it will ultimately reside? Make sure that as you implement config split you thoroughly train your developers on the configuration management workflow, explain your configuration management strategy, and whatever you do, take the time to thoroughly explain where each ticket’s implementation will ultimately reside.

Remember: the more splits you have, the harder it is to do everything.

In Conclusion

Config Split is a module I literally use on every build with Drupal 8 and 9. It’s a critical component to ensuring the success of that build, wether it’s a single site or a multisite platform. If it’s not a tool you’re familiar with, I strongly recommend familiarizing yourself sooner than later. It will change the way you build in Drupal (for the better)!

Related Content