Config-as-code with Config Split: never cex what a split is hiding
Drupal's Config Split keeps environment-specific configuration out of your canonical sync directory — dev tooling, a dev-only permissions tier, per-environment overrides. It works well until someone runs drush cex with a split active and half of config/sync disappears from the diff. Here is the model that avoids that.
What it solves
You want one canonical configuration that deploys to production, plus a few things that exist only in development — Devel, a broader agent-permission tier, verbose logging. Config Split lets a named split own those items so they live in a separate folder and activate conditionally (keyed on an environment variable), while the shared config stays in config/sync.
The trap: cex with a split active
When a split is active, its items are removed from the main export set. Run drush cex in that state and Config Split does exactly what it is designed to: it writes the reduced configuration and deletes the split-owned files from config/sync. If you did not intend to re-partition, you have just staged the deletion of a large part of your canonical config. The git diff is alarming, and if you commit it, the next deploy imports the deletion.
The working model
- Do not cex with a split active. Treat the split's member lists as hand-edited config: add or remove an item by editing the split's own
complete_list/partial_list, not by exporting. - Verify with cim, not cex. After editing, run
drush cimand confirm it reports the change you intended and nothing else. Import is non-destructive to your source of truth; export, under a split, is not. - Env-specific values do not belong in a split at all. A different OAuth client per environment, a secret, a hostname — put those in a
settings.php$config[...]override that reads from the environment. Config Split is for env-specific items (this module or profile exists only here), not per-environment values of a shared item. - When you complete-split an item, split its dependents too. A role that exists only in development must take its dependent config with it, or import fails on the other environments.
Takeaway
Config Split is a scalpel for "what config exists in this environment." Drive it by hand-editing the split lists and verifying with cim; keep cex away from an active split; and route per-environment values through settings.php, not the split. Get that separation right and config-as-code stays trustworthy across every environment.