This example provisions a production-ready Oracle Enterprise Edition 19c RDS instance with bring-your-own-license (BYOL) licensing, character set configuration, and cross-region automated backup replication using a KMS key.
Configuration
provider "aws" {
region = local.region
}
provider "aws" {
alias = "region2"
region = local.region2
}
data "aws_caller_identity" "current" {}
data "aws_availability_zones" "available" {}
locals {
name = "complete-oracle"
region = "eu-west-1"
region2 = "eu-central-1"
vpc_cidr = "10.0.0.0/16"
azs = slice(data.aws_availability_zones.available.names, 0, 3)
tags = {
Name = local.name
Example = local.name
Repository = "https://github.com/terraform-aws-modules/terraform-aws-rds"
}
}
################################################################################
# RDS Module
################################################################################
module "db" {
source = "terraform-aws-modules/rds/aws"
identifier = "demodb-oracle"
engine = "oracle-ee"
engine_version = "19"
family = "oracle-ee-19" # DB parameter group
major_engine_version = "19" # DB option group
instance_class = "db.t3.large"
license_model = "bring-your-own-license"
allocated_storage = 20
max_allocated_storage = 100
# Make sure that database name is capitalized, otherwise RDS will try to recreate RDS instance every time
# Oracle database name cannot be longer than 8 characters
db_name = "ORACLE"
username = "complete_oracle"
port = 1521
multi_az = true
db_subnet_group_name = module.vpc.database_subnet_group
vpc_security_group_ids = [module.security_group.security_group_id]
maintenance_window = "Mon:00:00-Mon:03:00"
backup_window = "03:00-06:00"
enabled_cloudwatch_logs_exports = ["alert", "audit"]
create_cloudwatch_log_group = true
backup_retention_period = 1
skip_final_snapshot = true
deletion_protection = false
performance_insights_enabled = true
performance_insights_retention_period = 7
create_monitoring_role = true
# See here for support character sets https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.OracleCharacterSets.html
character_set_name = "AL32UTF8"
nchar_character_set_name = "AL16UTF16"
tags = local.tags
}
module "db_disabled" {
source = "terraform-aws-modules/rds/aws"
identifier = "${local.name}-disabled"
create_db_instance = false
create_db_parameter_group = false
create_db_option_group = false
}
################################################################################
# RDS Automated Backups Replication Module
################################################################################
module "kms" {
source = "terraform-aws-modules/kms/aws"
version = "~> 1.0"
description = "KMS key for cross region automated backups replication"
# Aliases
aliases = [local.name]
aliases_use_name_prefix = true
key_owners = [data.aws_caller_identity.current.arn]
tags = local.tags
providers = {
aws = aws.region2
}
}
module "db_automated_backups_replication" {
source = "terraform-aws-modules/rds/aws//modules/db_instance_automated_backups_replication"
source_db_instance_arn = module.db.db_instance_arn
kms_key_arn = module.kms.key_arn
providers = {
aws = aws.region2
}
}
################################################################################
# Supporting Resources
################################################################################
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 6.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)]
create_database_subnet_group = true
tags = local.tags
}
module "security_group" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 5.0"
name = local.name
description = "Complete Oracle example security group"
vpc_id = module.vpc.vpc_id
# ingress
ingress_with_cidr_blocks = [
{
from_port = 1521
to_port = 1521
protocol = "tcp"
description = "Oracle access from within VPC"
cidr_blocks = module.vpc.vpc_cidr_block
},
]
tags = local.tags
}
Oracle-specific configuration
Engine identifiers
RDS Oracle supports two engine identifiers:
| Engine | Edition | License model |
|---|
oracle-ee | Enterprise Edition | bring-your-own-license only |
oracle-se2 | Standard Edition 2 | bring-your-own-license or license-included |
The family value follows the format "oracle-ee-19" or "oracle-se2-19", and major_engine_version is the version number string "19".
License model
Oracle requires an explicit license_model:
"bring-your-own-license" — you supply existing Oracle licenses. Required for Enterprise Edition.
"license-included" — the Oracle license is included in the instance price. Only available for Standard Edition 2.
Database name constraints
The Oracle db_name (SID) must be capitalized and 8 characters or fewer. If you specify a lowercase name, Terraform will detect drift after creation because RDS stores it in uppercase, causing repeated plan/apply cycles. Use "ORACLE" not "oracle".
Character sets (immutable)
Both character_set_name and nchar_character_set_name are immutable after creation. Changing either value requires destroying and recreating the RDS instance. Choose carefully before first apply.
The example uses:
| Variable | Value | Description |
|---|
character_set_name | "AL32UTF8" | Database character set. AL32UTF8 is the Oracle implementation of the Unicode UTF-8 encoding — the recommended choice for new databases. |
nchar_character_set_name | "AL16UTF16" | National character set used for NCHAR, NVARCHAR2, and NCLOB columns. AL16UTF16 is the default and recommended value. |
For a full list of supported character sets, see the Oracle Character Sets documentation.
CloudWatch log exports
Oracle supports the following log export types:
| Log type | Description |
|---|
alert | Oracle alert log (instance errors and events) |
audit | Unified auditing trail |
listener | Oracle listener log |
trace | Oracle trace files |
Outputs
| Output | Description |
|---|
db_instance_address | DNS hostname of the RDS instance |
db_instance_endpoint | Full connection endpoint including port |
db_instance_identifier | The RDS instance identifier |
db_instance_engine_version_actual | The resolved engine version running |
db_instance_port | Database port (1521) |
db_instance_name | The database name (SID) |
db_instance_username | Master username (sensitive) |
db_instance_master_user_secret_arn | ARN of the Secrets Manager secret |
db_parameter_group_id | The parameter group name |
db_parameter_group_arn | ARN of the parameter group |
db_instance_cloudwatch_log_groups | Map of CloudWatch log group names and ARNs |