Claude
Skills
Sign in
Back

drupal-config-mgmt

Included with Lifetime
$97 forever

Drupal configuration management including config import/export, config splits (complete and partial), syncing config across environments, drush commands for config management, config:import, config:export, config-split commands

General

What this skill does


# Drupal Configuration Management

Comprehensive guide for Drupal configuration management including imports, exports, config splits, and environment syncing.

## Remote CLI — host-neutral

Examples below use Pantheon's **Terminus** (`terminus drush <site>.<env> -- <cmd>`). The commands are identical on any host — substitute your platform's remote-drush form. If your platform provides Drush site aliases, the generic `drush @<alias> <cmd>` works everywhere.

| Task | Acquia (`acli`) | Pantheon (Terminus) | Platform.sh / Upsun | Lagoon (amazee.io) | Generic (Drush aliases) |
|---|---|---|---|---|---|
| Remote drush | `acli remote:drush -- <cmd>` | `terminus drush <site>.<env> -- <cmd>` | `platform drush -e <env> -- <cmd>` (Upsun: `upsun drush …`) | `lagoon ssh -p <project> -e <env> -C "drush <cmd>"` | `drush @<alias> <cmd>` |
| Get/inspect config | `acli remote:drush -- config:get <name>` | `terminus drush <site>.<env> -- config:get <name>` | `platform drush -e <env> -- config:get <name>` | `lagoon ssh -p <project> -e <env> -C "drush config:get <name>"` | `drush @<alias> config:get <name>` |

> **The auto-confirm warning below applies to every host** — append `--no` to `cim`/`config:import` to preview instead of apply. Drush defaults to `--yes` when invoked non-interactively (which all remote-CLI wrappers do).

## Problem: Avoid Accidental Config Imports

**CRITICAL**: Terminus drush commands default to `--yes` unless explicitly told `--no`. This means commands like `config:import` or `cim` will AUTO-CONFIRM and import configuration even when you only want to inspect differences.

### Dangerous vs Safe Patterns

❌ **DANGEROUS** - Auto-imports without confirmation:
```bash
terminus drush {site}.{env} -- cim --diff  # DON'T DO THIS!
```

✅ **SAFE** - Shows diff without importing:
```bash
terminus drush {site}.{env} -- cim --no --diff
```

✅ **SAFEST** - Read-only commands:
```bash
terminus drush {site}.{env} -- config:get config.name
terminus drush {site}.{env} -- config:status
```

## Table of Contents

