Blog
clouderacloudera-managerbackupdisaster-recoveryoperationsrest-apisecurity

Cloudera Manager Configuration Backup and Restore

How to back up and restore a Cloudera Manager deployment with the GET/PUT /cm/deployment APIs — including the redaction and deleteCurrentDeployment traps that bite in production.

Data DynamicsSeptember 30, 202611 min read

Cloudera Manager can export the deployment configuration it currently manages as JSON over its REST API, and import the same JSON to restore that configuration. There are only two APIs involved.

GET /api/vXX/cm/deployment    # Backup
PUT /api/vXX/cm/deployment    # Restore

That looks simple, but using them safely in production requires understanding two things: redaction and deleteCurrentDeployment=true. This guide walks through the full procedure including those traps.

What actually gets backed up

The exported deployment typically includes:

  • Cloudera Manager settings
  • Cluster definitions
  • Host information
  • Service, role, and role configuration group definitions
  • Service configuration
  • Users and some security-related settings
  • The deployment structure Cloudera Manager manages

So it is better understood as a logical backup of the entire Cloudera Manager deployment configuration than as a backup of any single service's settings.

Note This does not back up actual user data — HDFS DataNode data, Hive, Kudu, or HBase data. It is also not a physical backup of the Cloudera Manager PostgreSQL/MySQL/Oracle database.

Required privileges

Configuration export/import requires:

Cluster Administrator   or   Full Administrator

The feature is not available where Cloudera Manager manages Data Hub clusters.

End-to-end flow

Loading diagram…

The biggest trap — sensitive configuration redaction

By default Cloudera Manager redacts sensitive values in the exported configuration. Password and credential settings come out like this:

{
  "name": "database_password",
  "value": "REDACTED"
}

Restoring that JSON as-is may not produce a working deployment, because the real passwords are missing. To produce a restorable backup, pick one of two options:

  1. Disable redaction at export time — generate JSON containing the real values.
  2. Replace the REDACTED values before restore — export with defaults and substitute real values just before restoring.

In production this means the JSON may contain plaintext passwords, so storage location and access control matter a great deal.

Disabling redaction

Add the JVM option on the Cloudera Manager server.

vi /etc/default/cloudera-scm-server

If the existing setting looks like this,

export CMF_JAVA_OPTS="-Xmx4G"

add -Dcom.cloudera.api.redaction=false.

export CMF_JAVA_OPTS="-Xmx4G -Dcom.cloudera.api.redaction=false"

Restart the Cloudera Manager server and check its status.

sudo systemctl restart cloudera-scm-server
systemctl status cloudera-scm-server

Security warning With redaction disabled, the exported JSON contains passwords and credentials. Treat the file as a secret, not as an ordinary configuration file.

Recommended permissions and storage:

chmod 600 cm-deployment.json
Encrypted backup storage
Vault
Restricted NFS
Encrypted object storage

Backup

Check the API version

The API version varies with the Cloudera Manager release, so check it rather than hardcoding the number from the docs.

curl -u admin:password \
http://cm.example.com:7180/api/version
v49

Subsequent calls then use /api/v49/cm/deployment.

Over HTTP

curl -u <ADMIN_USER>:<ADMIN_PASSWORD> \
"http://<CM_HOST>:7180/api/v49/cm/deployment" \
-o cm-deployment.json

Shell redirection works too.

curl -u admin:password \
"http://cm01.example.com:7180/api/v49/cm/deployment" \
> /backup/cloudera/cm-deployment.json

Over HTTPS

Where TLS is configured, use the HTTPS URL (port 7183 by default).

curl -u admin:password \
"https://cm01.example.com:7183/api/v49/cm/deployment" \
-o /backup/cloudera/cm-deployment.json

If curl does not trust your internal CA or self-signed certificate, -k works for testing.

curl -k -u admin:password \
"https://cm01.example.com:7183/api/v49/cm/deployment" \
-o cm-deployment.json

In production, configure curl to trust the CA certificate rather than reaching for -k every time.

curl --cacert /etc/pki/ca-trust/source/anchors/company-ca.pem \
-u admin:password \
"https://cm01.example.com:7183/api/v49/cm/deployment" \
-o cm-deployment.json

Verify the backup file

Check the file size and JSON validity.

ls -lh cm-deployment.json
jq empty cm-deployment.json      # no error means valid JSON
jq '.' cm-deployment.json | less

Check for REDACTED entries

If the backup is meant to be restorable, always check for redacted values.

grep -n 'REDACTED' cm-deployment.json
grep -o 'REDACTED' cm-deployment.json | wc -l

A count of 0 suggests a backup without redaction. Any non-zero count means those entries need attention before restore.

Securing the backup file

A deployment JSON exported with redaction disabled is effectively a credential backup. Restrict permissions and encrypt it where possible.

chown root:root cm-deployment.json
chmod 600 cm-deployment.json
 
