AWS RDS Terraform module
Terraform module which creates RDS resources on AWS.
Root module calls these modules which can also be used separately to create independent resources:
- db_instance - creates RDS DB instance
- db_subnet_group - creates RDS DB subnet group
- db_parameter_group - creates RDS DB parameter group
- db_option_group - creates RDS DB option group
- db_instance_role_association - creates RDS DB instance role association resources
Usage
module "db" {
source = "terraform-aws-modules/rds/aws"
identifier = "demodb"
engine = "mysql"
engine_version = "8.0"
instance_class = "db.t3a.large"
allocated_storage = 5
db_name = "demodb"
username = "user"
port = "3306"
iam_database_authentication_enabled = true
vpc_security_group_ids = ["sg-12345678"]
maintenance_window = "Mon:00:00-Mon:03:00"
backup_window = "03:00-06:00"
# Enhanced Monitoring - see example for details on how to create the role
# by yourself, in case you don't want to create it automatically
monitoring_interval = "30"
monitoring_role_name = "MyRDSMonitoringRole"
create_monitoring_role = true
tags = {
Owner = "user"
Environment = "dev"
}
# DB subnet group
create_db_subnet_group = true
subnet_ids = ["subnet-12345678", "subnet-87654321"]
# DB parameter group
family = "mysql8.0"
# DB option group
major_engine_version = "8.0"
# Database Deletion Protection
deletion_protection = true
parameters = [
{
name = "character_set_client"
value = "utf8mb4"
},
{
name = "character_set_server"
value = "utf8mb4"
}
]
options = [
{
option_name = "MARIADB_AUDIT_PLUGIN"
option_settings = [
{
name = "SERVER_AUDIT_EVENTS"
value = "CONNECT"
},
{
name = "SERVER_AUDIT_FILE_ROTATIONS"
value = "37"
},
]
},
]
}
Conditional creation
The following values are provided to toggle on/off creation of the associated resources as desired:
module "db" {
source = "terraform-aws-modules/rds/aws"
# Disable creation of RDS instance(s)
create_db_instance = false
# Disable creation of option group - provide an option group or default AWS default
create_db_option_group = false
# Disable creation of parameter group - provide a parameter group or default to AWS default
create_db_parameter_group = false
# Enable creation of subnet group (disabled by default)
create_db_subnet_group = true
# Enable creation of monitoring IAM role
create_monitoring_role = true
# ... omitted
}
Option Groups
Users have the ability to:
- Create an option group with the name provided:
option_group_name = "prod-instance-mysql-8.0"
option_group_use_name_prefix = false
- Create an option group using a unique prefix beginning with the name provided:
option_group_name = "prod-instance-mysql-8.0"
- Pass the name of an option group to use that has been created outside of the module:
create_db_option_group = false
option_group_name = "prod-instance-mysql-8.0" # must already exist in AWS
- Skip creating an option group for PostgreSQL entirely as that is not supported
engine = "postgres"
option_group_name = "prod-instance-postgresql-11.0" # this will be ignored, no option group created
- Use a default option group provided by AWS
create_db_option_group = false
Parameter Groups
Users have the ability to:
- Create a parameter group with the name provided:
parameter_group_name = "prod-instance-mysql-8.0"
parameter_group_use_name_prefix = false
- Create a parameter group using a unique prefix beginning with the name provided:
parameter_group_name = "prod-instance-mysql-8.0"
- Pass the name of a parameter group to use that has been created outside of the module:
create_db_parameter_group = false
parameter_group_name = "prod-instance-mysql-8.0" # must already exist in AWS
- Use a default parameter group provided by AWS
create_db_parameter_group = false
Known limitations (Terraform/OpenTofu, not this module)
A few requests come up again and again and cannot be implemented by this
module, or by any module: Terraform requires lifecycle arguments to be
literal values inside the resource block.
hashicorp/terraform#18367
has been open since 2018,
#22544 since 2019, and
opentofu/opentofu#1329 is
the same request for OpenTofu.
- terraform destroy deleted a production database - Native option: set
deletion_protection = true, which this module already exposes. For a stop at plan time, fork and addprevent_destroy. - Terraform wants to reset the database password on every plan - Native
option: hand rotation to AWS with
manage_master_user_password, which this module already exposes. Otherwise fork and addignore_changes = [password].
Compliance.tf serves this module with
these rules applied at download time, on top of whatever your organization
already has enabled there. Inputs and outputs do not change; the source line
does. Drop the version argument and pin the release you use by adding
&version= and that release number to the URL. To get started, register a free
compliance.tf account and configure an access token:
source = "https://registry.compliance.tf/terraform-aws-modules/rds/aws?add_rules=lifecycle_ignore_secret_rotation,lifecycle_prevent_destroy_data"
The full workaround for each item above, and the exact diff each rule makes, are in the compliance.tf docs for this module. To preview a diff without an account, open this module in the Rules Playground.
Disclosure: written by this module's maintainer, who also builds compliance.tf.
Examples
- Complete RDS example for MSSQL
- Complete RDS example for MySQL
- Complete RDS example for Oracle
- Complete RDS example for PostgreSQL
- Cross Region Replica example for PostgreSQL
- Enhanced monitoring example
- Parameter and Option Groups example for MySQL
- Replica RDS example for MySQL
- Replica RDS example for PostgreSQL
- Role association example for PostgreSQL
- S3 import example for MySQL
- Blue/Green Deployment example for MySQL and PostgreSQL
Notes
- This module does not create RDS security group. Use terraform-aws-security-group module for this.
- For an RDS instance with
storage_typeusinggp3, be aware thatiopsandstorage_throughputcannot be specified if theallocated_storagevalue is below a per-enginethreshold. See the RDS User Guide for details.
Authors
Module is maintained by Anton Babenko with help from these awesome contributors.
License
Apache 2 Licensed. See LICENSE for full details.
Additional information for users from Russia and Belarus
- Russia has illegally annexed Crimea in 2014 and brought the war in Donbas followed by full-scale invasion of Ukraine in 2022.
- Russia has brought sorrow and devastations to millions of Ukrainians, killed hundreds of innocent people, damaged thousands of buildings, and forced several million people to flee.
- Putin khuylo!