Provisioning TDE Enabled (19c) Oracle EBS PDB

Refer Provisioning a TDE-enabled vPDB and
Provisioning a TDE software keystore based vPDB sections.

  • Copy the source DB keystore (WALLET_ROOT) files cwallet.sso, ewallet.p12 to target server and mention that location in Parent Database TDE Keystore Location.

  • On Source CDB, run below query to get WALLET_ROOT(files cwallet.sso, ewallet.p12) location -

select wrl_parameter from v$encryption_wallet;

WRL_PARAMETER
------------------------
/home/oravis/wallet/tde/

It is mandatory to copy the ewallet.p12 file from the source to the target server for the target container database to use it. No exporting of keys needed, this is done by the Delphix Continuous Data Engine itself using the path and secrets provided in the configuration. On the target server, cwallet.sso, ewallet.p12 files should be owned by the ORACLE_HOME installation owner.provision oracle ebs tde

The Parent Database TDE keystore Location is the location of the keystore for the dSource, which can be the actual location if it’s a provision back to the source, or else it needs to be copied to the target. The parent keystore password is the password for the dSource keystore. You can decide the TDE Secret for Exported Keys, which is a mandatory input and secret can be anything, it is used when exporting and importing the encryption keys.provision oracle ebs tdeprovision oracle ebs tde

Once a TDE-enabled vPDB is provisioned, it can be used the same as a non-TDE-enabled vPDB within Delphix, with the exception of migrate.  There are few caveats:

  • A refresh operation will use the parent keystore for the recovery. If the dSource is rekeyed then the user will need to update the parent keystore with the new keys. Similarly, if the location or password to the parent keystore has changed then they should be updated before the refresh.

  • A rewind operation will use the target keystore for the recovery. If the vPDB is rekeyed after it is provisioned, then the rekey will update the target keystore, so it does not need to be updated in Delphix.

  • For a single vPDB in a vCDB, if the vCDB keystore location is changed, the new path must be updated in Delphix before refresh or rewind.

  • Each disable operation will result in the keys being exported to an exported keyfile in the artifact directory, to be used for a subsequent enable. Refresh and rewind operations will first disable the existing vPDB, so those will also result in a new exported keyfile in the artifact directory.

  • Provisioning a second-generation vPDB (vvPDB) from a TDE-enabled vPDB is done in the same manner as a first-generation vPDB, by specifying the TDE parameters during provision. The current keystore for the vPDB can be specified as the parent keystore.

For versions 19.3 or later, follow the below guidelines if you see any of the following error:

  1. ORA-01017: invalid username/password logon denied

  2. ORA-28040 During cloning: No Matching Authentication Protocol

Occasionally, it is necessary to restart the database to resolve connectivity to the database. This is atypical but may be necessary in certain cases.
On target container database, run the following command:
alter system set SEC_CASE_SENSITIVE_LOGON=FALSE scope=both;

The above ALTER command should run as a first configure clone hook.

"${ORACLE_HOME}/${ORACLE_SID}_${HOSTNAME}.env";
sqlplus -s "/ as sysdba" <<EOF
alter system set SEC_CASE_SENSITIVE_LOGON=FALSE scope=both;
EOF

Configure clone first hook for a 19c multi-tenant high privileged user:

Configure  clone hook will create and start the PDB specific services

It is mandatory to declare DLPX_SOURCE_APPS_PASSWORD for providing the source apps schema password and SOURCE_PDB_NAME for  source PDB name as credential environment variables in hook sections.If you are linking from a RAC dbTier, select the environment for a single running node of the RAC cluster.
provision oracle ebs tde
#!/usr/bin/env bash
#
# Copyright (c) 2023 by Delphix. All rights reserved.
#
# shellcheck source=/dev/null
# NOTE: Ensure the below environment variables will be set up correctly by the
# shell. If not, hardcode or generate the values below.
HOSTNAME=$(uname -n | cut -d '.' -f1)
CONTEXT_NAME=${DELPHIX_PDB_NAME}_${HOSTNAME}
SOURCE_PDB_NAME=$SOURCE_PDB_NAME_PASSWORD
APPS_PASSWD=$DLPX_SOURCE_APPS_PASSWORD_PASSWORD
. "${ORACLE_HOME}/${ORACLE_SID}_${HOSTNAME}.env";
# Check for local_listener parameter is set for PDB, otherwise set it
# appropriately
check_value=$(sqlplus -s "/ as sysdba" <<EOF
alter session set container="${DELPHIX_PDB_NAME}";
show parameter local_listener;
EOF
)
local_listener=$(echo "$check_value" | awk '{print $11}')
value=("${local_listener//:/ }")
host="${value[0]}"port="${value[1]}"curr_port=$(grep PORT < "${ORACLE_HOME}/network/admin/listener.ora" | awk '{print $9}' | sed 's/)//g')
if [[ $port != "$curr_port" || $host != "${HOSTNAME}" ]]; then
sqlplus -s "/ as sysdba" <<EOF
alter session set container="${DELPHIX_PDB_NAME}";
alter system set local_listener='${HOSTNAME}:${curr_port}';
alter system register;
EOF
fi