gpg -c cm-deployment.json        # → cm-deployment.json.gpg
shred -u cm-deployment.json      # remove the original

Versioning

Taking a timestamped backup before every configuration change pays off.

BACKUP_DIR=/backup/cloudera
DATE=$(date '+%Y%m%d-%H%M%S')
 
curl -u admin:password \
"https://cm01.example.com:7183/api/v49/cm/deployment" \
-o "${BACKUP_DIR}/cm-deployment-${DATE}.json"
cm-deployment-20260930-090000.json
cm-deployment-20261001-090000.json
cm-deployment-20261002-090000.json

Backup script example

#!/bin/bash
 
CM_HOST="cm01.example.com"
CM_PORT="7183"
CM_USER="admin"
CM_PASSWORD="password"
 
API_VERSION="v49"
 
BACKUP_DIR="/backup/cloudera-manager"
DATE=$(date '+%Y%m%d-%H%M%S')
 
BACKUP_FILE="${BACKUP_DIR}/cm-deployment-${DATE}.json"
 
mkdir -p "${BACKUP_DIR}"
 
curl --fail --silent --show-error \
    -u "${CM_USER}:${CM_PASSWORD}" \
    "https://${CM_HOST}:${CM_PORT}/api/${API_VERSION}/cm/deployment" \
    -o "${BACKUP_FILE}"
 
if [ $? -ne 0 ]; then
    echo "ERROR: Cloudera Manager configuration backup failed."
    exit 1
fi
 
if ! jq empty "${BACKUP_FILE}" >/dev/null 2>&1; then
    echo "ERROR: Invalid JSON file."
    exit 1
fi
 
chmod 600 "${BACKUP_FILE}"
 
echo "Backup completed:"
echo "${BACKUP_FILE}"

Avoid storing the password in the script itself; use Vault, environment variables, a protected credential file, or a secret management system.

Restore

Restore is a PUT of the backup JSON to the deployment API.

PUT /api/v49/cm/deployment?deleteCurrentDeployment=true

Pre-restore checklist

1. API/CM version of the backup JSON
2. Presence of REDACTED values
3. Hostname changes
4. Cluster name
5. Service and role layout
6. Repository settings
7. TLS / AutoTLS settings
8. Kerberos principals / keytabs
9. Database connection details
10. External service URLs

Restoring a deployment backup as-is into an environment whose hostnames or infrastructure have changed is especially risky.

Fix the REDACTED values

If the backup still contains

{
    "name": "database_password",
    "value": "REDACTED"
}

replace it with the real value before restoring.

{
    "name": "database_password",
    "value": "ActualPassword"
}

Stop cluster services

Cloudera's official procedure calls for stopping running cluster services before restore.

Cloudera Manager → Home → Cluster → Actions → Stop

Wait for All services successfully stopped.

This step matters. If you call the restore API without stopping first, Cloudera Manager may stop the services itself, terminating running jobs in the process. In production, always secure a maintenance window.

Restore over HTTP

curl \
-H "Content-Type: application/json" \
--upload-file /backup/cloudera/cm-deployment.json \
-u admin:password \
"http://cm01.example.com:7180/api/v49/cm/deployment?deleteCurrentDeployment=true"

You can also spell out -X PUT.

curl -X PUT \
-H "Content-Type: application/json" \
-u admin:password \
--data-binary @/backup/cloudera/cm-deployment.json \
"http://cm01.example.com:7180/api/v49/cm/deployment?deleteCurrentDeployment=true"

--upload-file sends the file as a PUT, which is why Cloudera's examples use it.

Restore over HTTPS

curl \
--cacert /etc/pki/ca-trust/source/anchors/company-ca.pem \
-H "Content-Type: application/json" \
--upload-file /backup/cloudera/cm-deployment.json \
-u admin:password \
"https://cm01.example.com:7183/api/v49/cm/deployment?deleteCurrentDeployment=true"

Drop the --cacert line if CA verification is not needed.

What deleteCurrentDeployment=true means

This is the single most important option in a restore. It asks Cloudera Manager to remove the current deployment configuration and then apply the deployment description you sent.

Loading diagram…

It is not a merge that preserves the existing deployment. This is not an API for tweaking a few settings — use it carefully in production.

Post-restore verification

Rather than starting the cluster right after the restore call, verify the configuration and state first.

Cloudera Manager UI

Hosts · Clusters · Services · Role Instances
Configuration · Parcels · Security

Verification via API

curl -u admin:password "https://cm01.example.com:7183/api/v49/hosts"
curl -u admin:password "https://cm01.example.com:7183/api/v49/clusters"
curl -u admin:password "https://cm01.example.com:7183/api/v49/clusters/Cluster1/services"

Start the services

Once hosts and roles look healthy, start the services.

Cloudera Manager → Cluster → Actions → Start

Then check the health of whichever services exist in your environment (ZooKeeper, HDFS, YARN, Hive, Impala, Kudu, HBase, Kafka, Ranger, Atlas, Solr, Knox, and so on).

