Skip to content

Commit

Permalink
Merge pull request #144 from kloia/aws-rds-oracle
Browse files Browse the repository at this point in the history
Add RDS Module for Oracle
  • Loading branch information
bilalunalnet authored Mar 8, 2024
2 parents 8ac7036 + 5d2cbf7 commit eb89d7e
Show file tree
Hide file tree
Showing 34 changed files with 2,893 additions and 0 deletions.
373 changes: 373 additions & 0 deletions aws-rds/README.md

Large diffs are not rendered by default.

149 changes: 149 additions & 0 deletions aws-rds/db_instance/README.md

Large diffs are not rendered by default.

220 changes: 220 additions & 0 deletions aws-rds/db_instance/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
locals {
monitoring_role_arn = var.create_monitoring_role ? aws_iam_role.enhanced_monitoring[0].arn : var.monitoring_role_arn

final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.final_snapshot_identifier_prefix}-${var.identifier}-${try(random_id.snapshot_identifier[0].hex, "")}"

identifier = var.use_identifier_prefix ? null : var.identifier
identifier_prefix = var.use_identifier_prefix ? "${var.identifier}-" : null

monitoring_role_name = var.monitoring_role_use_name_prefix ? null : var.monitoring_role_name
monitoring_role_name_prefix = var.monitoring_role_use_name_prefix ? "${var.monitoring_role_name}-" : null

# Replicas will use source metadata
is_replica = var.replicate_source_db != null
}

# Ref. https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces
data "aws_partition" "current" {}

resource "random_id" "snapshot_identifier" {
count = var.create && !var.skip_final_snapshot ? 1 : 0

keepers = {
id = var.identifier
}

byte_length = 4
}

resource "aws_db_instance" "this" {
count = var.create ? 1 : 0

identifier = local.identifier
identifier_prefix = local.identifier_prefix

engine = local.is_replica ? null : var.engine
engine_version = var.engine_version
instance_class = var.instance_class
allocated_storage = var.allocated_storage
storage_type = var.storage_type
storage_encrypted = var.storage_encrypted
kms_key_id = var.kms_key_id
license_model = var.license_model

db_name = var.db_name
username = !local.is_replica ? var.username : null
password = !local.is_replica && var.manage_master_user_password ? null : var.password
port = var.port
domain = var.domain
domain_auth_secret_arn = var.domain_auth_secret_arn
domain_dns_ips = var.domain_dns_ips
domain_fqdn = var.domain_fqdn
domain_iam_role_name = var.domain_iam_role_name
domain_ou = var.domain_ou
iam_database_authentication_enabled = var.iam_database_authentication_enabled
custom_iam_instance_profile = var.custom_iam_instance_profile
manage_master_user_password = !local.is_replica && var.manage_master_user_password ? var.manage_master_user_password : null
master_user_secret_kms_key_id = !local.is_replica && var.manage_master_user_password ? var.master_user_secret_kms_key_id : null

vpc_security_group_ids = var.vpc_security_group_ids
db_subnet_group_name = var.db_subnet_group_name
parameter_group_name = var.parameter_group_name
option_group_name = var.option_group_name
network_type = var.network_type

availability_zone = var.availability_zone
multi_az = var.multi_az
iops = var.iops
storage_throughput = var.storage_throughput
publicly_accessible = var.publicly_accessible
ca_cert_identifier = var.ca_cert_identifier

allow_major_version_upgrade = var.allow_major_version_upgrade
auto_minor_version_upgrade = var.auto_minor_version_upgrade
apply_immediately = var.apply_immediately
maintenance_window = var.maintenance_window

# https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html
dynamic "blue_green_update" {
for_each = length(var.blue_green_update) > 0 ? [var.blue_green_update] : []

content {
enabled = try(blue_green_update.value.enabled, null)
}
}

snapshot_identifier = var.snapshot_identifier
copy_tags_to_snapshot = var.copy_tags_to_snapshot
skip_final_snapshot = var.skip_final_snapshot
final_snapshot_identifier = local.final_snapshot_identifier

performance_insights_enabled = var.performance_insights_enabled
performance_insights_retention_period = var.performance_insights_enabled ? var.performance_insights_retention_period : null
performance_insights_kms_key_id = var.performance_insights_enabled ? var.performance_insights_kms_key_id : null

replicate_source_db = var.replicate_source_db
replica_mode = var.replica_mode
backup_retention_period = length(var.blue_green_update) > 0 ? coalesce(var.backup_retention_period, 1) : var.backup_retention_period
backup_window = var.backup_window
max_allocated_storage = var.max_allocated_storage
monitoring_interval = var.monitoring_interval
monitoring_role_arn = var.monitoring_interval > 0 ? local.monitoring_role_arn : null

character_set_name = var.character_set_name
nchar_character_set_name = var.nchar_character_set_name
timezone = var.timezone
enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports

deletion_protection = var.deletion_protection
delete_automated_backups = var.delete_automated_backups

dynamic "restore_to_point_in_time" {
for_each = var.restore_to_point_in_time != null ? [var.restore_to_point_in_time] : []

content {
restore_time = lookup(restore_to_point_in_time.value, "restore_time", null)
source_db_instance_automated_backups_arn = lookup(restore_to_point_in_time.value, "source_db_instance_automated_backups_arn", null)
source_db_instance_identifier = lookup(restore_to_point_in_time.value, "source_db_instance_identifier", null)
source_dbi_resource_id = lookup(restore_to_point_in_time.value, "source_dbi_resource_id", null)
use_latest_restorable_time = lookup(restore_to_point_in_time.value, "use_latest_restorable_time", null)
}
}

dynamic "s3_import" {
for_each = var.s3_import != null ? [var.s3_import] : []

content {
source_engine = "mysql"
source_engine_version = s3_import.value.source_engine_version
bucket_name = s3_import.value.bucket_name
bucket_prefix = lookup(s3_import.value, "bucket_prefix", null)
ingestion_role = s3_import.value.ingestion_role
}
}

tags = var.tags

depends_on = [aws_cloudwatch_log_group.this]

timeouts {
create = lookup(var.timeouts, "create", null)
delete = lookup(var.timeouts, "delete", null)
update = lookup(var.timeouts, "update", null)
}

# Note: do not add `latest_restorable_time` to `ignore_changes`
# https://github.com/terraform-aws-modules/terraform-aws-rds/issues/478
}

