Drupal Config

The configuration system for Drupal 8 and 9 handles configuration in a unified manner.

By default, Drupal stores configuration data in its (MySQL) database, but configuration data can be exported to YAML files. This enables a sites configuration to be copied from one installation to another (e.g. dev to test) and also allows the configuration to be managed by version control.

TIP: Configuration data (aka settings) includes information on how custom and contributed modules are configured. Think of configuration as the way developers define how the Drupal back-end functions, and what options will be available to content authors.

  • Configuration is very different to content. Content is information which will be displayed to website viewers in Drupal nodes. Content is also stored in the database, but is not managed by the configuration system.

See this Drupal Framework Elements Overview.

Core Configuration Management Utilities

Drupal has a built in configuration management system, along with drush CLI commands to import and export configurations.

  1. Configurations are saved in a folder (the config sync directory) on the webserver hosting the Drupal website. This folder is defined in the settings array $settings['config_sync_directory'] which is defined in the settings.php file. This folder is defined relative to the docroot folder typically outside of the docroot for example:

    $settings['config_sync_directory'] = "../config/default";
  2. drush cex exports configurations from the the database into the config sync directory.

  3. drush cim imports configurations from the config sync directory into the database.

  4. Module Exclusions: The Configurations for an entire module can be excluded from both of the drush cim / cex processes by defining them in the $settings['config_exclude_modules'] array in the settings.phpfile. For example:

    $settings['config_exclude_modules'] = [  'devel', 'syslog' ];

WARNING / CARE: If you add modules into this list, then they will be removed from the core.extensions.yml file during the next config export. This means these modules will be uninstalled/disabled on any environment in which these configs are imported.

As a rule of thumb - only add modules to this array that you wish to be removed for all environments other than the one you are developing on.

The Drush CLI is the main CLI utility and is installed and enabled on the CoB Drupal backend.

config:delete (cdel) Delete a configuration key, or a whole object.

config:devel-export (cde, cd-em) Write back configuration to module's config directory.

config:devel-import (cdi, cd-im) Import configuration from module's config directory to active storage.

config:devel-import-one (cdi1, cd-i1) Import a single config item into active storage.

config:diff (cfd) Displays a diff of a config item.

config:different-report (crd) Displays differing config items.

config:edit (cedit) Open a config file in a text editor. Edits are imported after closing editor.

config:export (cex) Export Drupal configuration to a directory.

config:get (cget) Display a config value, or a whole configuration object.

config:import (cim) Import config from a config directory.

config:import-missing (cfi) Imports missing config item.

config:inactive-report (cri) Displays optional config items.

config:list-types (clt) Lists config types.

config:missing-report (crm) Displays missing config items.

config:pull (cpull) Export and transfer config from one environment to another.

config:revert (cfr) Reverts a config item.

config:revert-multiple (cfrm) Reverts multiple config items to extension provided version.

config:set (cset) Set config value directly. Does not perform a config import.

config:status (cst) Display status of configuration (differences between the filesystem configuration and database configuration).

Configuration overrides

It is possible to override configurations in the php files on the Drupal back end.

Global Overrides

Normally the configurations a developer will wish to override will be in a xxx.settings.yml file. This is where settings type configurations are defined and saved by contributed and custom modules.

The strategy to globally override a config setting for the entire Drupal site is to alter the $config array in the settings.php file.

Because the main settings.php file can include different settings files for different environments, we can add global overrides to an environment-specific settings.php file to implement an override for only that environment.

TIP: Code in a settings.php file can be conditional, so the override can be made to be conditional on the value of a local (or environment) variable.

Example 1- Core config override: The system.maintenance.yml file contains a messagekey to control text that appears on the site maintenance page when shown. To override the message key set in the system.maintenance.ymlfile, place this in an appropriate settings file.

$config['system.maintenance']['message'] = 'Sorry, our site is down now.';

Example 2- Custom/Contributed Module config override: The salesforce.settings.yml file supplied by the salesforce module contains key to authenticate against a salesforce.com account in order to sync data. To override the consumer_secret key set in the salesforce.settings.ymlfile, place this in an appropriate settings file.

$config['salesforce.settings']['consumer_secret'] = '1223425';

Override/Secrets Best Practice:

It is best practice not to save passwords and other secrets (incl API keys) in configuration files, as these will end up in repositories, and could be made public by accident.

Instead, passwords and other secrets should be stored as Environment variables on the Drupal web server, and then be set in an appropriate settings.php file.

