Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 19, 2025

Description

Extends database support from MySQL-only to five engines: MySQL, MariaDB, PostgreSQL, Aurora MySQL, and Aurora PostgreSQL. Adds Aurora Serverless v2 with automatic scaling (0.5-128 ACUs) and Aurora provisioned clusters with configurable instance counts.

Warning

Breaking Change for Existing Deployments: This PR requires Terraform state migration for existing MySQL deployments to avoid database recreation. See MIGRATION.md for detailed instructions.

Key Changes:

  • Database Module: Conditional RDS vs Aurora deployment based on db_engine variable. Engine-specific parameter families, port mapping (3306/5432), and version defaults.
  • Aurora Support: Serverless v2 scaling configuration, provisioned instance clusters, reader endpoints for read scaling.
  • Networking: Dynamic security group rules based on database port instead of hardcoded MySQL port.
  • Bastion: PostgreSQL client installation, engine-specific user creation (MySQL/PostgreSQL SQL variants), automatic database detection.
  • Variables: New db_engine, db_engine_version, aurora_* configuration options with validation.
  • Migration Guide: Comprehensive MIGRATION.md with step-by-step instructions for upgrading existing deployments.

Configuration Example:

# Aurora Serverless v2 (auto-scaling)
db_engine = "aurora-mysql"  # or aurora-postgresql
aurora_enable_serverlessv2 = true
aurora_min_capacity = 0.5
aurora_max_capacity = 16.0

# RDS PostgreSQL
db_engine = "postgres"
db_engine_version = "16.4"
db_instance_class = "db.t3.medium"

# Default (backward compatible)
# Defaults to MySQL 8.0.43 if db_engine not specified

Default Versions:

  • MySQL: 8.0.43 | MariaDB: 10.11.9 | PostgreSQL: 16.4
  • Aurora MySQL: 8.0.mysql_aurora.3.07.1 | Aurora PostgreSQL: 16.4

Type of Change

  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update

Testing

  • I have tested this locally
  • My code follows the code style of this project
  • I have updated the documentation accordingly

Testing Approach:

  • Validated Terraform syntax and module structure
  • Verified backward compatibility (defaults to MySQL 8.0.43)
  • Confirmed engine-specific parameter groups and port mappings
  • Reviewed bastion user creation scripts for both MySQL and PostgreSQL
  • Documented state migration requirements for existing deployments

Screenshots (if applicable)

N/A - Infrastructure as Code changes

Related Issues

Closes #18

Checklist

  • My code follows the code style of this project
  • I have updated the documentation accordingly
  • All new and existing tests passed
  • My changes generate no new warnings
  • I have checked my code and corrected any misspellings

Additional Notes

Breaking Change - State Migration Required:

Existing MySQL deployments require Terraform state migration to avoid database recreation. The module now uses conditional logic (count) to support both RDS and Aurora, which changes resource addresses from module.database.module.rds to module.database.module.rds[0].

Migration Commands:

terraform state mv 'module.database.module.rds' 'module.database.module.rds[0]'
terraform state mv 'module.database.module.rds_read_replica' 'module.database.module.rds_read_replica[0]'

See MIGRATION.md for complete step-by-step instructions including prerequisites, verification steps, troubleshooting, and rollback procedures.

For New Deployments: No migration needed - configure and deploy as normal.

Engine Switching: Users can switch engines by updating db_engine and redeploying. PostgreSQL requires application code changes (different SQL syntax). Aurora can be created from RDS snapshots.

Files Modified:

  • terraform/modules/database/ - Multi-engine support, Aurora cluster configuration
  • terraform/modules/networking/ - Dynamic port-based security rules
  • terraform/modules/bastion/ - PostgreSQL client, engine-specific user creation
  • terraform/variables.tf - New database configuration options
  • README.md - Comprehensive engine comparison, configuration guide, and migration warnings
  • terraform/environments/example.tfvars - Complete configuration examples
  • MIGRATION.md - Detailed migration guide for existing deployments (new file)

Release Notes: This PR will be included in the next release. The PR title and labels will be used to generate release notes automatically.

Original prompt

This section details on the original issue you should resolve