1. [Preferred Prod Config Merge Workflow](#preferred-prod-config-merge-workflow)
2. [Configuration Import & Export Basics](#configuration-import--export-basics)
3. [Config Splits Overview](#config-splits-overview)
4. [Complete vs Partial Splits](#complete-vs-partial-splits)
5. [Config Split Commands](#config-split-commands)
6. [Safe Inspection Workflow](#safe-inspection-workflow)
7. [Syncing Config from Upstream Environments](#syncing-config-from-upstream-environments)

---

## Preferred Prod Config Merge Workflow

**Purpose**: Safely merge production config changes while preserving local feature work.

### The Process

**Step 1: Commit local changes first**
```bash
git add config/default/your-new-field.yml docroot/modules/custom/your_module/your_module.module
git commit -m "feat: add new feature"
```

**Step 2: Pull production database**
```bash
ddev pull pantheon --environment=live
# Or your preferred method
```

**Step 3: Export config from prod DB**
```bash
ddev drush config:export -y
```

**Step 4: Review git diff on config directory**
```bash
git diff --stat config/           # Summary of changes
git status --short config/        # See added/modified/deleted
```

**Step 5: Identify files to revert vs keep**

Look for these patterns:
- **D (Deleted)** - Your new feature files deleted by prod export → **REVERT**
- **M (Modified)** - UUID changes from prod → **KEEP**
- **M (Modified)** - Actual prod config changes → **KEEP**
- **M (Modified)** - Local changes overwritten → **REVERT** (case by case)

**Step 6: Restore your local feature files**
```bash
# Restore deleted files (your new feature config)
git checkout HEAD -- config/default/field.storage.node.your_new_field.yml
git checkout HEAD -- config/default/field.field.node.bundle.your_new_field.yml

# Or restore specific modified files
git checkout HEAD -- config/default/some.config.yml
```

**Step 7: Verify and commit prod config**
```bash
git status --short config/        # Verify your files are restored
git diff config/                  # Review remaining prod changes
git add config/
git commit -m "chore: sync config from production"
```

### Quick Reference Table

| git status | Meaning | Action |
|------------|---------|--------|
| `D config/default/field.*.your_feature.yml` | Your new feature deleted | `git checkout HEAD -- <file>` |
| `M config/default/*.yml` (UUID only) | Prod UUID sync | Keep (stage for commit) |
| `M config/default/views.view.*.yml` | View changed in prod | Keep (review first) |
| `M config/default/system.*.yml` | System config from prod | Keep (review first) |

### Example Session

```bash
# After pulling prod DB and exporting config
$ git status --short config/
 M config/default/core.entity_view_display.node.song.teaser.yml
 M config/default/field.storage.group.field_member_count.yml
 D config/default/field.field.node.song.field_child_song_count.yml
 D config/default/field.storage.node.field_child_song_count.yml
 M config/default/views.view.songs.yml

# The D files are our new feature - restore them
$ git checkout HEAD -- config/default/field.field.node.song.field_child_song_count.yml \
                       config/default/field.storage.node.field_child_song_count.yml

# Verify
$ git status --short config/
 M config/default/core.entity_view_display.node.song.teaser.yml
 M config/default/field.storage.group.field_member_count.yml
 M config/default/views.view.songs.yml

# Our feature files are no longer in the diff - commit prod changes
$ git add config/ && git commit -m "chore: sync config from production"
```

---

## Configuration Import & Export Basics

### Exporting Configuration

**Export ALL configuration** (from active config to YAML files):
```bash
# Local
ddev drush config:export
ddev drush cex

# Remote
terminus drush {site}.{env} -- config:export
```

**Export a SINGLE config object**:
```bash
# Get config and save to file
ddev drush config:get config.name --format=yaml > config/default/config.name.yml

# Example: Export a specific view
ddev drush config:get views.view.content --format=yaml > config/default/views.view.content.yml
```

### Importing Configuration

**Import ALL configuration** (from YAML files to active config):
```bash
# Local
ddev drush config:import
ddev drush cim

# Remote (DANGEROUS - auto-confirms with terminus!)
terminus drush {site}.{env} -- config:import --no  # Use --no to preview only
```

**Import a SINGLE config object**:
```bash
# Delete from active config first, then import
ddev drush config:delete config.name
ddev drush config:import --partial --source=config/default

# Or use config:set for specific values
ddev drush config:set config.name key.subkey value
```

**Best Practice**: Always preview changes first:
```bash
ddev drush config:import --no --diff  # Show what would change
ddev drush cim --no --diff            # Alias
```

---

## Config Splits Overview

Config splits allow you to have **environment-specific configuration** that doesn't get deployed to all environments.

### Common Use Cases

- **Local development**: Enable devel, kint, stage_file_proxy
- **Staging/Test**: Enable similar modules but different API keys
- **Production**: Disable development modules, enable caching

### How Splits Work

1. **Base config** (`config/default/`) - Shared across all environments
2. **Split config** (`config/{split-name}/`) - Environment-specific overrides
3. **Split definition** (`config/default/config_split.config_split.{name}.yml`) - Defines which config goes in split

When a split is **active**, its config takes precedence over base config.

### Split Activation

Splits are activated based on conditions in their config:
- **Status**: `status: true` in split config
- **Environment variable**: Can use conditions based on env vars
- **Manual activation**: Via admin UI or drush

---

## Complete vs Partial Splits

**CRITICAL**: Understanding the difference between Complete and Partial splits is essential.

### Complete Splits (R

Related in General