################################################################################
# CloudWatch Log Group
################################################################################

# Log groups will not be created if using an identifier prefix
resource "aws_cloudwatch_log_group" "this" {
for_each = toset([for log in var.enabled_cloudwatch_logs_exports : log if var.create && var.create_cloudwatch_log_group && !var.use_identifier_prefix])

name = "/aws/rds/instance/${var.identifier}/${each.value}"
retention_in_days = var.cloudwatch_log_group_retention_in_days
kms_key_id = var.cloudwatch_log_group_kms_key_id

tags = var.tags
}

################################################################################
# Enhanced monitoring
################################################################################

data "aws_iam_policy_document" "enhanced_monitoring" {
statement {
actions = [
"sts:AssumeRole",
]

principals {
type = "Service"
identifiers = ["monitoring.rds.amazonaws.com"]
}
}
}

resource "aws_iam_role" "enhanced_monitoring" {
count = var.create_monitoring_role ? 1 : 0

name = local.monitoring_role_name
name_prefix = local.monitoring_role_name_prefix
assume_role_policy = data.aws_iam_policy_document.enhanced_monitoring.json
description = var.monitoring_role_description
permissions_boundary = var.monitoring_role_permissions_boundary

tags = merge(
{
"Name" = format("%s", var.monitoring_role_name)
},
var.tags,
)
}

resource "aws_iam_role_policy_attachment" "enhanced_monitoring" {
count = var.create_monitoring_role ? 1 : 0

role = aws_iam_role.enhanced_monitoring[0].name
policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole"
}

################################################################################
# Managed Secret Rotation
################################################################################

resource "aws_secretsmanager_secret_rotation" "this" {
count = var.create && var.manage_master_user_password && var.manage_master_user_password_rotation ? 1 : 0

secret_id = aws_db_instance.this[0].master_user_secret[0].secret_arn
rotate_immediately = var.master_user_password_rotate_immediately

rotation_rules {
automatically_after_days = var.master_user_password_rotation_automatically_after_days
duration = var.master_user_password_rotation_duration
schedule_expression = var.master_user_password_rotation_schedule_expression
}
}
138 changes: 138 additions & 0 deletions aws-rds/db_instance/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
output "enhanced_monitoring_iam_role_name" {
description = "The name of the monitoring role"
value = try(aws_iam_role.enhanced_monitoring[0].name, null)
}