<issue_title>Multiple DB Support</issue_title>
<issue_description>Make database type configuration based. Options for MySQL, MariaDB, and Postgres in addition to db version. Keep RDS. Add Auroa support as well</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Summary by CodeRabbit

  • New Features

    • Added support for multiple database engines (MySQL, MariaDB, PostgreSQL, Aurora) with flexible deployment options
    • Introduced Aurora Serverless v2 with auto-scaling capabilities based on capacity configuration
    • Enhanced read scaling with reader endpoints for improved performance distribution
  • Documentation

    • Updated configuration guides to cover multi-engine database setup and migration paths
    • Added Aurora-specific configuration examples and best practices

Copilot AI changed the title [WIP] Add configuration for multiple database support Add multiple database engine support (MySQL, MariaDB, PostgreSQL, Aurora) Nov 19, 2025
Copilot AI requested a review from leek November 19, 2025 16:46
@leek leek marked this pull request as ready for review November 19, 2025 18:49
@leek
Copy link
Owner

leek commented Nov 19, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leek leek added the enhancement New feature or request label Nov 19, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

📝 Walkthrough

Walkthrough

This PR adds multi-engine database support (MySQL, MariaDB, PostgreSQL) and Aurora deployment options to the infrastructure. It introduces engine-agnostic configuration, Aurora Serverless v2 capabilities, and updates modules to dynamically select database ports, connection logic, and provisioning steps based on the chosen database engine.

Changes

Cohort / File(s) Summary
Documentation
README.md
Updated to reflect multi-engine database support across MySQL, MariaDB, PostgreSQL, and Aurora variants; added Aurora Serverless v2 configuration details, read scaling options, and engine-specific version/port guidance.
Configuration Examples
terraform/environments/example.tfvars, terraform/variables.tf
Introduced db_engine and db_engine_version variables with engine validation; added Aurora-specific variables (aurora_enable_serverlessv2, aurora_min_capacity, aurora_max_capacity, aurora_instance_count) and expanded existing database descriptions to reference Aurora and performance insights options.
Root Terraform
terraform/main.tf
Added centralized database port mapping (db_port_map in locals); propagated db_port, db_engine, and Aurora configuration inputs across networking, database, and bastion modules; updated security group rules to use dynamic port instead of hard-coded 3306.
Database Module - Core Logic
terraform/modules/database/main.tf
Introduced engine-agnostic configuration via locals with per-engine defaults; made RDS module conditional (count = local.is_aurora ? 0 : 1); added Aurora module with serverless v2 support, subnet groups, and availability zone configuration; updated read replica logic to handle both RDS and Aurora.
Database Module - Configuration
terraform/modules/database/variables.tf, terraform/modules/database/outputs.tf
Added variables for engine selection and Aurora serverless v2 tuning; added outputs for rds_port, db_engine, and is_aurora; made existing outputs conditional to return Aurora or RDS values appropriately.
Bastion Module - Configuration & Script
terraform/modules/bastion/main.tf, terraform/modules/bastion/variables.tf
Added db_engine and db_port variables; updated user_data template to pass engine and port; renamed setup_mysql_user template key to setup_database_user.
Bastion Module - Provisioning
terraform/modules/bastion/user_data.sh
Added PostgreSQL client installation; introduced DB engine branching with conditional logic for MySQL/MariaDB vs PostgreSQL database readiness checks and user creation; replaced single MySQL-specific SQL block with engine-appropriate SQL/PSQL commands.
Networking Module
terraform/modules/networking/main.tf, terraform/modules/networking/variables.tf
Added db_port variable; updated RDS security group ingress rules to use var.db_port instead of hard-coded ports; updated descriptions from "MySQL" to generic "database"; fixed missing closing brace in variables.

Sequence Diagram(s)

