Alright, I haven’t done a post on Drupal 9 configuration in a while. And since I’ve been dealing with some configuration stuff recently at work, I thought I’d share!
Scenario: we need to “change” Drupal configuration.
Methodology: …it depends.
Changing config is a highly conditional (and potentially controversial) task in Drupal. Why? Well, the question is how / why are you changing it. Here are some examples to consider:
When I install my <thing> I want to create some <stuff>
When I deploy my site I want to change <something>
When I’m in my production environment I want a different API key for my <service>
I am doing some testing and need to turn on an additional module
Obviously each of these scenarios above is a slightly different variation on the theme of changing site config. Unfortunately that means that there may be one (or more) methods of adjusting the configuration for each! Let’s dig into some of the most common ways to handle configuration changes.
Ways to Change Drupal 9 Configuration
Config Directory for Config Import/Export (project)
This is my personal go to for nearly “all” configuration changes. Yes, this creates a big ol’ config directory with hundreds (or thousands) of files, but anytime you want to change config, you can rewrite that config during a config import. See more about this topic in my other configuration series.Config Directory (module / profile / theme)
This is the “core” way of doing Drupal configuration. You can bundle up config file files in your module / profile / theme and Drupal will automatically install them for you when you enable the thing.
Good news: it installs!
Bad news: it doesn’t update !!!
This method works great for partial configuration management strategies (a la features in Drupal 7). Just keep in mind that you are on the hook for writing update hooks in your module’s .install file any time you want to change config after install (and let’s be honest… you’re going to want to eventually change config).
Drush
Drush gives you some super slick config commands like cget and cset to allow you to change config quickly from the command line. This isn’t a viable strategy for “long-term” management of config, but it can be used for a quick change!Drupal UI Change
Similar to the Drush example above, you can always change the config via the UI (but again, you should rely on your configuration management strategy to do the change for you in the real world and longterm).Install / Update Hook
The .install file in your module is a great place to make config changes. Warning! These config changes are usually “much” more complex than just exporting YML. Why? Well, you have to use the Drupal config service to load / save config and you have to actually get in and muck about with the config in PHP (vs just using Drush to sync a file).
Having said that, if you aren’t using a full config sync and/or there are reasons you cannot rely on a YML files, this is a great method of changing config. Here’s a quick example.Submit Handlers
Remember, config is (and can be) used in custom code as well. Blocks, admin forms, etc. are all common places to use config! So you may need to write a custom form that loads config or a submit handler that sets it.Settings File
The entire $config object can be overridden in your settings.php file. I generally recommend against making config changes here (see the config overrider service example next on this list) but you “can” do it (and there are times when it makes sense). I very commonly use this method with a LOCAL settings file for things like solr servers and other local specific config that are simpler to override in PHP than in a config split.
Why might PHP in this case be simpler? To override config in a config split, you have to store the entire config file. For a solr server config file that can be a lot of config when all you really need to do is change one line.
Note: settings files also can be used for things like a platform-level secrets file. See more about this on Acquia’s documentation site.Config Overrider Service
Finally, if you do need to do a code override (and not a config split) AND you don’t want to do it in the settings.php file, you can use a Config Overrider Service. This is one of the most complex methods of doing a config change because it requires the definition of a new service, but there are times when they are necessary. Again, not using config split / a full config workflow sometimes leads to necessary workarounds and this is a great tool in that scenario!
Revisiting Our Scenarios
So, let’s look at our scenarios from above:
When I install my <thing> I want to create some <stuff>
this could be module-based config
this could be a config in PHP via an install hook
When I deploy my site I want to change <something>
this is mostly likely a config directory change
it could also be an install / update hook in a module
When I’m in my production environment I want a different API key for my <service>
this is likely a config split
but it could be conditional config running in an update hook
it could also be a settings override or a config overrider service
I am doing some testing and need to turn on an additional module
this could be drush
this could be the ui
it could be a more permanent fix using one of the other methods!
Conclusion
One of the reasons I spend so much time talking about Drupal 9 configuration is that config is just plain hard. There are a lot of ways to do it, they don’t all work the same way, and unfortunately some are very much “the wrong tool for the wrong job.”
Planning the architecture of your configuration is a non-trivial journey that you should take on ASAP and integrate as early as possible if your development process. There is a ton of related reading below on the topic and other articles I’ve written. Good luck!
I hit a couple of issues updating to Drupal 9.3, so I wanted to share my experience. Config changes incoming!