#Create, Start EBS PDB services and Delete Source PDB services
. "${ORACLE_HOME}/${ORACLE_SID}_$(hostname -s).env";
sqlplus -s "/ as sysdba" <<EOF
alter session set container="${DELPHIX_PDB_NAME}";
BEGIN DBMS_SERVICE.STOP_SERVICE( service_name => '${SOURCE_PDB_NAME}_ebs_patch'); end ;
/
BEGIN DBMS_SERVICE.STOP_SERVICE( service_name => 'ebs_${SOURCE_PDB_NAME}'); end;
/
BEGIN DBMS_SERVICE.DELETE_SERVICE( service_name => '${SOURCE_PDB_NAME}_ebs_patch'); end ;
/
BEGIN DBMS_SERVICE.DELETE_SERVICE( service_name => 'ebs_${SOURCE_PDB_NAME}'); end;
/
BEGIN DBMS_SERVICE.CREATE_SERVICE( service_name => 'ebs_${DELPHIX_PDB_NAME}', network_name => 'ebs_${DELPHIX_PDB_NAME}'); 
end;
/
BEGIN DBMS_SERVICE.CREATE_SERVICE( service_name => '${DELPHIX_PDB_NAME}_ebs_patch', network_name => '${DELPHIX_PDB_NAME}_ebs_patch'); 
end;
/
BEGIN DBMS_SERVICE.START_SERVICE( service_name => 'ebs_${DELPHIX_PDB_NAME}');    
end; 
/
BEGIN DBMS_SERVICE.START_SERVICE( service_name => '${DELPHIX_PDB_NAME}_ebs_patch');    
end; 
/
alter system register;
EOF

#For compatibility with version 6.0.16.0 or later
. ${ORACLE_HOME}/${ORACLE_SID}_${HOSTNAME}.env; sqlplus -s "/ as sysdba" <<EOF
shutdown immediate;
startup;
ALTER PLUGGABLE DATABASE ALL OPEN read write services=all;
alter pluggable database ${DELPHIX_PDB_NAME} open read write services=all;
alter pluggable database all save state instances=all;
EOF
sqlplus "/ as sysdba" <<EOF
@${ORACLE_HOME}/appsutil/install/${CONTEXT_NAME}/adupdlib.sql so
EOF
. "${ORACLE_HOME}/${CONTEXT_NAME}.env";
perl "${ORACLE_HOME}/appsutil/clone/bin/adcfgclone.pl" dbconfig "${ORACLE_HOME}/appsutil/${CONTEXT_NAME}.xml" <<EOF # noqa
${APPS_PASSWD}
EOF

Configure clone first hook for a 19c multi-tenant low privileged user:

#!/usr/bin/env bash
#
# Copyright (c) 2022 by Delphix. All rights reserved.
#
# shellcheck source=/dev/null
# NOTE: Ensure the below environment variables will be set up correctly by the
# shell. If not, hardcode or generate the values below.
# Input the SOURCE_PDB_NAME enclosed in double quotes.
# Input the DLPX_PRIV_USER according to your environment setup.
SOURCE_PDB_NAME="TDEPDB"DLPX_DB_EXEC_SCRIPT="<Remote BIN location till dlpx_db_exec script>"DLPX_PRIV_USER=oravis
SOURCE_PDB_NAME=$SOURCE_PDB_NAME_PASSWORD
APPS_PASSWD=$DLPX_SOURCE_APPS_PASSWORD_PASSWORD
CONTEXT_NAME=${DELPHIX_PDB_NAME}_$(hostname -s)