sequenceDiagram
    participant root as Root Module<br/>(main.tf)
    participant db as Database Module
    participant rds as RDS Instance
    participant aurora as Aurora Cluster
    participant bastion as Bastion Host
    participant sg as Security Groups

    root->>db: Pass db_engine,<br/>db_engine_version,<br/>aurora_* vars
    
    rect rgba(200, 220, 255, 0.3)
        note over db: Engine Config Selection
        db->>db: is_aurora =<br/>(db_engine contains 'aurora')
    end
    
    alt is_aurora
        db->>aurora: Create Aurora cluster<br/>with engine config
        aurora-->>db: cluster_endpoint,<br/>cluster_id
        db-->>root: is_aurora=true,<br/>endpoint=Aurora endpoint
    else RDS path
        db->>rds: Create RDS instance<br/>with engine config
        rds-->>db: db_instance_endpoint,<br/>db_instance_identifier
        db-->>root: is_aurora=false,<br/>endpoint=RDS endpoint
    end
    
    root->>root: db_port_map:<br/>select port by engine
    root->>sg: Apply db_port
    
    rect rgba(200, 255, 220, 0.3)
        note over root,bastion: Bastion Setup
        root->>bastion: Pass db_engine,<br/>db_port,<br/>db_endpoint
    end
    
    alt db_engine == 'postgres'
        bastion->>bastion: Install postgresql-client<br/>wait for port 5432
        bastion->>bastion: Create users via psql
    else MySQL/MariaDB
        bastion->>bastion: MySQL client present<br/>wait for port 3306
        bastion->>bastion: Create users via mysql
    end
    
    bastion-->>root: Database ready
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

  • Areas requiring extra attention:
    • terraform/modules/database/main.tf: Logic density in engine configuration selection (locals for engine config, conditional module instantiation, Aurora-specific resource handling) requires careful verification that all engine paths work correctly.
    • terraform/modules/bastion/user_data.sh: Database readiness detection and user provisioning branches for PostgreSQL vs MySQL/MariaDB need validation that the correct commands and flags are used per engine.
    • Engine validation in terraform/modules/database/variables.tf and terraform/variables.tf: Ensure the allowed engine list is comprehensive and matches documentation.
    • Conditional outputs in terraform/modules/database/outputs.tf: Verify null fallbacks handle edge cases when Aurora/RDS modules are not instantiated.

Possibly related PRs

Suggested labels

enhancement

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: adding support for multiple database engines (MySQL, MariaDB, PostgreSQL, Aurora) instead of the previous MySQL-only configuration.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering key changes, testing approach, backward compatibility, and migration paths. It follows the template with description, type of change, testing, related issues, and checklists completed.
Linked Issues check ✅ Passed The PR fully addresses issue #18 objectives: enables configuration-based database type selection [#18], supports multiple engines (MySQL, MariaDB, PostgreSQL) [#18], includes Aurora support [#18], maintains RDS compatibility [#18], and exposes engine/version configuration variables [#18].
Out of Scope Changes check ✅ Passed All changes are directly related to multi-database engine support: database module refactoring for engine flexibility, networking security group updates for dynamic ports, bastion configuration for engine-specific user creation, variable additions for engine configuration, and README documentation updates. No unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch copilot/add-multiple-db-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
terraform/environments/example.tfvars (1)

100-156: I'll search for the current default versions for each database engine from AWS documentation.

Let me search for MariaDB version information to complete the verification.

Update version numbers and clarify AWS default version behavior.

MySQL 8.0.43 is available on Amazon RDS, which matches the comment. However, the other versions listed are outdated:

  • MariaDB's latest supported version is 10.11.15, not 10.11.9
  • Aurora PostgreSQL-Compatible Edition supports PostgreSQL 17.5, 16.9, and other versions, making 16.4 outdated
  • For RDS PostgreSQL, newer versions like 16.9 are available
  • Aurora versions include MySQL 3.08.2 (compatible with MySQL 8.0.39), not 3.07.1

Additionally, AWS defaults to a supported version, typically the most recent version, though defaults vary by region. The comment should reference AWS CLI commands to check current defaults rather than listing static version numbers, since they change frequently and vary by region:

aws rds describe-db-engine-versions --engine <engine> --region <region> --query '*[?Preferred==`true`]'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a8064a and b9be925.

