← Back to list

Oracle EPM Cloud Backup and Restore — A Production Strategy Using Snapshots and EPM Automate

Platform: Oracle EPM Cloud Planning (PBCS / EPBCS) Tool: EPM Automate, Snapshots

João Novais · 2026-08-19 02:59 · 0 claps · 3.9 min read
#oracle #hyperion-planning #oracle-cloud
Open on Medium ↗

Oracle EPM Cloud Backup and Restore — A Production Strategy Using Snapshots and EPM Automate

Platform: Oracle EPM Cloud Planning (PBCS / EPBCS) Tool: EPM Automate, Snapshots

Oracle EPM Cloud does not have a point-in-time restore button.

When a bad data load corrupts the Planning cube, when a metadata change breaks a form hierarchy, or when a business rule accidentally clears the wrong scenario — the only reliable recovery path is a snapshot taken before the incident.

Without a snapshot strategy, recovery means rebuilding from scratch.

This article documents the snapshot-based backup strategy used in production EPM Cloud environments: what snapshots contain, how to automate them, how to restore, and what a realistic disaster recovery plan looks like.

What Is an EPM Cloud Snapshot

A snapshot is a complete point-in-time backup of an Oracle EPM Cloud environment. It captures:

Snapshot contents:
├── Application metadata
│   ├── Dimension hierarchies (members, aliases, attributes)
│   ├── Forms, dashboards, task lists
│   ├── Business rules (Calculation Manager)
│   └── Data Management configurations
├── Essbase data
│   ├── BSO cube data
│   └── ASO cube data
├── Security and provisioning
│   ├── User roles and groups
│   └── Data access grants
└── Application settings
    └── System settings, substitution variables

A snapshot does NOT capture:

  • Files in the inbox/outbox (data files, export files)
  • EPM Automate logs
  • Job history

Snapshot vs Artifact Export

Oracle EPM Cloud offers two backup mechanisms:

Mechanism What it captures Use case Snapshot Everything (metadata + data + security) Full environment backup and restore Artifact Export Selected artifacts only (forms, rules, dimensions) Metadata version control, migration between environments

For disaster recovery, always use Snapshot. Artifact exports cannot restore data.

Creating a Snapshot — EPM Automate

# Login
epmautomate login user password https://env.pbcs.us2.oraclecloud.com
# Export snapshot (creates snapshot in EPM Cloud server)
epmautomate exportSnapshot "backup_prod_20240701"
# Download snapshot to local server
epmautomate downloadFile "backup_prod_20240701.zip"
# Logout
epmautomate logout

The snapshot file is a .zip archive. Store it in a location outside the EPM Cloud environment — S3, OCI Object Storage, or a network drive.

Automating Daily Snapshots With Python

import subprocess
import os
import shutil
from datetime import datetime
# Configuration
EPM_URL    = os.environ["EPM_URL"]
EPM_USER   = os.environ["EPM_USER"]
EPM_PASS   = os.environ["EPM_PASS"]
BACKUP_DIR = os.environ["BACKUP_DIR"]  # local directory for snapshots
RETAIN_DAYS = 7  # keep last 7 daily snapshots
def run_epm(command: str) -> str:
    result = subprocess.run(command, shell=True, capture_output=True, text=True)
    if result.returncode != 0:
        raise Exception(f"EPM Automate error: {result.stderr}")
    print(result.stdout.strip())
    return result.stdout
def create_snapshot(snapshot_name: str) -> str:
    print(f"Creating snapshot: {snapshot_name}")
    run_epm(f"epmautomate login {EPM_USER} {EPM_PASS} {EPM_URL}")
    run_epm(f'epmautomate exportSnapshot "{snapshot_name}"')
    run_epm(f'epmautomate downloadFile "{snapshot_name}.zip"')
    run_epm("epmautomate logout")
    # Move to backup directory
    local_path  = f"{snapshot_name}.zip"
    target_path = os.path.join(BACKUP_DIR, f"{snapshot_name}.zip")
    shutil.move(local_path, target_path)
    print(f"Snapshot saved: {target_path}")
    return target_path
def cleanup_old_snapshots(retain_days: int) -> None:
    now   = datetime.now()
    count = 0
    for filename in os.listdir(BACKUP_DIR):
        if not filename.endswith(".zip"):
            continue
        filepath = os.path.join(BACKUP_DIR, filename)
        modified = datetime.fromtimestamp(os.path.getmtime(filepath))
        age_days = (now - modified).days
        if age_days > retain_days:
            os.remove(filepath)
            print(f"Deleted old snapshot: {filename} ({age_days} days old)")
            count += 1
    print(f"Cleanup complete — {count} snapshots deleted.")
def run_backup() -> None:
    today         = datetime.now().strftime("%Y%m%d_%H%M")
    snapshot_name = f"backup_prod_{today}"
    print(f"=== Backup started: {snapshot_name} ===")
    create_snapshot(snapshot_name)
    cleanup_old_snapshots(RETAIN_DAYS)
    print(f"=== Backup completed ===")
if __name__ == "__main__":
    run_backup()

Schedule this script to run daily via Windows Task Scheduler or cron, after the nightly data load completes.

Uploading Snapshots to AWS S3

For environments where local storage is insufficient or snapshots need to be retained long-term:

import boto3
from boto3.s3.transfer import TransferConfig
def upload_snapshot_to_s3(file_path: str, bucket: str, prefix: str) -> None:
    filename = os.path.basename(file_path)
    key      = f"{prefix}/{filename}"
    s3  = boto3.client("s3")
    cfg = TransferConfig(
        multipart_threshold=1024 * 25,
        multipart_chunksize=1024 * 25,
        use_threads=True
    )
    s3.upload_file(file_path, bucket, key, Config=cfg)
    print(f"Snapshot uploaded: s3://{bucket}/{key}")

S3 folder structure:

s3://your-bucket/
└── epm-snapshots/
    ├── daily/
    │   ├── backup_prod_20240701_0200.zip
    │   └── backup_prod_20240702_0200.zip
    └── pre-update/
        ├── backup_prod_before_2607.zip
        └── backup_prod_before_2608.zip

Keep pre-update snapshots separately — these are the most critical recovery points.

Snapshot Naming Convention

Consistent naming makes recovery faster under pressure:

backup_{environment}_{date}_{time}.zip
Examples:
backup_prod_20240701_0200.zip      ← daily scheduled backup
backup_prod_before_2607.zip        ← pre-update backup
backup_prod_before_budget_load.zip ← pre-critical-load backup
backup_test_20240701_0200.zip      ← test environment backup

Restoring From a Snapshot

EPM Automate restore:

# Login
epmautomate login user password https://env.pbcs.us2.oraclecloud.com
# Upload the snapshot file to EPM Cloud
epmautomate uploadFile "backup_prod_20240701_0200.zip"
# Import (restore) the snapshot
epmautomate importSnapshot "backup_prod_20240701_0200"
# Logout
epmautomate logout

Python restore:

def restore_snapshot(snapshot_zip_path: str, snapshot_name: str) -> None:
    print(f"=== Restore started: {snapshot_name} ===")
    # Upload snapshot to EPM Cloud
    run_epm(f"epmautomate login {EPM_USER} {EPM_PASS} {EPM_URL}")
    run_epm(f'epmautomate uploadFile "{snapshot_zip_path}"')
    # Import (restore) — this overwrites the current environment
    run_epm(f'epmautomate importSnapshot "{snapshot_name}"')
    run_epm("epmautomate logout")
    print(f"=== Restore completed: {snapshot_name} ===")

⚠️ importSnapshot overwrites the current environment completely. This is irreversible. Always confirm the target environment before running restore.

Restore Timing

Snapshot restore takes time — plan accordingly:

Environment size Estimated restore time Small (< 1GB) 15–30 minutes Medium (1–5GB) 30–90 minutes Large (5GB+) 90–180 minutes

During restore, the environment is unavailable. Communicate to users before starting.

When to Take a Manual Snapshot

Beyond daily automated backups, take manual snapshots before:

# Pre-update snapshot
snapshot_name = f"backup_prod_before_{update_version}"
create_snapshot(snapshot_name)
# Pre-critical data load
snapshot_name = f"backup_prod_before_budget_load_{date}"
create_snapshot(snapshot_name)
# Pre-metadata change
snapshot_name = f"backup_prod_before_dimension_change_{date}"
create_snapshot(snapshot_name)

These manual snapshots are your safety net for the highest-risk operations.

Disaster Recovery Checklist

Daily:

  • [ ] Automated snapshot runs after nightly data load
  • [ ] Snapshot uploaded to S3 or external storage
  • [ ] Old snapshots (> 7 days) cleaned up
  • [ ] Backup script log reviewed for errors

Before every monthly Oracle update:

  • [ ] Manual pre-update snapshot created for PROD
  • [ ] Snapshot downloaded and stored externally
  • [ ] Snapshot name includes update version (e.g., before_2607)

Before critical operations (data loads, metadata changes):

  • [ ] Manual snapshot created and downloaded
  • [ ] Restore procedure reviewed with team
  • [ ] Estimated restore time communicated to stakeholders

Recovery procedure (when needed):

  • [ ] Identify the correct snapshot (by name and timestamp)
  • [ ] Upload snapshot to EPM Cloud
  • [ ] Confirm target environment with team before running importSnapshot
  • [ ] Communicate downtime window to users
  • [ ] Run restore and monitor until complete
  • [ ] Validate key forms, rules, and data after restore

Full automation scripts on GitHub:

🔗 https://github.com/joaovnovais/oracle-epm-groovy-scripts

João Novais Oracle ACE Apprentice | Oracle EPM Cloud Consultant linkedin.com/in/joaovnovais


메타데이터
post_id
b7c9bfe77a5b
slug
oracle-epm-cloud-backup-and-restore-a-production-strategy-using-snapshots-and-epm-automate-b7c9bfe77a5b
url
https://medium.com/@joaovictornovais8/oracle-epm-cloud-backup-and-restore-a-production-strategy-using-snapshots-and-epm-automate-b7c9bfe77a5b
canonical_url
https://medium.com/@joaovictornovais8/oracle-epm-cloud-backup-and-restore-a-production-strategy-using-snapshots-and-epm-automate-b7c9bfe77a5b
author_url
https://medium.com/@joaovictornovais8
status
ok
fetched_at
2026-08-21 05:43:42