output "enhanced_monitoring_iam_role_arn" {
description = "The Amazon Resource Name (ARN) specifying the monitoring role"
value = try(aws_iam_role.enhanced_monitoring[0].arn, null)
}

output "db_instance_address" {
description = "The address of the RDS instance"
value = try(aws_db_instance.this[0].address, null)
}

output "db_instance_arn" {
description = "The ARN of the RDS instance"
value = try(aws_db_instance.this[0].arn, null)
}

output "db_instance_availability_zone" {
description = "The availability zone of the RDS instance"
value = try(aws_db_instance.this[0].availability_zone, null)
}

output "db_instance_endpoint" {
description = "The connection endpoint"
value = try(aws_db_instance.this[0].endpoint, null)
}

output "db_listener_endpoint" {
description = "Specifies the listener connection endpoint for SQL Server Always On"
value = try(aws_db_instance.this[0].listener_endpoint, null)
}

output "db_instance_engine" {
description = "The database engine"
value = try(aws_db_instance.this[0].engine, null)
}

output "db_instance_engine_version_actual" {
description = "The running version of the database"
value = try(aws_db_instance.this[0].engine_version_actual, null)
}

output "db_instance_hosted_zone_id" {
description = "The canonical hosted zone ID of the DB instance (to be used in a Route 53 Alias record)"
value = try(aws_db_instance.this[0].hosted_zone_id, null)
}

output "db_instance_identifier" {
description = "The RDS instance identifier"
value = try(aws_db_instance.this[0].identifier, null)
}

output "db_instance_resource_id" {
description = "The RDS Resource ID of this instance"
value = try(aws_db_instance.this[0].resource_id, null)
}

output "db_instance_status" {
description = "The RDS instance status"
value = try(aws_db_instance.this[0].status, null)
}

output "db_instance_name" {
description = "The database name"
value = try(aws_db_instance.this[0].db_name, null)
}

output "db_instance_username" {
description = "The master username for the database"
value = try(aws_db_instance.this[0].username, null)
sensitive = true
}

output "db_instance_port" {
description = "The database port"
value = try(aws_db_instance.this[0].port, null)
}

output "db_instance_ca_cert_identifier" {
description = "Specifies the identifier of the CA certificate for the DB instance"
value = try(aws_db_instance.this[0].ca_cert_identifier, null)
}

output "db_instance_domain" {
description = "The ID of the Directory Service Active Directory domain the instance is joined to"
value = try(aws_db_instance.this[0].domain, null)
}

output "db_instance_domain_auth_secret_arn" {
description = "The ARN for the Secrets Manager secret with the self managed Active Directory credentials for the user joining the domain"
value = try(aws_db_instance.this[0].domain_auth_secret_arn, null)
}

output "db_instance_domain_dns_ips" {
description = "The IPv4 DNS IP addresses of your primary and secondary self managed Active Directory domain controllers"
value = try(aws_db_instance.this[0].domain_dns_ips, null)
}

output "db_instance_domain_fqdn" {
description = "The fully qualified domain name (FQDN) of an self managed Active Directory domain"
value = try(aws_db_instance.this[0].domain_fqdn, null)
}

output "db_instance_domain_iam_role_name" {
description = "The name of the IAM role to be used when making API calls to the Directory Service"
value = try(aws_db_instance.this[0].domain_iam_role_name, null)
}

output "db_instance_domain_ou" {
description = "The self managed Active Directory organizational unit for your DB instance to join"
value = try(aws_db_instance.this[0].domain_ou, null)
}

output "db_instance_master_user_secret_arn" {
description = "The ARN of the master user secret (Only available when manage_master_user_password is set to true)"
value = try(aws_db_instance.this[0].master_user_secret[0].secret_arn, null)
}

################################################################################
# CloudWatch Log Group
################################################################################

output "db_instance_cloudwatch_log_groups" {
description = "Map of CloudWatch log groups created and their attributes"
value = aws_cloudwatch_log_group.this
}

################################################################################
# Managed Secret Rotation
################################################################################

output "db_instance_secretsmanager_secret_rotation_enabled" {
description = "Specifies whether automatic rotation is enabled for the secret"
value = try(aws_secretsmanager_secret_rotation.this[0].rotation_enabled, null)
}
Loading

0 comments on commit eb89d7e

Please sign in to comment.