Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ This repository contains reusable infrastructure modules designed for enterprise
| `database/` | `aurora` | AWS Aurora clusters (MySQL, PostgreSQL, Serverless v2, Global Database) (includes `rvn-aurora` module definition) | v1.0.0 |
| `database/` | `dynamodb` | AWS DynamoDB tables | v1.0.0 |
| `database/` | `rds` | AWS RDS instances | v1.0.0 |
| `database/` | `rds-proxy` | AWS RDS Proxy for connection pooling in front of RDS instances or Aurora clusters (standalone or via the `rds`/`aurora` modules) (includes `rvn-rds-proxy` module definition) | v1.0.0 |
| `hosting/` | `static_site` | Composite static site hosting (S3 + CloudFront + OAC, optional CloudFront Function / Lambda@Edge) | v1.0.0 |
| `kubernetes/` | `eks_cluster` | AWS EKS clusters with OIDC, KMS-encrypted secrets, control plane logging, core add-ons, EBS CSI / Pod Identity Agent, LB Controller Pod Identity role, and access entries | v1.0.0 |
| `kubernetes/` | `eks_node_group` | AWS EKS managed node groups (one per module) with IAM, optional launch template, taints, labels, and SPOT/ON_DEMAND capacity | v1.0.0 |
Expand Down Expand Up @@ -59,7 +60,7 @@ sync by `node tools/ravion-modules/dist/src/cli.js readme` (enforced in CI, and
| Definition | Name | Version | Module path |
| ---------- | ---- | ------- | ----------- |
| `rvn-acm-certificate` | ACM Certificate | v1.0.0 | `security/acm_certificate/` |
| `rvn-aurora` | Aurora Database | v1.0.0 | `database/aurora/` |
| `rvn-aurora` | Aurora Database | v1.1.0 | `database/aurora/` |
| `rvn-aws-alb` | AWS Application Load Balancer | v1.0.0 | `networking/alb/` |
| `rvn-aws-iam-policy` | AWS IAM Policy | v1.0.0 | `security/iam_policy/` |
| `rvn-aws-iam-role` | AWS IAM Role | v1.0.0 | `security/iam/` |
Expand All @@ -74,7 +75,8 @@ sync by `node tools/ravion-modules/dist/src/cli.js readme` (enforced in CI, and
| `rvn-efs` | EFS File System | v1.0.0 | `storage/efs/` |
| `rvn-elasticache` | ElastiCache | v1.0.0 | `cache/elasticache/` |
| `rvn-lambda` | Lambda Function | v1.0.0 | `compute/lambda/` |
| `rvn-rds` | RDS Database | v1.0.0 | `database/rds/` |
| `rvn-rds` | RDS Database | v1.1.0 | `database/rds/` |
| `rvn-rds-proxy` | RDS Proxy | v0.1.0 | `database/rds-proxy/` |
| `rvn-route53` | Route 53 DNS | v1.0.0 | `networking/route53/` |
| `rvn-s3` | S3 Bucket | v1.0.0 | `storage/s3/` |
| `rvn-stack` | Terraform Stack | v1.2.4 | `stack/terraform/` |
Expand Down
10 changes: 9 additions & 1 deletion database/aurora/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions database/aurora/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,18 @@ module "aurora" {
| activity_stream_mode | Activity stream mode: sync or async. | `string` | `"async"` | no |
| activity_stream_kms_key_id | KMS key ARN for activity stream (required when enabled). | `string` | `null` | no |
| iam_role_associations | Map of IAM role associations (S3_IMPORT, S3_EXPORT, LAMBDA_INVOKE, etc.). | `map(object)` | `{}` | no |
| proxy_creation_enabled | Whether to create an RDS Proxy in front of the cluster. | `bool` | `false` | no |
| proxy_auth_secret_arns | Secrets Manager secret ARNs for proxy auth (defaults to the managed master user secret). | `list(string)` | `[]` | no |
| proxy_secret_kms_key_arns | KMS key ARNs used to encrypt the proxy auth secrets (customer-managed keys). | `list(string)` | `[]` | no |
| proxy_iam_auth_enabled | Require IAM authentication for proxy connections. | `bool` | `false` | no |
| proxy_tls_requirement_enabled | Require TLS for proxy connections. | `bool` | `true` | no |
| proxy_debug_logging_enabled | Log detailed proxy connection information to CloudWatch Logs. | `bool` | `false` | no |
| proxy_idle_client_timeout | Seconds a client connection can be idle before the proxy disconnects it. | `number` | `1800` | no |
| proxy_connection_borrow_timeout | Seconds the proxy waits for an available connection in the pool. | `number` | `120` | no |
| proxy_init_query | SQL statements the proxy runs when opening each new database connection. | `string` | `null` | no |
| proxy_max_connections_percent | Max proxy connection pool size (% of database max_connections). | `number` | `100` | no |
| proxy_max_idle_connections_percent | Max idle proxy connections (% of database max_connections). | `number` | `50` | no |
| proxy_session_pinning_filters | Session pinning filters (EXCLUDE_VARIABLE_SETS). | `list(string)` | `[]` | no |

## Outputs

Expand Down Expand Up @@ -458,6 +470,9 @@ module "aurora" {
| activity_stream_kinesis_stream_name | The Kinesis data stream name for activity stream. |
| activity_stream_kms_key_id | The KMS key ID for activity stream. |
| autoscaling_target_arn | The Application Auto Scaling target ARN. |
| proxy_endpoint | The RDS Proxy endpoint (null when no proxy is created). |
| proxy_arn | The RDS Proxy ARN (null when no proxy is created). |
| proxy_security_group_id | The RDS Proxy security group ID (null when no proxy is created). |

## Security Considerations

Expand Down
10 changes: 10 additions & 0 deletions database/aurora/cluster.tf
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ resource "aws_rds_cluster" "this" {
condition = !var.activity_stream_enabled || var.activity_stream_kms_key_id != null
error_message = "activity_stream_kms_key_id is required when activity_stream_enabled is true."
}

precondition {
condition = !var.proxy_creation_enabled || var.master_user_password_management_enabled || length(var.proxy_auth_secret_arns) > 0
error_message = "proxy_auth_secret_arns is required when proxy_creation_enabled is true and master_user_password_management_enabled is false."
}

precondition {
condition = !var.proxy_creation_enabled || length(var.subnet_ids) >= 2
error_message = "At least 2 subnet_ids are required when proxy_creation_enabled is true."
}
}

depends_on = [
Expand Down
12 changes: 12 additions & 0 deletions database/aurora/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,16 @@ locals {
)

instances = length(var.instances) > 0 ? var.instances : local.generated_instances

# RDS Proxy
create_proxy = var.proxy_creation_enabled
proxy_engine_family = local.is_mysql ? "MYSQL" : "POSTGRESQL"
proxy_auth_secret_arns = (
length(var.proxy_auth_secret_arns) > 0 ? var.proxy_auth_secret_arns :
var.master_user_password_management_enabled ? [aws_rds_cluster.this.master_user_secret[0].secret_arn] : []
)
proxy_secret_kms_key_arns = distinct(concat(
var.proxy_secret_kms_key_arns,
try(startswith(var.master_user_secret_kms_key_id, "arn:"), false) ? [var.master_user_secret_kms_key_id] : []
))
}
19 changes: 19 additions & 0 deletions database/aurora/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,22 @@ output "region" {
description = "The AWS region where the resources are deployed."
value = local.region
}

################################################################################
# RDS Proxy Outputs
################################################################################

output "proxy_endpoint" {
description = "The endpoint of the RDS Proxy. Null when no proxy is created."
value = local.create_proxy ? module.proxy[0].endpoint : null
}

output "proxy_arn" {
description = "The ARN of the RDS Proxy. Null when no proxy is created."
value = local.create_proxy ? module.proxy[0].proxy_arn : null
}

output "proxy_security_group_id" {
description = "The ID of the RDS Proxy security group. Null when no proxy is created."
value = local.create_proxy ? module.proxy[0].security_group_id : null
}
43 changes: 43 additions & 0 deletions database/aurora/rds_proxy.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
################################################################################
# RDS Proxy (optional)
################################################################################

module "proxy" {
count = local.create_proxy ? 1 : 0

source = "../rds-proxy"

name = var.name
engine_family = local.proxy_engine_family
vpc_id = var.vpc_id
subnet_ids = var.subnet_ids
port = local.port
tags = var.tags

db_cluster_identifier = aws_rds_cluster.this.cluster_identifier

auth = [
for arn in local.proxy_auth_secret_arns : {
secret_arn = arn
iam_auth = var.proxy_iam_auth_enabled ? "REQUIRED" : "DISABLED"
}
]
secret_kms_key_arns = local.proxy_secret_kms_key_arns

tls_requirement_enabled = var.proxy_tls_requirement_enabled
debug_logging_enabled = var.proxy_debug_logging_enabled
idle_client_timeout = var.proxy_idle_client_timeout

connection_borrow_timeout = var.proxy_connection_borrow_timeout
init_query = var.proxy_init_query
max_connections_percent = var.proxy_max_connections_percent
max_idle_connections_percent = var.proxy_max_idle_connections_percent
session_pinning_filters = var.proxy_session_pinning_filters

allowed_security_group_ids = var.allowed_security_group_ids
allowed_cidr_blocks = var.allowed_cidr_blocks

# Registering an Aurora cluster as a proxy target requires the cluster to
# already have at least one instance.
depends_on = [aws_rds_cluster_instance.this]
}
130 changes: 128 additions & 2 deletions database/aurora/rvn-aurora-definition.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ definition:
description: Creates and manages an Amazon Aurora cluster. Supports Aurora PostgreSQL and Aurora MySQL with provisioned or Serverless v2 capacity.

release:
version: 1.0.0
description: First stable release.
version: 1.1.0
description: Add optional RDS Proxy connection pooling in front of the cluster.
module:
inputs:
- id: network
Expand Down Expand Up @@ -322,6 +322,115 @@ module:
show_when:
security_group_creation_enabled: true
type: string_array
- id: section_proxy
label: Connection pooling
type: section
- default: false
description: Create an RDS Proxy in front of the cluster for connection pooling and improved failover handling.
id: proxy_creation_enabled
label: RDS Proxy
type: boolean
- add_button_label: Add secret ARN
collapsible: true
description: Secrets Manager secrets containing database credentials for the proxy. Leave blank to use the managed master user secret.
id: proxy_auth_secret_arns
label: Auth secret ARNs
placeholder: arn:aws:secretsmanager:...
required: false
show_when:
proxy_creation_enabled: true
type: string_array
- add_button_label: Add KMS key ARN
collapsible: true
description: KMS keys used to encrypt the auth secrets when using customer-managed keys. The master user secret KMS key is included automatically.
id: proxy_secret_kms_key_arns
label: Auth secret KMS key ARNs
placeholder: arn:aws:kms:...
required: false
show_when:
proxy_creation_enabled: true
type: string_array
- collapsible: true
default: false
description: Require IAM authentication for client connections to the proxy.
id: proxy_iam_auth_enabled
label: IAM authentication
show_when:
proxy_creation_enabled: true
type: boolean
- collapsible: true
default: true
description: Require TLS for client connections to the proxy.
id: proxy_tls_requirement_enabled
label: Require TLS
show_when:
proxy_creation_enabled: true
type: boolean
- collapsible: true
default: false
description: Log detailed connection information, including SQL statements, to CloudWatch Logs.
id: proxy_debug_logging_enabled
label: Debug logging
show_when:
proxy_creation_enabled: true
type: boolean
- collapsible: true
default: 1800
id: proxy_idle_client_timeout
label: Idle client timeout (seconds)
max: 28800
min: 1
show_when:
proxy_creation_enabled: true
type: number
- collapsible: true
default: 120
id: proxy_connection_borrow_timeout
label: Connection borrow timeout (seconds)
min: 0
show_when:
proxy_creation_enabled: true
type: number
- collapsible: true
default: 100
description: Maximum size of the connection pool as a percentage of the database max_connections setting.
id: proxy_max_connections_percent
label: Max connections (%)
max: 100
min: 1
show_when:
proxy_creation_enabled: true
type: number
- collapsible: true
default: 50
description: Maximum idle connections kept open, as a percentage of the database max_connections setting.
id: proxy_max_idle_connections_percent
label: Max idle connections (%)
max: 100
min: 0
show_when:
proxy_creation_enabled: true
type: number
- add_button_label: Add filter
collapsible: true
id: proxy_session_pinning_filters
label: Session pinning filters
required: false
show_when:
proxy_creation_enabled: true
type: string_array
values:
- label: EXCLUDE_VARIABLE_SETS
value: EXCLUDE_VARIABLE_SETS
- collapsible: true
description: SQL statements the proxy runs when opening each new database connection.
id: proxy_init_query
label: Initialization query
placeholder: SET time_zone = 'UTC'
required: false
show_when:
proxy_creation_enabled: true
type: string
- id: section_readers
label: Readers
type: section
Expand Down Expand Up @@ -1003,6 +1112,18 @@ module:
preferred_backup_window: << module.input.preferred_backup_window >>
preferred_maintenance_window: << module.input.preferred_maintenance_window >>
promotion_tier: << module.input.promotion_tier >>
proxy_auth_secret_arns: << module.input.proxy_auth_secret_arns >>
proxy_connection_borrow_timeout: << module.input.proxy_connection_borrow_timeout >>
proxy_creation_enabled: << module.input.proxy_creation_enabled >>
proxy_debug_logging_enabled: << module.input.proxy_debug_logging_enabled >>
proxy_iam_auth_enabled: << module.input.proxy_iam_auth_enabled >>
proxy_idle_client_timeout: << module.input.proxy_idle_client_timeout >>
proxy_init_query: << module.input.proxy_init_query >>
proxy_max_connections_percent: << module.input.proxy_max_connections_percent >>
proxy_max_idle_connections_percent: << module.input.proxy_max_idle_connections_percent >>
proxy_secret_kms_key_arns: << module.input.proxy_secret_kms_key_arns >>
proxy_session_pinning_filters: << module.input.proxy_session_pinning_filters >>
proxy_tls_requirement_enabled: << module.input.proxy_tls_requirement_enabled >>
public_access_enabled: << module.input.public_access_enabled >>
reader_count: << module.input.reader_count >>
reader_instance_class: << module.input.reader_instance_class >>
Expand Down Expand Up @@ -1275,6 +1396,10 @@ module:

The Ravion UI charts Aurora CloudWatch metrics for CPU utilization, freeable memory, database connections, serverless capacity and ACU utilization, storage used, read and write latency, replica lag, buffer cache hit ratio, commit latency, deadlocks, network throughput, and volume IOPS.

## Connection pooling

Enable RDS Proxy to place a managed connection pool in front of the cluster. The proxy authenticates with the Secrets Manager master user secret by default, requires TLS, and allows the same security group and CIDR sources configured for the cluster. Pool sizing, idle timeouts, session pinning, IAM authentication, and custom auth secrets are configurable in the Connection pooling section.

## Configuration

| Field | Required | Default | Notes |
Expand All @@ -1296,6 +1421,7 @@ module:
| Deletion protection | No | true | Helps prevent accidental deletion. |
| Performance insights | No | true | Enables AWS Performance Insights. |
| CloudWatch alarms | No | true | Adds CPU, memory, and connection alarms. |
| RDS Proxy | No | false | Creates an RDS Proxy connection pool in front of the cluster. |
| Global database | No | false | Create or join an Aurora global database. |
| Activity stream | No | false | Enables Database Activity Streams with a required KMS key. |
| Tags | No | Blank | Merged with Ravion standard tags. |
Expand Down
12 changes: 11 additions & 1 deletion database/aurora/security_group.tf
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,17 @@ module "security_group" {
ip_protocol = "tcp"
cidr_ipv4 = cidr
}
]
],
# RDS Proxy source
local.create_proxy ? [
{
description = "Allow ${var.engine} traffic from the RDS Proxy"
from_port = local.port
to_port = local.port
ip_protocol = "tcp"
referenced_security_group_id = module.proxy[0].security_group_id
}
] : []
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Circular proxy dependency graph

When proxy_creation_enabled uses the default module-managed security group, the database depends on this security group, this rule depends on the proxy module, and the proxy targets the same database, causing Terraform to report a dependency cycle and reject the plan for both the Aurora and RDS integrations.

Knowledge Base Used: Database Modules: Aurora, RDS, DynamoDB

Prompt To Fix With AI
This is a comment left during a code review.
Path: database/aurora/security_group.tf
Line: 40-47

Comment:
**Circular proxy dependency graph**

When `proxy_creation_enabled` uses the default module-managed security group, the database depends on this security group, this rule depends on the proxy module, and the proxy targets the same database, causing Terraform to report a dependency cycle and reject the plan for both the Aurora and RDS integrations.

**Knowledge Base Used:** [Database Modules: Aurora, RDS, DynamoDB](https://app.greptile.com/flightcontrol/-/custom-context/knowledge-base/flightcontrolhq/modules/-/docs/database.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.


# Egress to VPC only. For ip_protocol="-1" (all protocols), AWS requires
Expand Down
Loading