📒 Files selected for processing (12)
  • README.md (10 hunks)
  • terraform/environments/example.tfvars (2 hunks)
  • terraform/main.tf (6 hunks)
  • terraform/modules/bastion/main.tf (1 hunks)
  • terraform/modules/bastion/user_data.sh (4 hunks)
  • terraform/modules/bastion/variables.tf (1 hunks)
  • terraform/modules/database/main.tf (6 hunks)
  • terraform/modules/database/outputs.tf (1 hunks)
  • terraform/modules/database/variables.tf (1 hunks)
  • terraform/modules/networking/main.tf (1 hunks)
  • terraform/modules/networking/variables.tf (1 hunks)
  • terraform/variables.tf (3 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
README.md

286-286: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


301-301: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


352-352: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


359-359: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


388-388: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


1017-1017: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


1022-1022: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


1034-1034: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


1040-1040: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🔇 Additional comments (23)
terraform/modules/bastion/variables.tf (2)

146-150: LGTM! Engine variable properly defined.

The db_engine variable is well-structured with a sensible default that maintains backward compatibility. Validation is appropriately handled at the root module level.


152-156: LGTM! Port variable properly defined.

The db_port variable has an appropriate default that aligns with the MySQL default, maintaining backward compatibility.

README.md (4)

26-46: LGTM! Feature documentation accurately reflects multi-engine support.

The updated feature list clearly communicates the expanded database capabilities, including both RDS and Aurora options.


472-498: Excellent production configuration examples.

Providing three distinct database configuration options (RDS Multi-AZ, Aurora Serverless v2, and Aurora Provisioned) with clear comments helps users choose the right setup for their needs.


1015-1046: LGTM! Database scaling documentation is clear and comprehensive.

The scaling section effectively distinguishes between RDS and Aurora capabilities, including Aurora's automatic storage scaling and Serverless v2 options.


343-348: ACU specifications are accurate—no changes required.

The ACU-to-RAM mappings in the README are mathematically correct per AWS documentation: 1 ACU ≈ 2 GiB RAM, which validates all listed ratios (0.5 ACU = ~1GB, 2–4 ACU = ~4–8GB, 8+ ACU = ~16GB+). AWS confirms 0.5-ACU increments are the supported minimum. The specifications require no updates.

terraform/variables.tf (1)

174-220: LGTM! Updated variable descriptions accurately distinguish RDS and Aurora.

The updated descriptions appropriately clarify which variables apply to RDS vs Aurora, helping users understand the differences.

terraform/modules/database/outputs.tf (2)

2-35: LGTM! Conditional output logic properly handles Aurora vs RDS.

The conditional logic correctly routes to Aurora or RDS module outputs based on local.is_aurora, with appropriate null fallbacks. Note that output names retain the "rds_" prefix for backward compatibility, even though they now support Aurora.


37-50: LGTM! New outputs support engine-agnostic configuration.

The new outputs (rds_port, db_engine, is_aurora) provide necessary information for downstream modules to handle different database engines correctly. All local variables are properly defined with correct engine-to-port mappings: mysql/mariadb use port 3306, postgres/aurora-postgresql use port 5432, and current_engine correctly selects the configuration based on var.db_engine.

terraform/modules/networking/variables.tf (1)

32-36: LGTM! Database port variable enables engine-agnostic networking.

The db_port variable allows security group rules to dynamically configure the correct port based on the database engine.

terraform/modules/networking/main.tf (1)

75-103: LGTM! Security group rules properly updated for multi-engine support.

The security group now uses var.db_port for dynamic port configuration, replacing the hardcoded "mysql-tcp" rule. This enables support for PostgreSQL (port 5432) and other engines while maintaining the same security posture.

terraform/environments/example.tfvars (1)

157-182: LGTM! Aurora-specific configuration is well-documented.

The Aurora configuration section provides clear guidance on Serverless v2 vs provisioned instances, with practical ACU recommendations for different environments.

terraform/modules/bastion/main.tf (1)

122-136: Verification successful: User data template correctly implements engine-specific provisioning.

The user_data.sh template properly handles the db_engine parameter with engine-specific logic for MySQL/MariaDB and PostgreSQL variants. Database readiness checks and user creation commands are differentiated appropriately for each engine family. The setup_database_user gate correctly controls when user provisioning occurs.

terraform/modules/bastion/user_data.sh (2)

53-54: Verify: PostgreSQL client installation should likely be conditional.

PostgreSQL client is installed unconditionally (line 53-54), unlike MySQL client which is gated by install_mysql_client (line 48-51). If the template is engine-aware and only instantiates the database setup when needed, consider making PostgreSQL installation conditional via a template variable (e.g., %{ if install_postgres_client ~}), to align with the MySQL pattern and avoid unnecessary tooling on MySQL-only deployments.

Can you verify whether this unconditional install is intentional (defensive tooling) or should follow the MySQL pattern with a template variable?


109-220: Engine-aware database user setup is well-structured.

The conditional branching on DB_ENGINE (lines 124-140) correctly validates supported engines and gates the entire setup. The MySQL and PostgreSQL user creation paths (lines 160-211) are appropriately implemented:

  • MySQL path uses standard CREATE USER IF NOT EXISTS and GRANT statements
  • PostgreSQL path uses DO blocks to safely handle conditional user creation and properly configures default privileges

The 30-attempt readiness check (lines 142-157) with 10-second intervals provides adequate time for database startup.

terraform/main.tf (3)

29-37: Database port mapping is correct and properly derived.

The db_port_map local correctly maps all supported database engines to their standard ports (3306 for MySQL family, 5432 for PostgreSQL family). The lookup on var.db_engine is safe because the variable has validation in terraform/modules/database/variables.tf.


151-165: Database module variables are properly forwarded.

All new Aurora and engine configuration variables (db_engine, db_engine_version, and aurora_*) are correctly passed to the database module. The forwarding pattern is consistent with the PR objectives.


384-385: No issues found. The rds_port output is correctly defined and implemented.

The output is properly defined at line 37 to use local.current_engine.port, which maps to the correct port for each database engine (3306 for MySQL/Aurora MySQL, 5432 for PostgreSQL/Aurora PostgreSQL). The output is correctly referenced in the security group rule at lines 394-395, and the port configuration logic is consistently applied across RDS and Aurora modules.

terraform/modules/database/main.tf (5)

6-55: Database engine configuration is well-structured and maintainable.

The engine configuration locals approach (lines 6-55) is clear and follows a good pattern:

  • is_aurora detection is simple and reliable
  • engine_config map centralizes all per-engine settings (engine name, default version, parameter family, port)
  • current_engine lookup is straightforward
  • Default versions match PR objectives (MySQL 8.0.43, MariaDB 10.11.9, PostgreSQL 16.4, Aurora variants)

The conditional instance class selection for Aurora Serverless v2 (line 54) is correct.


86-86: Conditional RDS vs Aurora deployment is correct.

The count-based gating correctly separates concerns:

  • RDS module only creates when !is_aurora (line 86)
  • Read replicas only create for RDS (line 157)
  • Aurora module only creates when is_aurora (line 224)

This prevents resource conflicts and aligns with the multi-engine design.

Also applies to: 157-157, 224-224


233-245: Verify: Aurora instances map and serverlessv2_scaling_configuration syntax.

The instances map (lines 233-239) dynamically creates either a single serverless instance or multiple provisioned instances based on aurora_enable_serverlessv2. The serverlessv2_scaling_configuration block (lines 242-245) is conditionally set only when serverless is enabled.

This pattern appears correct, but should be verified against terraform-aws-modules/rds-aurora v9.0 module documentation to ensure:

  1. The instances map structure matches module expectations
  2. The scaling_configuration is correctly applied

Can you verify this syntax against the rds-aurora module v9.0 documentation, particularly for:

  • How the instances map should be structured
  • Whether serverlessv2_scaling_configuration is the correct variable name
  • Whether the on/off pattern with null vs configuration object works as expected

297-315: Aurora supporting resources are properly gated.

The Aurora subnet group (lines 297-305) and data sources (lines 308-315) are correctly gated by count = local.is_aurora ? 1 : 0, ensuring they're only created when using Aurora engines. The references in the Aurora module (lines 248, 251) safely use array indexing [0].


289-289: Confirmed: Aurora availability zones logic is correct.

When availability_zones is set to null, AWS RDS/Aurora auto-distributes the cluster across available AZs (multi-AZ behavior); when explicitly set to a single AZ, it restricts to that zone. The code correctly implements this: multi_az ? null : [single_az] properly controls multi-AZ vs single-AZ deployments as intended. The logic is not inverted.

Comment on lines +248 to +257
db_subnet_group_name = aws_db_subnet_group.aurora[0].name
security_group_rules = {
vpc_ingress = {
cidr_blocks = [data.aws_vpc.selected[0].cidr_block]
}
}

# Use security group from networking module
create_security_group = false
vpc_security_group_ids = [var.rds_security_group_id]
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Verify: Aurora security group configuration pattern.

The Aurora module passes security_group_rules (lines 249-253) while also setting create_security_group = false (line 256) and providing vpc_security_group_ids (line 257). This pattern needs verification with the rds-aurora module to ensure:

  1. security_group_rules is the correct way to define intra-VPC rules when not creating the security group
  2. The module correctly applies these rules to the externally-provided security group

Alternatively, consider whether the security_group_rules block is even necessary here, since the bastion-to-RDS rule is already defined separately in terraform/main.tf (lines 391-400).


🌐 Web query:

rds-aurora Terraform module v9.0 security group configuration pattern with create_security_group false

💡 Result:

Use an existing SG and pass it into the module instead of letting the module create one.

Recommended pattern

  • set create_security_group = false
  • provide the existing security-group id(s) via the module input the module expects (vpc_security_group_ids / security_group_id / allowed_security_groups depending on the module version)
  • ensure the module call concatenates only when an SG exists (module code v9.x historically had a bug when it always referenced aws_security_group.this[0] — see note below)

Example (minimal):

  • if the module expects vpc_security_group_ids:
    module "db" {
    source = "terraform-aws-modules/rds-aurora/aws"
    version = "9.0.0"
    create_security_group = false
    vpc_security_group_ids = [aws_security_group.rds_existing.id] # <-- supply existing SG(s)
    ...
    }

If the module input name is security_group_id or allowed_security_groups use that input instead.

Note about v9.x bug

  • Older v9.x module code referenced aws_security_group.this[0] unconditionally and fails when create_security_group = false. The workaround/fix is to pass only existing SG ids into the module input (so the module doesn’t need to reference an internal SG), or patch the module to use a conditional/ternary (e.g. compact(concat(var.create_security_group ? [aws_security_group.this[0].id] : [], var.vpc_security_group_ids))). See module docs and GH discussion. [1][2]

Sources

  • module documentation (conditional creation / create_security_group). [1]
  • community/issue note showing the create_security_group=false index error and ternary workaround. [2]

I need to verify a critical detail about the security_group_rules block in this context. Let me search for more specific information about whether this input is applicable when using an external security group.

I need to verify whether the rds-aurora module actually accepts security_group_rules as an input, and inspect the codebase to understand the module configuration.

The search results show that the module uses security_group_ingress_rules and security_group_egress_rules, not security_group_rules. Let me verify the exact module version and confirm the proper input variables.Let me directly inspect the codebase to verify the module version and inputs being used:

Actually, I need to clone the repo. Let me fix that:


🏁 Script executed:

#!/bin/bash
# Find the rds-aurora module source and version
grep -r "source.*rds-aurora" terraform/modules/database/

# Also look for version constraint
grep -r "version" terraform/modules/database/main.tf | head -20

Length of output: 1179


🏁 Script executed:

#!/bin/bash
# Inspect the Aurora module configuration
cat terraform/modules/database/main.tf | grep -A 30 "module.*aurora"

# Check if there's a version specification
grep -n "terraform-aws-modules/rds-aurora" terraform/modules/database/main.tf

Length of output: 1107


Let me verify what inputs are actually accepted by the rds-aurora module v9.0:

Based on my verification, the security_group_rules variable (lines 249-253) is not a valid input for the rds-aurora module v9.0. The module uses security_group_ingress_rules and security_group_egress_rules, not security_group_rules. This block will be silently ignored by the module and represents dead code that should be removed.

The core configuration pattern is correct: setting create_security_group = false with an externally provided security group via vpc_security_group_ids is the recommended approach. The module's implementation properly handles this using a try() pattern to avoid referencing the non-existent internal security group when create_security_group = false.


Remove the invalid security_group_rules block (lines 249-253). This variable is not recognized by the rds-aurora v9.0 module and serves no purpose. The recommended security group pattern—create_security_group = false with vpc_security_group_ids—is already correctly configured.

🤖 Prompt for AI Agents
In terraform/modules/database/main.tf around lines 248 to 257, remove the
invalid security_group_rules block (lines 249-253) because rds-aurora v9.0
expects security_group_ingress_rules/security_group_egress_rules and will ignore
security_group_rules; keep create_security_group = false and
vpc_security_group_ids = [var.rds_security_group_id] as-is to supply the
external SG.

Comment on lines +111 to +121
variable "aurora_min_capacity" {
description = "Minimum Aurora Capacity Units (ACUs) for Serverless v2. 0.5 to 128 in 0.5 increments."
type = number
default = 0.5
}

variable "aurora_max_capacity" {
description = "Maximum Aurora Capacity Units (ACUs) for Serverless v2. 0.5 to 128 in 0.5 increments."
type = number
default = 1.0
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add validation for Aurora Serverless v2 capacity parameters.

The aurora_min_capacity and aurora_max_capacity variables lack validation. According to AWS Aurora Serverless v2 documentation, valid values are 0.5 to 128 in 0.5 increments, and min must be ≤ max. Without validation, invalid configurations could be provisioned, causing Terraform errors or unexpected behavior.

Add validation blocks to enforce the valid range and logical constraints:

 variable "aurora_min_capacity" {
   description = "Minimum Aurora Capacity Units (ACUs) for Serverless v2. 0.5 to 128 in 0.5 increments."
   type        = number
   default     = 0.5
+  validation {
+    condition     = var.aurora_min_capacity >= 0.5 && var.aurora_min_capacity <= 128 && floor(var.aurora_min_capacity * 2) == var.aurora_min_capacity * 2
+    error_message = "aurora_min_capacity must be between 0.5 and 128 in 0.5 increments."
+  }
 }

 variable "aurora_max_capacity" {
   description = "Maximum Aurora Capacity Units (ACUs) for Serverless v2. 0.5 to 128 in 0.5 increments."
   type        = number
   default     = 1.0
+  validation {
+    condition     = var.aurora_max_capacity >= 0.5 && var.aurora_max_capacity <= 128 && floor(var.aurora_max_capacity * 2) == var.aurora_max_capacity * 2 && var.aurora_max_capacity >= var.aurora_min_capacity
+    error_message = "aurora_max_capacity must be between 0.5 and 128 in 0.5 increments and >= aurora_min_capacity."
+  }
 }

Note: The validation uses floor(x * 2) == x * 2 to check for 0.5-increment multiples (accounting for floating-point precision).

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In terraform/modules/database/variables.tf around lines 111 to 121, the
aurora_min_capacity and aurora_max_capacity variables lack validation; add
Terraform validation blocks for each to enforce numeric range 0.5..128 and 0.5
increments (use the floor(x * 2) == x * 2 check to allow 0.5 steps), and add a
cross-variable validation to ensure aurora_min_capacity <= aurora_max_capacity
(e.g., validate in aurora_min_capacity or a separate local/validation block that
references var.aurora_max_capacity), returning a clear error message when
constraints are violated.

leek and others added 2 commits November 19, 2025 13:57
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@leek
Copy link
Owner

leek commented Nov 19, 2025

@copilot will this setup "just work" with current configurations using mysql? or do resources need to be imported?

Copy link
Contributor Author

Copilot AI commented Nov 19, 2025

@copilot will this setup "just work" with current configurations using mysql? or do resources need to be imported?

Good catch! The current implementation has a breaking change due to adding count to the RDS module. Existing MySQL deployments will require state migration to avoid database recreation.

Issue: Module address changes from module.database.module.rds to module.database.module.rds[0]

Migration required:

# For existing MySQL deployments
terraform state mv 'module.database.module.rds' 'module.database.module.rds[0]'
terraform state mv 'module.database.module.rds_read_replica' 'module.database.module.rds_read_replica[0]'

I'll update the implementation to avoid this breaking change by using a conditional approach that doesn't change the resource address for the default MySQL case. Working on a fix now.

@copilot will this setup "just work" with current configurations using mysql? or do resources need to be imported?

No, existing MySQL configurations require state migration to avoid database recreation.

Issue: Adding count to the RDS module changes resource addresses from module.database.module.rds to module.database.module.rds[0].

Required migration:

terraform state mv 'module.database.module.rds' 'module.database.module.rds[0]'
terraform state mv 'module.database.module.rds_read_replica' 'module.database.module.rds_read_replica[0]'

See MIGRATION.md for complete step-by-step instructions.

Fixed in commit 88425f7 with comprehensive migration documentation.

Copilot AI changed the title Add multiple database engine support (MySQL, MariaDB, PostgreSQL, Aurora) Add multiple database engine support (MySQL, MariaDB, PostgreSQL, Aurora) - Breaking Change Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multiple DB Support

2 participants