Moving Oracle EBS to OCI (Oracle Cloud Infrastructure) combines two distinct challenges: migrating an Oracle Database and migrating the EBS application tier. Oracle ZDM (Zero Downtime Migration) handles the database layer. The EBS application tier requires separate planning. This article covers the architecture, the ZDM setup, and the EBS-specific steps.

## Migration Architecture

A typical EBS to OCI lift-and-shift looks like:

```
On-Premises                          OCI
-----------                          ---
EBS App Tier  ──── ZDM migrate ───► EBS App Tier (OCI VM)
EBS DB Tier   ──── ZDM migrate ───► EBS DB Tier (OCI DB / ExaCS)
              ──── switch ────────► Users connect to OCI
```

ZDM uses Oracle Data Guard to synchronize the source and target databases with minimal downtime — the cutover is just the time to switch users to the target.

## Prerequisites

### Source environment checks

```sql
-- Verify source database is archivelog mode (required for ZDM)
SELECT log_mode FROM v$database;

-- Check for unsupported datatypes
SELECT owner, table_name, column_name, data_type
FROM dba_tab_columns
WHERE data_type IN ('LONG', 'LONG RAW', 'BFILE')
  AND owner NOT IN ('SYS','SYSTEM')
ORDER BY owner, table_name;

-- Check TDE status (ZDM handles TDE migration but needs to know)
SELECT encryptedts FROM v$encrypted_tablespaces;

-- Check supplemental logging (ZDM needs minimal supplemental logging)
SELECT supplemental_log_data_min, supplemental_log_data_pk
FROM v$database;

-- Enable minimal supplemental logging if not already enabled
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
```

### OCI target setup

Before running ZDM, provision the OCI target:

1. **DB System or ExaCS** — same Oracle version as source (or higher if upgrading during migration)
2. **EBS App Tier VMs** — same OS version as source, same shape/capacity
3. **VPN or FastConnect** — ZDM communicates between source and target; low-latency connectivity is critical
4. **SSH keys** — ZDM needs passwordless SSH from the ZDM host to both source and target

## ZDM Setup

ZDM runs as a service on a dedicated migration server (not the source or target):

```bash
# Install ZDM (download from MOS or oracle.com)
# Unzip to /u01/zdmhome or similar

# Initialize ZDM service
export ZDM_HOME=/u01/zdmhome
$ZDM_HOME/bin/zdmservice start

# Verify ZDM service is running
$ZDM_HOME/bin/zdmcli query job

# Check ZDM version
$ZDM_HOME/bin/zdmcli -version
```

## ZDM Response File

ZDM is configured via a response file that defines source, target, and migration parameters:

```bash
# Create the response file
cat > /home/oracle/zdm_ebs_migration.rsp << 'EOF'
MIGRATION_METHOD=ONLINE_LOGICAL
DATA_TRANSFER_MEDIUM=DIRECT
PLATFORM_TYPE=VMDB

# Source (on-premises)
SRC_DB_UNIQUE_NAME=EBSPROD
SRC_HOST=source-db-host.company.com
SRC_DB_LISTENER_PORT=1521
SRC_DB_SERVICE_NAME=EBSPROD

# Target (OCI)
TGT_DB_UNIQUE_NAME=EBSPRODOCI
TGT_HOST=db-host.subnet.vcn.oraclevcn.com
TGT_DB_LISTENER_PORT=1521
TGT_DB_SERVICE_NAME=EBSPRODOCI

# ZDM settings
MIGRATION_ANALYSIS_TIME=PT1H
BACKUP_PATH=

# For Data Guard replication
STANDBY_INSTANCE=1
SKIP_FALLBACK_STEPS=FALSE
EOF
```

## Running the Migration

### Phase 1: Evaluate (no changes, just assessment)

```bash
$ZDM_HOME/bin/zdmcli migrate database \
  -sourcedb EBSPROD \
  -sourcenode source-db-host \
  -srcauth zdmauth \
  -srcarg1 user:oracle \
  -srcarg2 identity_file:/home/oracle/.ssh/id_rsa \
  -targetdb EBSPRODOCI \
  -targetnode db-host.subnet.vcn.oraclevcn.com \
  -tgtauth zdmauth \
  -tgtarg1 user:opc \
  -tgtarg2 identity_file:/home/oracle/.ssh/oci_key \
  -rsp /home/oracle/zdm_ebs_migration.rsp \
  -eval
```

The `-eval` flag runs all checks without making any changes. Review the evaluation report before proceeding.

### Phase 2: Run the migration