"${DLPX_DB_EXEC_SCRIPT}" -u"${DLPX_PRIV_USER}" ". ${ORACLE_HOME}/${ORACLE_SID}_$(hostname -s).env;"# Check for local_listener parameter is set for PDB, otherwise set it appropriately
check_value=$("${DLPX_DB_EXEC_SCRIPT}" -u"${DLPX_PRIV_USER}" ". ${ORACLE_HOME}/${CONTEXT_NAME}.env; sqlplus -s \"/ as sysdba\" <<-EOF
alter session set container=${DELPHIX_PDB_NAME};
show parameter local_listener;
EOF
")

local_listener=$(echo "$check_value" | awk '{print $11}')
value=("${local_listener//:/ }")
host="${value[0]}"port="${value[1]}"curr_port=$(grep PORT < "${ORACLE_HOME}/network/admin/listener.ora" | awk '{print $9}' | sed 's/)//g')

if [[ $port != "$curr_port" || $host != "$(hostname -s)" ]]; then
    "${DLPX_DB_EXEC_SCRIPT}" -u"${DLPX_PRIV_USER}" ". ${ORACLE_HOME}/${ORACLE_SID}_$(hostname -s).env; sqlplus -s \"/ as sysdba\" <<EOF
    alter session set container=${DELPHIX_PDB_NAME};
    alter system set local_listener='$(hostname -s):${curr_port}';
    alter system register;
EOF
"fi

#Create, Start EBS PDB services and Delete Source PDB services
"${DLPX_DB_EXEC_SCRIPT}" -u"${DLPX_PRIV_USER}" ". ${ORACLE_HOME}/${ORACLE_SID}_$(hostname -s).env; sqlplus -s "/ as sysdba" <<EOF
alter session set container="${DELPHIX_PDB_NAME}";
BEGIN DBMS_SERVICE.STOP_SERVICE( service_name => '${SOURCE_PDB_NAME}_ebs_patch'); end ;
/
BEGIN DBMS_SERVICE.STOP_SERVICE( service_name => 'ebs_${SOURCE_PDB_NAME}'); end;
/
BEGIN DBMS_SERVICE.DELETE_SERVICE( service_name => '${SOURCE_PDB_NAME}_ebs_patch'); end ;
/
BEGIN DBMS_SERVICE.DELETE_SERVICE( service_name => 'ebs_${SOURCE_PDB_NAME}'); end;
/
BEGIN DBMS_SERVICE.CREATE_SERVICE( service_name => 'ebs_${DELPHIX_PDB_NAME}', network_name => 'ebs_${DELPHIX_PDB_NAME}'); 
end;
/
BEGIN DBMS_SERVICE.CREATE_SERVICE( service_name => '${DELPHIX_PDB_NAME}_ebs_patch', network_name => '${DELPHIX_PDB_NAME}_ebs_patch'); 
end;
/
BEGIN DBMS_SERVICE.START_SERVICE( service_name => 'ebs_${DELPHIX_PDB_NAME}');    
end; 
/
BEGIN DBMS_SERVICE.START_SERVICE( service_name => '${DELPHIX_PDB_NAME}_ebs_patch');    
end; 
/
alter system register;
EOF
""${DLPX_DB_EXEC_SCRIPT}" -u"${DLPX_PRIV_USER}" ". ${ORACLE_HOME}/${ORACLE_SID}_$(hostname -s).env; sqlplus \"/ as sysdba\" <<-EOF
@${ORACLE_HOME}/appsutil/install/${CONTEXT_NAME}/adupdlib.sql so
EOF
""${DLPX_DB_EXEC_SCRIPT}" -u"${DLPX_PRIV_USER}" ". ${ORACLE_HOME}/${CONTEXT_NAME}.env; perl ${ORACLE_HOME}/appsutil/clone/bin/adcfgclone.pl dbconfig ${ORACLE_HOME}/appsutil/${CONTEXT_NAME}.xml <<-EOF1
${APPS_PASSWD}
EOF1
"

The remaining configure clone & Pre-snapshot hooks remain unchanged. It is mandatory to use hooks mentioned in the documentation while provisioning the TDE vPDB database. Follow the instructions from step 10 to the end in the Oracle EBS database hooks on OCI ExaCC or ExaCS page.