Drupal configuration management for feature sync
Drupal features often combine a content type, custom fields, an editorial workflow, a view and a set of permissions. Drupal configuration management turns those building blocks into portable YAML definitions, giving teams a reliable way to promote the same feature between development, staging and production.
The practical goal of feature synchronisation is consistency without overwriting real content. For an Australian agency, that means a developer in Melbourne, an editor in Brisbane and a reviewer in Sydney can work from a shared, auditable history rather than rebuilding settings manually on each site.
The essential boundary is configuration versus content. Nodes, uploaded files, comments, accounts and taxonomy terms are data, while content types, fields, vocabularies, views, workflows, roles and permissions are configuration. Keeping those categories separate prevents a routine release from replacing customer records or staff accounts with development data.
Define the feature and its configuration boundary
Start by naming the feature’s behaviour and ownership. A booking feature might include appointment types, fields, a restricted availability view, a booking-status workflow and the permissions required by customer-service staff. A custom module provides a clear home for the feature’s PHP code and declares its dependencies, while its configuration remains available for controlled promotion.
The boundary determines how changes are packaged and released:
| Packaging approach | What it covers | Best suited to | Main caution |
|---|---|---|---|
| Feature custom module | Feature-specific configuration shipped with the module | Features with a clear owner and reusable dependencies | Shared roles, permissions and views still need review |
| Site-wide configuration export | All active configuration in the site’s sync directory | Small sites or straightforward maintenance | Large diffs create noise and merge conflicts |
| Selected configuration import | Only the reviewed YAML items selected for import | Isolated view, workflow or permission updates | Related dependencies must be identified first |
| Drupal recipe | A parameterised set of site-building steps | Establishing a consistent baseline for a new project | Less suitable for an incremental production update |
For an existing site, avoid placing every relevant item inside the feature module merely to create tidier folders. Some definitions are shared by several features: an editorial role might manage bookings, support tickets and event registrations. Keep those shared definitions in the normal configuration workflow, and record which features depend on them. Configuration shipped with a custom module can remain with that module when appropriate, but shared settings still require deliberate promotion.
Automate configuration exports and imports
Drush provides a scriptable workflow that works equally well on a developer’s laptop and in a deployment pipeline. Drupal keeps active and exported configuration separately: drush config:export -y copies active configuration into the site’s sync directory, while drush config:import replaces active configuration from that directory. Use drush config:status to identify differences before deciding what to export or import.
A normal development cycle begins with drush config:status, followed by drush config:export -y and a review of the resulting Git diff. On the target environment, drush config:import --diff displays the proposed changes before confirmation. For a feature release, drush config:import --partial -y can apply selected items after the reviewer has chosen them. Drupal core’s import and export screens remain useful for inspecting a site, but repeatable commands are easier to document, audit and automate.
Check environment-specific values before importing. Site names, contact addresses, regional settings and scheduled content can differ between environments without the underlying feature logic changing. Secrets belong in settings.php or managed environment variables, not in committed YAML. Likewise, a role can be synchronised while the staff accounts assigned to that role remain site data.
Full imports deserve particular caution. A full import can remove configuration that exists on the target but is absent from the exported set, including a separately managed module’s settings. Prefer a partial import for a focused feature release, or prepare and review a complete configuration set. The goal is to deliver the reviewed changes without silently restoring unrelated settings.
Review changes and deploy through Git
Create a branch for the feature and commit the module code and matching configuration together. A clear commit message should explain the behavioural change, not merely list YAML filenames. Pull requests then give another developer an opportunity to check permissions, dependencies, workflows and the effect on existing content before the release reaches staging.
Review the generated files rather than assuming the export is self-explanatory. YAML is deterministic, but an exported view may still refer to a field that another developer has renamed. Check whether a custom module requires an update hook, whether new permissions need explicit assignment to roles, and whether a workflow transition depends on a vocabulary created in an earlier commit. These checks are quicker than diagnosing an editor’s missing option after deployment.
Protect the release with a database and files backup, then repeat the same deployment steps on every environment. A pipeline can deploy code, enable the feature module, import the reviewed configuration and run database updates in the order required by that release. Some update hooks expect new configuration to exist, so follow the module’s documented sequence instead of guessing. Do not let a pipeline perform an unreviewed full import simply because it is the shortest command.
Merge conflicts in configuration files deserve the same attention as code conflicts. Rebase the feature branch on the latest main branch, export again after resolving any code changes, and review the resulting diff before merging. If two developers have changed the same view or content type, ask one of them to reconcile the intent rather than choosing whichever YAML version happens to appear last.
Compare environment promotion strategies
A controlled promotion path normally runs from development to staging and then to production. Each environment should use the same branch or tag, the same module code and the same configuration definitions. A change approved in staging is then identifiable by its commit hash in production, giving administrators a clear record of what was deployed and when.
Staging should reproduce the feature’s behaviour without reproducing sensitive production content. Synthetic appointments, demonstration accounts and representative reference data are usually sufficient for testing forms, permissions and editorial transitions. Run drush config:status on staging as well as production, because manual testing can create local configuration differences. Decide whether each difference is intentional and valuable enough to promote, or merely a leftover that should be removed.
A public-sector team in Canberra may have additional obligations under the Australian Privacy Act and internal records policies, which makes the choice of sample content significant. Avoid importing real names, email addresses or client records into a shared staging environment. The same principle applies to commercial agencies working across Australian clients: sanitised fixtures make configuration testing repeatable without turning a staging copy into another source of production data.
Distributed teams also need a sensible release window. During daylight saving, Sydney and Melbourne move to AEDT while Brisbane remains on AEST, and a meeting arranged in Sydney can easily fall in the middle of the afternoon in Perth. Agree on an Australian Eastern Time release slot, record it in the change log and give editors enough notice to complete content work before the configuration changes take effect.
Run a controlled feature rollout
A production rollout should be as repeatable as a development export. The release needs an identified commit, a reviewed configuration diff, a tested deployment sequence and a named person responsible for checking the result after activation.
Prepare the release branch with the module code, YAML definitions, update hooks and relevant tests. Include deployment notes that identify which environments have received the change and which tasks remain. These notes are particularly useful when a team member covers the release while another developer is unavailable.
A practical rollout includes these safeguards:
- Review the exact release set. Confirm the branch, commit hash and configuration diff before promotion. Ensure the change contains the feature’s intended settings rather than unrelated edits accumulated during testing.
- Test in a representative environment. Apply the release to staging, exercise the feature’s forms, views, workflows and permissions, and verify that existing content still behaves as expected.
- Promote the approved artefacts. Deploy the same reviewed code and YAML to production instead of re-exporting from a developer’s machine. Correct configuration separately if an urgent issue requires it.
- Verify after activation. Check the site’s status report, PHP error logs and cron queue, then ask an editor to complete a representative task. A successful import does not guarantee that every integration behaves correctly.
Keep a short record of the commands used, the approved diff and any manual adjustments. This gives administrators an audit trail and lets the next developer reproduce the deployment rather than reverse-engineer it. A predictable command sequence, a small reviewed diff and a documented promotion path make feature releases safe to repeat across every Drupal environment.