Drupal 8 Configuration - Part 3: Using the API
This is part three of a five-part series of articles exploring the Drupal 8 Configuration API, how it enables functionality to be migrated between multiple environments, and ways of using the Configuration API with contributed modules to effectively manage the configuration of a project.
We live in an age of Drupal complexity. In the early days of Drupal, many developers would have a single Drupal instance/environment (aka copy) that was their production site, where they would test out new modules and develop new functionality. Developing on the live website however sometimes met with disastrous consequences when things went wrong! Over time, technology on the web grew, and nowadays it's fairly standard to have a Drupal project running on multiple environments to allow site development to be run in parallel to a live website without causing disruptions. New functionality is developed first in isolated private copies of the website, put into a testing environment where it is approved by clients, and eventually merged into the live production site.
While multiple environments allow for site development without causing disruptions on the live production website, it introduces a new problem; how to ensure consistency between site copies so that they are all working with the correct code.
This series of articles will explore the Configuration API, how it enables functionality to be migrated between multiple environments (sites), and ways of using the Configuration API with contributed modules to effectively manage the configuration of a project. This series will consist of the following posts:
- Part 1: The Configuration API
- Part 2: How the API works
- Part 3: Using the API
- Part 4: Extending the API with contributed modules
- Part 5: Module developers and the API
Part 1 gives the background of the Configuration API, as well as discusses some terminology used within this article, and Part 2 describes how the API works, so they are worth a read before beginning this article.
Defining configuration directories
Configuration files are stored in configuration directories. On installation, a single default configuration directory is defined, but this directory can be changed in settings.php, and additional directories can be also be added in settings.php. Each directory has a unique key that is used to identify which directory should be used when importing or exporting configuration. The default directory Drupal creates upon installation, with the key 'sync', will look something like this:
$config_directories['sync'] = 'sites/default/files/config_4IM0aPRcEU-wTn6Z1nfQbEVTUMu5QKtsu5D2UM4QO-IOFNdAg2KEaKaf4qxFme8k4cj5pnQQig/sync
This declaration says that the directory that can be referred to as 'sync', can be found at
sites/default/config_[HASH]/sync. A good practice is to move the configuration out of the webroot, and set the path to be relative, for example:
$config_directories['sync'] = '../config/sync';
Note that you will need to create the directory and clear the Drupal registry (cache) before this change is picked up. Make sure to delete the original directory after making this change.
Overriding configuration in settings.php
Configuration can be overridden on a per-environment basis in settings.php, by defining a value in the
$config array. Note that the overridden values are NOT exported to YML files when configuration is exported, rather the value in the database is exported. Overridden values are only used at runtime.
Example Scenario: Your system connects with a 3rd party API. You want to have your local installation use different values for the endpoint, username and password. The values you will use are only to be used on your own installation, and on no other environments. In this situation, you can override the configuration in settings.php, and when you try to connect to the remote API, the values in settings.php will be used. If you export the configuration, the original values stored in the database are exported. This means that the values in your local settings.php do not overwrite the original values when migrating between environments.
The documentation page on Drupal.org explains overriding of configuration in detail: https://www.drupal.org/docs/8/api/configuration-api/configuration-overr…
Managing Configuration: Configuration Manager module
Drupal core ships with the Configuration Manager module. This module allows for management of configuration through the admin UI.
Viewing differences in configuration
After the Configuration Manager module has been enabled, the UI can be accessed at Admin -> Config -> Development -> Configuration Synchronization.
As mentioned in earlier installments of this series, active configuration exists in the database, and can be exported to a series of files for backup and/or migration. The configuration management page allows for visually determining differences between the database and file-based configuration values. Differences between database and file-based configuration are listed in (up to) three tables on this page: added, changed, and removed. Note that each of these tables is only shown if it has values to show.
- Added configuration is configuration that exists in the configuration file system, but not in the active configuration in the database. In the screenshot, the file private_message.settings.yml exists in the configuration file system, but the configuration for private_message.settings does not exist in the active configuration in the database.
- Changed configuration is configuration that exists in both the active configuration in the database as well as the configuration file system, but with differences between the values stored in each of these. In the above screenshot, the file system.site.yml exists in the configuration file system, and the configuration system.site exists in the active configuration, but the values differ.
- Removed configuration is configuration that does not exist the configuration file system, but exists in the active configuration in the database. In the above screenshot, the file restrict_ip.settings.yml does not exist in the configuration file system, but does exist in the active configuration in the database.
Each listing on this page has a 'view differences' button that shows the differences between the active configuration in the database and the file system. The column on the left shows the values in the active configuration in the database, the column on the right shows the values saved to the configuration file system.
Finally, this page allows for the import of the configuration from the file system to the active configuration database by clicking the Import All button. This button will resolve the three types of issues as follows:
- Added - These values will be imported into the active configuration in the database, becoming a new value that didn't previously exist.
- Changed - The value in the file system will be imported into the active configuration in the database, overwriting the current value.
- Removed - The value in the active configuration in the database will be written to the configuration file system.
Configuration import and export
The Configuration Manager UI page also has two tabs, for Import and Export. Each of these tabs in turn have their own Full archive and Single item tabs.
Exporting the full archive of configuration will create a tarball file containing all of the configuration files, which the user then downloads. Note that exporting the full archive of configuration through the admin UI, the configuration files are NOT saved to the configuration directory, they are only offered for download. See the section below on Drush to export the full archive to the configuration directory.
Full archives can only be imported into sites that were all copied/cloned from a common source when being set up. This is because when first installing a site, the site is given a UUID (Universally Unique IDentifier). When a site is cloned, the UUID is the same for both sites. If the sites were installed independently, the UUID will differ between the exporting site and the importing site, and an error is thrown. If you wish to import configuration into a site that does not have a common UUID, you can synchronise the UUIDs as explained here: https://drupal.stackexchange.com/questions/150481/how-can-i-import-the-…
Exporting a single item of configuration prints the configuration data to the screen, as can be seen in the following screenshot:
This configuration can now be copied and pasted into the Import -> Single item tab to import the value into the active configuration of another Drupal installation.
Managing Configuration: Drush
Configuration management can also be handled using Drush (9+) on the command line.
Viewing differences in configuration
Differences in configuration can be viewed with
drush config:status (alias:
drush cst). This outputs the same information as the Configuration Manager module, explaining differences between configuration files and the values in the database.
- Only in [DIRECTORY KEY] directory - the configuration file exists, but the data has not been imported to the database. Equivalent to the added section on the UI page.
- Only in DB - The configuration exists in the database, but there is no matching configuration in the configuration file system. Equivalent to the removed section on the UI page.
- Different - the configuration exists in the DB, and a file exists in the configuration file system, but the values differ from each other. Equivalent to the changed section on the UI page.
Configuration import and export
The full archive of configuration from file system to active database configuration can be imported using
drush config:import [DIRECTORY KEY] (alias:
drush cim [DIRECTORY KEY]). This will wipe out the active configuration in the database, then import all configuration from the directory
[DIRECTORY KEY] (defined in
settings.php - see section above on defining configuration directories) into the active configuration in the database.
Configuration can be exported using
drush config:export [DIRECTORY KEY] (alias:
drush cex [DIRECTORY KEY]). This will delete all files in the configuration directory
[DIRECTORY KEY], then export the full archive of active configuration in the database to that directory. Note that if any configuration values have been overridden in
settings.php, the original value in the database is exported, not the overridden value in
Installing Drupal from Configuration
Drupal 8.6.0 introduced a great new feature whereby a site can be installed using configuration files. in the past, when installing Drupal, a user was asked to install either the standard profile, minimal profile, or a custom profile (Drupal distribution). Starting with Drupal 8.6.0, if the codebase contains a defined configuration directory that in turn contains configuration files, users are provided with the additional option to install the site from configuration. With this selection, Drupal is installed normally, and the configuration is then directly imported to active configuration, creating a complete new copy of the project. This also gives the new system the same UUID as the original environment, allowing for configuration to be migrated between any environments that share the same UUID. This is perfect for developers setting up new environments, as they are able to easily create copies of the site from which to work.
In this article, we looked at how to actually use the API in projects. We looked at defining configuration directories, overriding configuration in settings.php, managing configuration with the Configuration Manager module and Drush, and how to install Drupal from configuration. Next, in part 4 of this series, we will look at some modules that extend the Configuration API, and how they can be used to manage differences in configuration between environments.