Friday, April 10, 2026

Automating cloning of your Exadata Database Service on Dedicated Infrastructure database

One of the questions I often get from customers is 

"How do I automate the cloning of a production database backup to a non-prod copy?  This is something we do often."

There are three different OCI commands  to do what seems like the exact same thing. Specifically, when it comes to restoring a database from a backup, the OCI CLI gives us three primary paths.

The "secret sauce" to choosing the right command is understanding where the database is going and ensuring you have the right OCIDs for your target infrastructure. Let's break down the full parameter sets you need to keep your automation from failing.

These are all "oci db database " commands


The Restore Matrix: Choosing Your Command

Command Infrastructure Target Required Target ID Primary Use Case
create-database-from-backup Exadata / C@C --db-home-id Restoring into an existing Exadata Home.
create-from-backup Base DB (VM/BM) --db-system-id Adding a DB to an existing DB System.
create --source DB_BACKUP Base DB (VM/BM) --compartment-id Building a NEW DB System from a backup.

1. The Exadata Full Set: create-database-from-backup

This command uses a JSON object for the --database flag. This is where you define the identity of the clone within the Exadata rack along with the backup you want to use to create the new database.

{
  "adminPassword": "YourPassword123#",
  "backupId": "ocid1.dbbackup.oc1...",
  "backupTDEPassword": "SourceWalletPassword",
  "dbName": "EXACLON",
  "dbUniqueName": "EXACLON_PRD",
  "sidPrefix": "EXACL",
  "pluggableDatabases": ["PDB1", "PDB2"],
  "dbHomeId": "ocid1.dbhome.oc1...",
  "storageSizeDetails": {
    "dataStorageSizeInGBs": 256,
    "recoStorageSizeInGBs": 512
  },
  "sourceEncryptionKeyLocationDetails": {
    "providerType": "AWS|AZURE|GCP|EXTERNAL",
    "awsEncryptionKeyId": "string",
    "hsmPassword": "string"
  }
}

2. The VM/BM In-Place Clone: create-from-backup

`

This is for standard Virtual Machine shapes. You must provide the dbSystemId (the OCID of the VM) to tell OCI exactly where to deploy the restored data.

{
  "adminPassword": "NewAdminPassword123#",
  "backupId": "ocid1.dbbackup.oc1...",
  "backupTdePassword": "SourceWalletPassword",
  "dbSystemId": "ocid1.dbsystem.oc1.iad.example_vm_ocid",
  "dbName": "VMCLON",
  "dbUniqueName": "VMCLON_DEV",
  "sidPrefix": "VMCL",
  "kmsKeyId": "ocid1.key.oc1...",
  "dataStorageSizeInGbs": 256,
  "recoStorageSizeInGbs": 512,
  "databaseSoftwareImageId": "ocid1.dbsoftwareimage.oc1...",
  "isUnifiedAuditingEnabled": true,
  "waitForState": ["AVAILABLE"],
  "maxWaitSeconds": 3600
}

3. Provisioning New Infra: create with --source

This is the "All-In-One" command. It creates the VM Cluster or DB System infrastructure from scratch. Because of this, it requires networking IDs (VCN/Subnet) and hardware shapes.

{
  "source": "DB_BACKUP",
  "backupId": "ocid1.dbbackup.oc1...",
  "tdeWalletPassword": "SourceWalletPassword",
  "compartmentId": "ocid1.compartment.oc1...",
  "subnetId": "ocid1.subnet.oc1...",
  "vmClusterId": "ocid1.vmcluster.oc1...",
  "dbSystemId": "ocid1.dbsystem.oc1...",
  "dbHomeId": "ocid1.dbhome.oc1...",
  "dbName": "NEWDB",
  "dbUniqueName": "NEWDB_U",
  "shape": "VM.Standard.E4.Flex",
  "vaultId": "ocid1.vault.oc1...",
  "kmsKeyId": "ocid1.key.oc1...",
  "dbWorkload": "OLTP",
  "autoBackupEnabled": true,
  "waitForState": ["AVAILABLE"]
}

Key Identification Checklist:
  • Exadata: You must have the --db-home-id of an existing home on the rack.
  • VM In-Place: You need the --db-system-id of the running VM instance.
  • Identity: Every command requires a dbName (8 chars max) and dbUniqueName. For automation, use the sidPrefix to prevent instance ID collisions.



Mastering TDE & Key Management

One of the biggest hurdles in database cloning is handling the Transparent Data Encryption (TDE) layer. If your source backup was encrypted using a key from a different cloud provider or a local HSM, you must tell OCI how to decrypt it during the restore process.

1. Cross-Cloud & External Key Providers

When using the create-database-from-backup command (Exadata), you use the sourceEncryptionKeyLocationDetails parameter. This is a JSON object where you must specify the providerType and the corresponding Key OCID or ID from the source provider.

Provider Type Parameter Required Description
AWS awsEncryptionKeyId The ARN of the AWS KMS key used on the source.
AZURE azureEncryptionKeyId The Azure Key Vault key URI.
GCP googleCloudProviderEncryptionKeyId The fully qualified resource name of the GCP KMS key.
EXTERNAL hsmPassword Used for backups protected by an on-premises Hardware Security Module.

2. Native OCI Vault Integration

For native OCI restores, you have two choices: use the standard Oracle-managed keys (default) or use your own keys via OCI Vault (KMS). If you want to use your own keys, you must provide the kmsKeyId and, in some cases, the vaultId.

  • kmsKeyId: The OCID of the Master Encryption Key in the OCI Vault.
  • kmsKeyVersionId: (Optional) Use this if you need to pin the restore to a specific version of your key.
  • vaultId: Required by the create command to identify which Vault the key resides in.
Important Security Note: If you are restoring a database into a different compartment or tenancy than the source, your Dynamic Group for the target DB System must have READ and USE permissions for the Vault and Key. Without these IAM policies, the restore will fail immediately with a "Not Authorized" error.

By correctly mapping these key parameters, you ensure that your data remains encrypted and compliant throughout its entire lifecycle, even as it moves across cloud boundaries.


Automating with Infrastructure as Code (Terraform)

While the CLI is great for one-off tasks, most of my customers eventually want to bake these clones into their CI/CD pipelines. In Terraform, we use the oci_database_database resource. The "magic" happens in the source attribute and the database_details block.

resource "oci_database_database" "cloned_db" {
    # This maps to the --source flag in the CLI
    source = "DB_BACKUP"

    database {
        admin_password      = var.database_admin_password
        db_name             = "CLONEDB"
        db_unique_name      = "CLONEDB_IAD"
        character_set       = "AL32UTF8"
        ncharacter_set      = "AL16UTF16"
        db_workload         = "OLTP"
        
        # TDE Management
        tde_wallet_password = var.source_tde_password
        kms_key_id          = var.target_vault_key_ocid
    }

    # Target Infrastructure IDs
    db_home_id   = var.target_db_home_ocid
    database_id  = var.source_database_backup_ocid

    # Best Practice: Ignore password changes after initial provision
    lifecycle {
        ignore_changes = [database[0].admin_password]
    }
}

Terraform Pro-Tip: Always use the ignore_changes lifecycle hook for the admin_password. Once the database is restored, security policies often require a password rotation. Without this hook, Terraform will try to revert the password to the plain-text value in your .tfvars every time you run an update!

No comments:

Post a Comment