Base Database Service (DBCS VM)
Oracle Database VM system with DB home, TDE via Vault, automated backups and optional Data Guard standby.
Verification
Plan-validatedPassed: module logic verified on a mocked plan — inputs, validation rules, conditional creation and outputs resolve (no real provider, no cloud).
Conformance
- Static validation (fmt · validate · tflint)
- Security scan: findings disclosed (Checkov)
- Plan tests (mocked: validation rules · outputs)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live test pending (no cloud run yet)
Last verified 2026-06-28 · how we verify
Documentation
oci-base-database
Status: static-validated, live-test pending. Ships under live-test quarantine — no OCI cloud sandbox is wired into CI yet, so the live apply → verify → destroy gate has not run (and a real DBCS apply costs money and takes 60-90 minutes). Static validation (fmt, validate, tflint) passes.
Oracle Base Database Service (DBCS) on a VM DB system: a VCN-private Oracle
Database with an inline primary DB home, TDE (Oracle- or customer-managed via
OCI Vault), HIGH disk redundancy, managed automatic backups, an optional second
DB home, and an optional Data Guard standby. Works with Terraform and
OpenTofu (>= 1.6), OCI provider >= 8.0, < 9.0.
Secure defaults
- VCN-private: no public IP. Prefer NSGs (
nsg_ids) for a deny-by-default data plane; OS access is SSH-key only (ssh_public_keys, at least one required). - TDE always on: Oracle-managed by default, or a customer-managed Vault key
(
kms_key_id+vault_id, enforced to be set together). - HIGH disk redundancy (triple-mirror) by default.
- Managed automatic backups on with a 30-day recovery window.
- Enterprise edition + ASM by default so Data Guard works out of the box; preconditions reject a Data Guard request on Standard edition or LVM storage.
- BYOL license model by default (no surprise license-included charges).
Usage
module "db" {
source = "./oci-base-database"
compartment_id = "ocid1.compartment.oc1..xxxx"
display_name = "prod-dbcs"
availability_domain = "Uocm:US-ASHBURN-AD-1"
subnet_id = module.vcn.subnet_ids["db"]
hostname = "proddb"
nsg_ids = [module.vcn.network_security_group_ids["db"]]
shape = "VM.Standard.E5.Flex"
cpu_core_count = 4
ssh_public_keys = [file("~/.ssh/id_ed25519.pub")]
db_name = "ORCL"
db_version = "19.0.0.0"
admin_password = var.db_admin_password # inject, never hardcode
# Customer-managed TDE key:
kms_key_id = module.vault.key_id
vault_id = module.vault.vault_id
# Cross-AD Data Guard standby:
data_guard = {
enabled = true
peer_subnet_id = module.vcn.subnet_ids["db-standby"]
peer_availability_domain = "Uocm:US-ASHBURN-AD-2"
peer_hostname = "proddb-sby"
}
}
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
compartment_id | string | — | Compartment OCID (required) |
display_name | string | — | DB system display name (required) |
availability_domain | string | — | AD of the DB system (required) |
subnet_id | string | — | Private subnet OCID (required) |
hostname | string | — | DB system hostname (required) |
ssh_public_keys | list(string) | — | SSH keys for OS access (≥ 1 required) |
shape | string | VM.Standard.E5.Flex | DB system shape |
cpu_core_count | number | 2 | Cores (required for Flex shapes) |
node_count | number | 1 | 1 (single) or 2 (RAC) |
data_storage_size_in_gb | number | 256 | Initial data volume (≥ 256) |
storage_management | string | ASM | ASM or LVM (ASM for Data Guard) |
database_edition | string | ENTERPRISE_EDITION | Database edition |
license_model | string | BRING_YOUR_OWN_LICENSE | Or LICENSE_INCLUDED |
disk_redundancy | string | HIGH | HIGH or NORMAL |
nsg_ids | list(string) | [] | NSGs on the DB system VNIC |
fault_domains | list(string) | [] | Fault domains to spread nodes |
time_zone | string | UTC | DB system time zone |
kms_key_id / vault_id | string | null | Customer-managed TDE key (set together) |
db_version | string | 19.0.0.0 | Primary DB home Oracle version |
db_name | string | ORCL | 1-8 alphanumeric, starts with a letter |
pdb_name | string | null | Initial pluggable database name |
admin_password | string (sensitive) | — | SYS/SYSTEM/PDB/TDE password (required) |
tde_wallet_password | string (sensitive) | null | Separate TDE password (else reuses admin) |
character_set / ncharacter_set | string | AL32UTF8 / AL16UTF16 | Character sets |
db_workload | string | OLTP | OLTP or DSS |
auto_backup_enabled | bool | true | Managed automatic backups |
backup_recovery_window_in_days | number | 30 | Recovery window (1-60) |
backup_window | string | null | SLOT_ONE .. SLOT_TWELVE |
additional_db_home | object | {} | Optional second DB home + database |
data_guard | object | {} | Optional Data Guard standby (new DB system) |
freeform_tags / defined_tags | map(string) | {} | Tags |
Outputs
db_system_id, db_system_state, primary_db_home_id, primary_database_id,
scan_dns_record_id, listener_port, additional_db_home_id,
data_guard_association_id, data_guard_peer_db_system_id.
Notes
admin_passwordandtde_wallet_passwordlive in Terraform state — encrypt and access-control your state backend.- DBCS provisioning takes ~60-90 minutes and a live apply costs real money; budget per run before promoting through the live-test gate.
kms_key_idandvault_idmust be set together or both null (precondition).- Data Guard provisions a new standby DB system;
delete_standby_on_destroydefaults to true soterraform destroyleaves nothing behind (the only value OCI currently supports). Change it, thenapply, beforedestroy. - Data Guard currently supports
MAXIMUM_PERFORMANCE+ASYNConly; the module enforces that pairing with a precondition.
Requirements
- Terraform or OpenTofu
>= 1.6 - Provider
oracle/oci>= 8.0, < 9.0
Verification
Static-validated (fmt, validate, tflint). Live apply/destroy testing pending cloud sandbox availability — see catalog status.
License
Commercial — LicenseRef-IaCBazaar-Commercial. © IaC Bazaar. Original work (not derived from a third-party module).