# Sync configuration with acli

**Goal:** export a [Source CMS](https://dev.acquia.com/start-here/glossary/#source-cms) site's configuration into a working copy with `acli`, change it, and import it back.

## What you'll have when you're done

- The site's configuration as YAML under `.acquia/config`, one file per configuration object.
- The site recorded in the working copy, so later commands need no site argument.
- An import that either applies the whole working copy or refuses with every violation listed.

## Prerequisites

- A Source CMS site you hold site-administrator rights on. Organization administrators hold those rights today.
- `acli` installed and logged in. See the [CLI quickstart](https://dev.acquia.com/cloud-platform/cli/quickstart/).

## Which command moves configuration which way

The commands are named from the working copy's side, the way git is: `pull` brings the site's configuration to you, `push` sends yours to the site.

| What you run                  | Direction | What it does                                                                   |
| ----------------------------- | --------- | ------------------------------------------------------------------------------ |
| `acli source:cms:config:pull` | Export    | Writes the site's configuration into `.acquia/config`, replacing what is there |
| `acli source:cms:config:push` | Import    | Sends `.acquia/config` to the site, replacing the site's configuration         |

An import takes the site offline and replaces its configuration.

## Steps

1. ### Record the site in the working copy, or pass it on every command

   A command with no site refuses rather than guessing. Record the site once:

   ```bash
   acli source:cms:link <sourceSiteId>
   ```

   That writes `source_site_id` into `.acquia-cli.yml`; commit it. Run without an argument in a terminal, the command lists the sites you can reach. `acli source:cms:unlink` removes the record from the local file.

   Or pass the site on each command, which suits a pipeline deploying one branch to several sites. `--site` overrides a recorded site:

   ```bash
   acli source:cms:config:push --site=<sourceSiteId> --yes
   ```

   The site ID is the Acquia identifier of the site you connect to. It is not the site UUID inside the exported configuration, which the site checks on import.

2. ### Export the configuration into your working copy

   From your repository root:

   ```bash
   acli source:cms:config:pull
   ```

   The first export creates `.acquia/config` in the current directory, and later commands find it from any subdirectory. The layout is a Drupal configuration directory: one `<name>.yml` per object, with translation overrides under `language/<langcode>/`.

   **An export replaces the whole directory without prompting.** Uncommitted local edits are lost. Commit or stash before exporting, then rebase your work on top.

3. ### Import it back into the site

   ```bash
   acli source:cms:config:push --yes
   ```

   `--yes` skips the confirmation prompt; without it and without a terminal, the command refuses. The command waits for the import to finish, so its exit status is the import's outcome.

   **The site goes offline while an import runs.** It enters maintenance mode, and a database backup and a configuration checkpoint are taken before anything is applied. Editors lose unsaved work. If the import fails, the site reverts to the checkpoint and comes back online.

4. ### Read the outcome

   A refusal exits non-zero. The command reports one of three outcomes:

   - **Imported.** The site holds what your working copy held.
   - **Refused.** Nothing was imported. The command lists every violation, not only the first.
   - **Unknown.** The command lost track of the import or hit its 45-minute ceiling. The import may still finish, so check the site before retrying.

   Add `--format=json` to print only the outcome, as JSON.

## What just happened

You exported the site's configuration to files and imported them back. `acli` only moves the files; the site runs every check, in one pass, against the whole change set:

- each object is in the [synced configuration](https://dev.acquia.com/source-cms/config-sync/#synced-configuration)
- it matches its schema
- its dependencies resolve once the change set is applied
- the configuration came from this site

One violation refuses the whole import. Exports are not checked, so a site an import would refuse can still be exported, fixed, and imported back.

## When something goes wrong

**The import is refused because the site has drifted.** The site's live configuration changed since the last sync, usually through a Drupal update. Export, commit what comes back, and import again.

**The import is refused because the site has never been exported.** Run an export against that site before the first import.

**The import is refused on the site UUID.** The configuration came from a different site. Environments of one site share a UUID; different sites do not, and configuration cannot be copied between them.

**The import is refused naming a configuration object.** The object is outside the [synced configuration](https://dev.acquia.com/source-cms/config-sync/#synced-configuration) or broke a rule. Fix every listed violation, then import again.

**The import is refused for removing configuration that still holds content.** Removing a content type, vocabulary, media type, field, menu, workflow, or language that still has content is refused, and nothing is deleted. Delete the content first, then import the removal.

**The import is refused for removing something other configuration depends on.** The refusal names the object and each dependent. Remove them together, or keep the object.

**`.acquia/config` does not exist.** Run an export first, or run the command from inside the working copy.

**Your local configuration edits disappeared.** An export replaced the directory. Recover them from version control.

**The import is refused for a document that is too large.** An import accepts at most 1 MiB of configuration, and an export has no limit. Splitting the directory does not help, because an import sends it as one document. To raise the limit, contact [Acquia Support](https://acquia.my.site.com/s/contactsupport).

## Next steps

- [Deploy configuration from CI/CD](https://dev.acquia.com/source-cms/config-sync/ci-cd/): run the import from a pipeline on every push.
- [Canvas CLI reference](https://dev.acquia.com/source-cms/reference/canvas-cli/): Canvas components, patterns, page regions, and content templates sync through Canvas CLI instead.
