A few years back I had a client running Oracle EE on regular RDS who needed a third-party monitoring agent installed at the OS level. Regular RDS for Oracle said no, flatly, there is no SSH, no root, no filesystem access, period. The workaround people usually reach for is "just run it on EC2 yourself" and eat the patching and backup burden forever. That tradeoff is exactly what RDS Custom for Oracle exists to remove, and if you have not looked at it since it launched, the details of how you actually get that access (and what it costs you operationally) are worth understanding before you commit a production workload to it.
What RDS Custom for Oracle actually is
It is not a third option between RDS and EC2, it is both at once. AWS still provisions and manages the underlying EC2 instance, still handles automated backups, patching orchestration, and monitoring, but it gives you SSH and root access to that instance and the ability to install agents, apply one-off patches, or tweak OS parameters that regular RDS locks away. The mechanism that makes this safe(ish) is called automation mode. When automation is in "full" mode, RDS Custom actively manages the instance and will overwrite or flag anything you change by hand. You pause it before you touch anything, do your work, then resume it.
The other piece that is different from stock RDS is the custom engine version (CEV). Instead of picking from AWS's list of Oracle versions, you build your own CEV from your own Oracle installation media and patch bundles, stored in S3. That is also how you get to bring specific PSU/RU levels or one-off patches that AWS has not pushed to the standard RDS for Oracle fleet yet.
Building a CEV and creating the instance
You need Oracle installation files and patches uploaded to an S3 bucket in the same region as the CEV, plus a manifest describing them:
{
"mediaImportTemplateVersion": "2020-08-14",
"databaseInstallationFileNames": ["V982063-01.zip"],
"opatchFileNames": ["p6880880_190000_Linux-x86-64.zip"],
"psuRuPatchFileNames": ["p32126828_190000_Linux-x86-64.zip"],
"installationParameters": {
"unixGroupName": "dba",
"unixUname": "oracle",
"oracleHome": "/home/oracle/oracle.19.0.0.0.ru-2020-04.rur-2020-04.r1.EE.1",
"oracleBase": "/home/oracle/"
}
}
Then create the CEV:
aws rds create-custom-db-engine-version \
--engine custom-oracle-ee-cdb \
--engine-version 19.cdb_cev1 \
--database-installation-files-s3-bucket-name us-east-1-123456789012-custom-installation-files \
--database-installation-files-s3-prefix 123456789012/cev1 \
--kms-key-id arn:aws:kms:us-east-1:123456789012:key/abcd1234-ef56-7890-ab12-cd34ef567890 \
--manifest file://manifest.json
Budget roughly two hours for this to finish, and know going in that a CEV's architecture is permanent once created. Get the manifest wrong and you delete and start over, you cannot patch it in place.
Once the CEV shows available, spin up the instance:
aws rds create-db-instance \
--engine custom-oracle-ee-cdb \
--db-instance-identifier my-cfo-instance \
--engine-version 19.cdb_cev1 \
--db-name MYPDB \
--db-system-id MYCDB \
--allocated-storage 250 \
--db-instance-class db.m5.xlarge \
--db-subnet-group mydbsubnetgroup \
--master-username myuser \
--master-user-password 'change-me-now' \
--backup-retention-period 7 \
--kms-key-id my-kms-key \
--no-auto-minor-version-upgrade \
--custom-iam-instance-profile AWSRDSCustomInstanceProfile-us-east-1
The IAM instance profile has to start with AWSRDSCustom, this is how RDS Custom's control plane distinguishes an instance it is allowed to manage.
Getting the SSH access you actually asked for
RDS Custom drops an SSH private key into Secrets Manager, named something like do-not-delete-rds-custom-ssh-privatekey-<resource-id>-<uuid>. Pull it down:
aws secretsmanager get-secret-value \
--secret-id do-not-delete-rds-custom-ssh-privatekey-db-ABCDEFGHIJKLMNOPQRS0123456-0d726c \
--query SecretString \
--output text > cfo-instance.pem
chmod 400 cfo-instance.pem
ssh -i cfo-instance.pem ec2-user@ec2-12-345-678-901.us-east-2.compute.amazonaws.com
For a private instance without a public IP, tunnel through Systems Manager instead of exposing port 22:
# add to ~/.ssh/config
# Host i-* mi-*
# ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
ssh -i cfo-instance.pem ec2-user@i-0bdc4219e66944afa
Once you are in as ec2-user, sudo su - rdsdb gets you the database owner account, and sudo su - gets you root. Before you do anything, pause automation:
aws rds modify-db-instance \
--db-instance-identifier my-cfo-instance \
--automation-mode all-paused \
--resume-full-automation-mode-minutes 60
That last flag is your safety net, automation resumes on its own after 60 minutes even if you forget to flip it back manually.
Where this requires care
The end-of-support date matters more than most gotchas here. AWS has set March 31, 2027 as the end of support for RDS Custom for Oracle, with the migration window (to self-managed Oracle on EC2, via RMAN active duplication or Data Guard) running now through then. If you are standing up a new RDS Custom for Oracle workload today, plan the exit before you plan the entry.
A few operational ones too:
- Standard Edition 2 on RDS Custom caps you at 16 vCPUs and 3 tenant databases per CDB, and Data Guard (so read replicas) is off the table on SE2 entirely.
- Leaving automation paused longer than necessary means no automated backups, no patching, and no health monitoring during that window. I have seen a "quick 20 minute fix" turn into a half-day troubleshooting session with automation sitting paused the whole time, that is an outage waiting to happen if something else goes wrong concurrently.
- A CEV manifest mistake is not a warning, it is a failed CEV you delete and rebuild, no patching in place.
- You cannot reset the master password through the console's Modify action the way you can on regular RDS, it has to be an
ALTER USERfrom inside the database. - Resource IDs, key names, and SSH secret names are all auto-generated and ugly. Script the lookups (
describe-db-instances,describe-instances,get-secret-value) rather than hunting through the console every time you need to connect.
My take
RDS Custom for Oracle is the right answer for a narrow but real problem: you need root or SSH for something specific (an agent, a kernel parameter, a one-off patch) and you are not willing to give up managed backups and patch orchestration to get it. It is not a general-purpose upgrade from regular RDS for Oracle, and given the 2027 end-of-support date, I would not recommend it as the long-term home for a new mission-critical system without a migration plan already sketched out. Use it as a bridge, not a destination, and pause automation like you mean it.
Top comments (0)