```bash
# Start the actual migration
$ZDM_HOME/bin/zdmcli migrate database \
  -sourcedb EBSPROD \
  -sourcenode source-db-host \
  -srcauth zdmauth \
  -srcarg1 user:oracle \
  -srcarg2 identity_file:/home/oracle/.ssh/id_rsa \
  -targetdb EBSPRODOCI \
  -targetnode db-host.subnet.vcn.oraclevcn.com \
  -tgtauth zdmauth \
  -tgtarg1 user:opc \
  -tgtarg2 identity_file:/home/oracle/.ssh/oci_key \
  -rsp /home/oracle/zdm_ebs_migration.rsp

# Monitor job status
$ZDM_HOME/bin/zdmcli query job -jobid <job_id>

# Detailed phase status
$ZDM_HOME/bin/zdmcli query job -jobid <job_id> -detailed
```

ZDM sets up Data Guard replication between source and OCI target. This phase completes when the target is synchronized and ready for cutover.

## EBS Application Tier Migration

ZDM handles the database. The EBS application tier must be migrated separately.

### Clone the application tier

```bash
# On source app tier (as applmgr): make sure no ADOP patching cycle is open
adop phase=status

# Rapid Clone pre-clone — stages the clone driver + context templates under
# $COMMON_TOP/clone that the target's adcfgclone.pl consumes. Run this BEFORE
# tarring; a plain tar with no adpreclone leaves the target unable to
# reconfigure the context cleanly.
cd $COMMON_TOP/clone/bin
perl adpreclone.pl appsTier

# Tar the run filesystem (this is your app tier clone source)
tar -czf /tmp/ebs_app_tier.tar.gz \
  $APPL_TOP \
  $ORACLE_HOME \
  $INST_TOP \
  $EBS_DOMAIN_HOME

# Transfer to OCI app tier
rsync -avz --progress /tmp/ebs_app_tier.tar.gz \
  opc@oci-app-tier:/tmp/
```

### Configure the OCI app tier

```bash
# On the OCI app tier (as applmgr): stage the copied EBS file systems into the
# 12.2 dual-filesystem layout — run edition (fs1), patch edition (fs2), and the
# non-editioned filesystem (fs_ne):
#   /u01/install/APPS/fs1     (run edition)
#   /u01/install/APPS/fs2     (patch edition)
#   /u01/install/APPS/fs_ne   (non-editioned)
cd /u01/install/APPS
tar -xzf /tmp/ebs_app_tier.tar.gz

# Configure the app tier with Rapid Clone — NOT adautocfg.sh directly. Running
# AutoConfig against a filesystem copied from another host would generate config
# from a context file that still points at the source. adcfgclone.pl appsTier
# reconfigures the context file for the new OCI host (hostname, domain, ports,
# DB connect string) and runs AutoConfig internally as its final stage.
cd /u01/install/APPS/fs1/EBSapps/comn/clone/bin
perl adcfgclone.pl appsTier

# adcfgclone.pl prompts for the OCI target host/domain, port pool, and the
# APPS / WebLogic / SYSTEM passwords, regenerates <CONTEXT_NAME>.xml, then
# instantiates every config file (httpd.conf, WLS config, tnsnames, listener.ora).
#
# On AD/TXK Delta 8+ (12.2.4+) configure both editions in a single pass:
#   perl adcfgclone.pl appsTier dualfs
# Otherwise repeat the appsTier config on the patch edition afterwards:
#   cd /u01/install/APPS/fs2/EBSapps/comn/clone/bin && perl adcfgclone.pl appsTier

# Start all services from the run edition once configuration completes
cd $ADMIN_SCRIPTS_HOME
./adstrtal.sh apps/<apps_pwd>   # prompts for the WebLogic admin password on 12.2
```

### Update context file for OCI

`adcfgclone.pl appsTier` sets most host-specific values from the answers you give at its prompts. The context file (`<CONTEXT_NAME>.xml`) is only worth editing by hand for values it did not ask about — for example forcing an external HTTPS web entry point behind an OCI load balancer:

```xml
<!-- Values adcfgclone.pl does not prompt for — set then re-run AutoConfig -->
<s_webentryurlprotocol oa_var="s_webentryurlprotocol">https</s_webentryurlprotocol>
<s_active_webport oa_var="s_active_webport">443</s_active_webport>
<s_webentryhost oa_var="s_webentryhost">ebs</s_webentryhost>
<s_webentrydomain oa_var="s_webentrydomain">company.com</s_webentrydomain>
```

After any manual edit, run AutoConfig (`$ADMIN_SCRIPTS_HOME/adautocfg.sh apps/<pwd>`) to propagate the change to all configuration files. The database host and connect string are already correct if you pointed adcfgclone.pl at the OCI DB.

## Rapid Clone for the App Tier

Rapid Clone is Oracle's supported tooling for moving an EBS application tier to a new host, and it is what the `adcfgclone.pl` step above is doing. It runs in two stages across the two hosts:

### The two stages