Health checks

In Cloudera Manager, review cluster/host/service/role health plus configuration staleness and restart-required flags. Per service:

hdfs dfsadmin -report
hdfs haadmin -getAllServiceState
 
yarn node -list
 
kudu cluster ksck <master-list>

For Hive, connect with beeline and run a query; for Impala, use impala-shell; for Kafka, list topics or run a producer/consumer test.

Loading diagram…

Back up the current state one more time right before restoring

Immediately before restoring into an existing environment, export the current deployment once more. That is your rollback point.

curl -u admin:password \
"https://cm01.example.com:7183/api/v49/cm/deployment" \
-o before-restore-$(date '+%Y%m%d-%H%M%S').json

Configuration backup ≠ database backup

This distinction trips people up.

  • GET /cm/deployment preserves the logical deployment configuration Cloudera Manager manages.
  • The Cloudera Manager database holds CM's internal state and metadata, and needs a separate database backup.
pg_dump scm > scm.sql

For real disaster recovery, keep both.

Loading diagram…

A /cm/deployment export alone does not make a complete Cloudera platform DR backup.

/backup/cloudera/
│
├── configuration/
│   ├── 20260928/cm-deployment.json
│   ├── 20260929/cm-deployment.json
│   └── 20260930/cm-deployment.json
│
├── database/
│   ├── scm.sql
│   ├── hive.sql
│   ├── ranger.sql
│   └── hue.sql
│
├── kerberos/
│   ├── krb5.conf
│   └── keytabs/
│
└── tls/
    ├── certificates/
    └── ca/

Scheduled backup with cron

To back up daily at 02:00:

0 2 * * * /opt/scripts/cm-config-backup.sh >> /var/log/cm-config-backup.log 2>&1
#!/bin/bash
 
source /root/.cm-credentials     # CM_USER, CM_PASSWORD
 
CM_HOST="cm01.example.com"
CM_PORT="7183"
 
API_VERSION=$(curl -ks \
    -u "${CM_USER}:${CM_PASSWORD}" \
    "https://${CM_HOST}:${CM_PORT}/api/version")
 
BACKUP_ROOT="/backup/cloudera/configuration"
DATE=$(date '+%Y%m%d')
TIME=$(date '+%H%M%S')
 
BACKUP_DIR="${BACKUP_ROOT}/${DATE}"
BACKUP_FILE="${BACKUP_DIR}/cm-deployment-${TIME}.json"
 
mkdir -p "${BACKUP_DIR}"
 
curl --fail --silent --show-error \
    -k \
    -u "${CM_USER}:${CM_PASSWORD}" \
    "https://${CM_HOST}:${CM_PORT}/api/${API_VERSION}/cm/deployment" \
    -o "${BACKUP_FILE}"
 
if ! jq empty "${BACKUP_FILE}" >/dev/null 2>&1; then
    echo "[ERROR] Invalid JSON"
    rm -f "${BACKUP_FILE}"
    exit 1
fi
 
chmod 600 "${BACKUP_FILE}"
 
REDACTED_COUNT=$(grep -o 'REDACTED' "${BACKUP_FILE}" | wc -l)
 
echo "Backup: ${BACKUP_FILE}"
echo "REDACTED count: ${REDACTED_COUNT}"

Keep the credentials in a separate, restricted file.

# /root/.cm-credentials
CM_USER=backup_admin
CM_PASSWORD=<password>
chmod 600 /root/.cm-credentials

Where a higher security bar applies, use a secret manager such as Vault.

How often to back up

TriggerRecommended frequency
Routine configuration backupDaily
Before a CM configuration changeAlways
Before a parcel upgradeAlways
Before a runtime upgradeAlways
Around host add/removeRecommended
Before adding/removing a serviceAlways
Before a TLS changeAlways
Before a Kerberos changeAlways
Before a major configuration changeAlways

The safest operating model combines a regular daily backup with change-triggered backups.

Summary

It comes down to two APIs.

Backup    GET /api/vXX/cm/deployment
Restore   PUT /api/vXX/cm/deployment?deleteCurrentDeployment=true

And four traps worth remembering:

  1. API version — check /api/version instead of hardcoding the number from the docs.
  2. Redaction — a backup still containing REDACTED will not restore cleanly. Disable redaction at export, or substitute real values before restore.
  3. Backups containing passwords — JSON exported with redaction off is a secret (chmod 600 plus encryption).
  4. deleteCurrentDeployment=true — it removes the existing definition rather than merging. Only after stopping the cluster, only in a maintenance window.

Finally, a /cm/deployment export alone is not a complete DR story. Back up the deployment JSON, the Cloudera Manager database, service databases (Hive, Ranger, Hue, and so on), Kerberos configuration and keytabs, TLS certificates and CAs, and external database/service configuration together — that is what makes recovery realistic when an outage or a rebuild actually happens.