Example: recaptcha secret key saved as environment variable bos_captcha_secret

$config['recaptcha_v3.settings']['secret_key'] = getenv('bos_captcha_sphpecret_key');

This means that passwords and other secrets are saved on the environment to which they apply so there is less (or no) need for environment-specific overrides.

It also means that all secrets are managed the same way, and can be changed on the environment and take effect immediately without needing to redeploy any code.

Accessing config variables in code

PHP commands retrieve a current configuration settings are as follows:

// Get the site name, with overrides.
$site_name = \Drupal::config('system.site')->get('name');

These commands will get the original config value, ignoring any overrides:

// Get the site name without overrides.
$site_name = \Drupal::config('system.site')->getOriginal('name', FALSE);
// Note that mutable config is always override free.
$site_name = \Drupal::configFactory()->getEditable('system.site')->get('name');

This information is adapted from this Drupal Resource, and contains more advanced techniques and discussion.

Contributed Config Management Modules

To assist with configuration management, there are a number of contributed modules.

The contributed modules are generally deployed to help manage situations where different configurations are desired on different environments.

gitignore

Although this is not a contributed module, the use of .gitignore allows a way to prevent configurations from making their way into repositories, and replicating upwards from the local development environments to the Acquia dev/stage/prod environments.

Simply add specific config files (and/or wildcards) to the .gitignore file in the root of the repository.

Provided the files do not already exist in the repository, they will be ignored by git during commits and pushes from the local repository.

Example: .gitignore in repository/project root.

...
# ignore settings files with possibly confidential information in them
bos_emergency_alerts.settings.yml
...

TIP: If you don't prefix the entry with any folder paths, then all occurrences of the file will be ignored. This includes files from config exports (drush cex) and also from config_devel exports (drush cde - see below.)

Config Ignore

This module provides configuration import protection. If you are concerned that importing certain configurations when using drush cim (which is used during a deploy) will overwrite existing configurations on a site, then config ignore will help prevent this.

Specific files to be ignored during an import can be added to the ignored_config_entities key of the config_ignore.settings.yml file. This array can also be overridden/extended by altering the $config['config_ignore.settings']['ignored_config_entities'] array in an appropriate settings file.

\\ Just override any config_ignore settings that are already set.
$config['config_ignore.settings']['ignored_config_entities'] =
    [ ... new entries ... ]  

\\ Merge and deduplicate the existing config with these manually added entries.
\\ Caution, this has a (small) performance impact as this merge/dedupe occurs
\\  on each bootstrap of the drupal framework (i.e. each page request/API call)
$config['config_ignore.settings']['ignored_config_entities'] =   
  array_unique(array_merge(    
    $config['config_ignore.settings']['ignored_config_entities'],    
    [ ... new entries ... ]  
  ));

The .yml extension is dropped and wildcards can be used to select entire modules, entities, etc:

ignored_config_entities: - salesforce.settings - ... - 'core.entity_view_display.node.metrolist_development.*'

Note: This module only provides protection when drush cim is executed. When drush cex is executed, the config_ignore settings are not considered and a full set of configs is still exported.

If you can't use $settings['config_exclude_modules'] (because you maybe only want to exclude just the module.settings.yml file from a module) then use gitignore to stop it being committed to the repo and deployed.

CoB Local Development.

CoB use config_ignore as a fail-safe protection.

Configurations that are set in the production system at runtime (usually settings) via the UI and are therefore different to the config in the ../config/default folder are added to config_ignore so that they cannot be imported over the site settings should the files exist in the folder.

Config Split

This module provides configuration separation. Configurations can be split into different folders and imported/exported independently.

Drush Command Summary:

config-split:activate Activate a config split. config-split:deactivate Deactivate a config split. config-split:export Export only split configuration to a directory. config-split:import Import only config from a split. config-split:status-override (csso) Override the status of a split via state.

Config split can be used to create a number of different configuration sets which can be applied on different environments and/or at different times. This is an ideal way to control which modules are installed on which environments, and even to provide environment-centric settings (for settings controlled via config).

Config Devel

This module provides custom module configuration installation. If you anticipate your custom module will be used as a "contributed" module on another site - or will be enabled or disabled individually - then you will want to save its configuration into an install folder inside the custom module.

Drush Command Summary:

config:devel-export (cde, cd-em) Write back configuration to module's config directory.

config:devel-import (cdi, cd-im) Import configuration from module's config directory to active storage.

config:devel-import-one (cdi1, cd-i1) Import a single config item into active storage.

Last updated