1. **`adpreclone.pl appsTier` (source)** — run under `$COMMON_TOP/clone/bin`. It stages a self-contained clone image under `$COMMON_TOP/clone`: the AutoConfig templates, the clone driver files, and a snapshot of the current context. Nothing is reconfigured on the source; you are only packaging what the target will need.
2. **`adcfgclone.pl appsTier` (target)** — run under `fs1/EBSapps/comn/clone/bin` after the file system is copied over. This is where the reconfiguration happens. It:
   - prompts for (or reads from a `pairsfile` in silent mode) the target hostname, domain, port pool, and the APPS / WebLogic / SYSTEM passwords;
   - regenerates `<CONTEXT_NAME>.xml` for the new host;
   - relinks the required binaries;
   - runs AutoConfig as its final stage to instantiate every config file (Apache, WebLogic, forms, `tnsnames.ora`, `listener.ora`) from templates using the new context.

Because AutoConfig runs *inside* `adcfgclone.pl`, you never call `adautocfg.sh` yourself on a fresh clone — doing so would regenerate config from a context file that still describes the source host.

### Rapid Clone vs. manual tar + AutoConfig

A raw `tar` of the file system followed by a hand-run of `adautocfg.sh` can appear to work, but it skips everything Rapid Clone does for you: it does not regenerate the context for the new host, does not relink, and leaves you editing `<CONTEXT_NAME>.xml` by hand for every changed hostname, path, and port.

- **Use Rapid Clone (`adpreclone.pl` → `adcfgclone.pl`)** for any move where the hostname, domain, paths, or ports change — which is every on-prem→OCI migration. It is the only method Oracle supports for a host change, and it handles the 12.2 dual filesystem (`dualfs`) cleanly.
- **Manual tar + AutoConfig** is only defensible when the target is byte-for-byte identical to the source — same hostname, same mount points, same ports (for example restoring onto replacement hardware). For a cloud move it is unsupported and error-prone; do not use it for OCI.

### How it complements ZDM

ZDM and Rapid Clone cover the two halves of an EBS migration and do not overlap:

- **ZDM migrates the database tier** via a Data Guard standby on OCI, with near-zero downtime at cutover. It knows nothing about the EBS application tier.
- **Rapid Clone rebuilds the application tier** on the OCI VMs and points it at the migrated database.

The two combine like this: run `adpreclone.pl` on the source app tier and copy the file system to OCI, run `adcfgclone.pl appsTier` on OCI pointing at the OCI database, then let ZDM perform the database cutover. Because the OCI database keeps the same `db_unique_name`/service you gave adcfgclone, the app tier needs only a final AutoConfig pass (step 5 of the cutover below) to lock onto the promoted OCI primary — no context surgery at cutover time.

## Cutover

The cutover window is the brief period when users are disconnected from source and reconnected to OCI. ZDM automates the database cutover:

```bash
# Initiate cutover (this switches the Data Guard standby to primary)
$ZDM_HOME/bin/zdmcli migrate database \
  -jobid <job_id> \
  -pauseafter ZDM_SYNC_READY \
  -resume
```

During cutover:
1. Disconnect all EBS users from source
2. Wait for Data Guard apply lag to reach zero
3. ZDM switches OCI standby to primary
4. Update DNS to point EBS URLs to OCI app tier
5. Run AutoConfig on OCI app tier pointing to new OCI primary
6. Start all EBS services on OCI
7. Test connectivity and run smoke tests
8. Open the OCI EBS URL to users

## Post-Migration Validation

```sql
-- Connect to OCI DB and verify
SELECT db_unique_name, database_role, open_mode FROM v$database;

-- Verify EBS components
SELECT comp_name, version, status
FROM dba_registry
WHERE status != 'VALID';

-- Check invalid objects
SELECT owner, object_type, COUNT(*)
FROM dba_objects
WHERE status = 'INVALID'
  AND owner NOT IN ('SYS','SYSTEM')
GROUP BY owner, object_type
ORDER BY owner;

-- Recompile if needed
EXEC UTL_RECOMP.RECOMP_PARALLEL(4, 'APPS');

-- Run EBS health checks
-- Login as sysadmin > System Administration > Monitor > System Alerts
```

```bash
# Verify all EBS services are up on OCI
./adstatus.sh apps/<pwd>

# Run ETCC on OCI app tier
cd $ETCC_HOME
./checkMTpatch.sh
```

## Fallback Plan

If migration fails, ZDM supports fallback to the source:

```bash
# Pause migration and revert to source
$ZDM_HOME/bin/zdmcli migrate database \
  -jobid <job_id> \
  -abort

# ZDM keeps the source database intact until fallback window expires
# Users can continue using source while you investigate
```

Keep the source environment intact for at least 30 days after successful migration. Only decommission after a full production cycle on OCI.

ZDM migration takes EBS to OCI with minimal downtime — but the health of your EBS environment before migration determines how smooth it goes. Run TuneVault's full health check on both DB and app tier before starting any ZDM migration to identify issues that could block or complicate the move.
