Skip to main content
Service Catalog Version 0.118.1Last updated in version 0.105.0

RDS Read Replicas Module

This module creates a read replica (read-only copy) of a DB instance.

View Source Release Notes

Features

  • Deploy a fully-managed native relational database replica
  • Supports, MySQL, PostgreSQL, SQL Server, Oracle, and MariaDB
  • Automatic scaling of storage
  • CloudWatch Alarms for alerting when CPU, memory, and disk metrics exceed certain thresholds
  • CloudWatch dashboard widgets for RDS statistics

Sample Usage

main.tf

# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S RDS-REPLICA MODULE
# ------------------------------------------------------------------------------------------------------

module "rds_replica" {

source = "git::git@github.com:gruntwork-io/terraform-aws-service-catalog.git//modules/data-stores/rds-replica?ref=v0.118.1"

# ----------------------------------------------------------------------------------------------------
# REQUIRED VARIABLES
# ----------------------------------------------------------------------------------------------------

# The name used to namespace all the RDS resources created by these templates,
# including the cluster and cluster instances (e.g. mysql-stage). Must be
# unique in this region. Must be a lowercase string.
name = <string>

# An ID of the primary DB instance to create read replicas from
primary_instance_id = <string>

# The ID of the VPC in which to deploy RDS.
vpc_id = <string>

# ----------------------------------------------------------------------------------------------------
# OPTIONAL VARIABLES
# ----------------------------------------------------------------------------------------------------

# The ARNs of SNS topics where CloudWatch alarms (e.g., for CPU, memory, and
# disk space usage) should send notifications. Also used for the alarms if the
# share snapshot backup job fails.
alarms_sns_topic_arns = []

# The list of network CIDR blocks to allow network access to RDS from. One of
# var.allow_connections_from_cidr_blocks or
# var.allow_connections_from_security_groups must be specified for the
# database to be reachable.
allow_connections_from_cidr_blocks = []

# The list of IDs or Security Groups to allow network access to RDS from. All
# security groups must either be in the VPC specified by var.vpc_id, or a
# peered VPC with the VPC specified by var.vpc_id. One of
# var.allow_connections_from_cidr_blocks or
# var.allow_connections_from_security_groups must be specified for the
# database to be reachable.
allow_connections_from_security_groups = []

# Indicates whether major version upgrades (e.g. 9.4.x to 9.5.x) will ever be
# permitted. Note that these updates must always be manually performed and
# will never be automatically applied.
allow_major_version_upgrade = true

# If true, both the CMK's Key Policy and IAM Policies (permissions) can be
# used to grant permissions on the CMK. If false, only the CMK's Key Policy
# can be used to grant permissions on the CMK. False is more secure (and
# generally preferred), but true is more flexible and convenient.
allow_manage_key_permissions_with_iam = false

# Specifies whether any cluster modifications are applied immediately, or
# during the next maintenance window. Note that cluster modifications may
# cause degraded performance or downtime.
apply_immediately = false

# Indicates that minor engine upgrades will be applied automatically to the DB
# instance during the maintenance window. If set to true, you should set
# var.engine_version to MAJOR.MINOR and omit the .PATCH at the end (e.g., use
# 5.7 and not 5.7.11); otherwise, you'll get Terraform state drift. See
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance.html#engine_version
# for more details.
auto_minor_version_upgrade = true

# How many days to keep backup snapshots around before cleaning them up. Must
# be 1 or greater to support read replicas.
backup_retention_period = 30

# A list of IAM ARNs for users who should be given administrator access to
# this CMK (e.g. arn:aws:iam::<aws-account-id>:user/<iam-user-arn>). If this
# list is empty, and var.kms_key_arn is null, the ARN of the current user will
# be used.
cmk_administrator_iam_arns = []

# A list of IAM ARNs for users from external AWS accounts who should be given
# permissions to use this CMK (e.g. arn:aws:iam::<aws-account-id>:root).
cmk_external_user_iam_arns = []

# A list of IAM ARNs for users who should be given permissions to use this CMK
# (e.g. arn:aws:iam::<aws-account-id>:user/<iam-user-arn>). If this list is
# empty, and var.kms_key_arn is null, the ARN of the current user will be
# used.
cmk_user_iam_arns = []

# Copy all the RDS instance tags to snapshots. Default is false.
copy_tags_to_snapshot = false

# If set to true, create a KMS CMK and use it to encrypt data on disk in the
# database. The permissions for this CMK will be assigned by the following
# variables: cmk_administrator_iam_arns, cmk_user_iam_arns,
# cmk_external_user_iam_arns, allow_manage_key_permissions.
create_custom_kms_key = false

# Set to true if you want a DNS record automatically created and pointed at
# the RDS endpoints.
create_route53_entry = false

# Configure a custom parameter group for the RDS DB. This will create a new
# parameter group with the given parameters. When null, the database will be
# launched with the default parameter group.
custom_parameter_group = null

# A map of custom tags to apply to the RDS Instance and the Security Group
# created for it. The key is the tag name and the value is the tag value.
custom_tags = {}

# Parameters for the cpu usage widget to output for use in a CloudWatch
# dashboard.
dashboard_cpu_usage_widget_parameters = {"height":6,"period":60,"width":8}

# Parameters for the database connections widget to output for use in a
# CloudWatch dashboard.
dashboard_db_connections_widget_parameters = {"height":6,"period":60,"width":8}

# Parameters for the available disk space widget to output for use in a
# CloudWatch dashboard.
dashboard_disk_space_widget_parameters = {"height":6,"period":60,"width":8}

# Parameters for the available memory widget to output for use in a CloudWatch
# dashboard.
dashboard_memory_widget_parameters = {"height":6,"period":60,"width":8}

# Parameters for the read latency widget to output for use in a CloudWatch
# dashboard.
dashboard_read_latency_widget_parameters = {"height":6,"period":60,"width":8}

# Parameters for the read latency widget to output for use in a CloudWatch
# dashboard.
dashboard_write_latency_widget_parameters = {"height":6,"period":60,"width":8}

# Set to true to enable several basic CloudWatch alarms around CPU usage,
# memory usage, and disk space usage. If set to true, make sure to specify SNS
# topics to send notifications to using var.alarms_sns_topic_arn.
enable_cloudwatch_alarms = true

# When true, enable CloudWatch metrics for the manual snapshots created for
# the purpose of sharing with another account.
enable_cloudwatch_metrics = true

# Enable deletion protection on the RDS instance. If this is enabled, the
# database cannot be deleted prior to disabling
enable_deletion_protection = false

# Set to true to enable alarms related to performance, such as read and write
# latency alarms. Set to false to disable those alarms if you aren't sure what
# would be reasonable perf numbers for your RDS set up or if those numbers are
# too unpredictable.
enable_perf_alarms = true

# List of log types to enable for exporting to CloudWatch logs. If omitted, no
# logs will be exported. Valid values (depending on engine): alert, audit,
# error, general, listener, slowquery, trace, postgresql (PostgreSQL) and
# upgrade (PostgreSQL).
enabled_cloudwatch_logs_exports = []

# The period, in seconds, over which to measure the CPU utilization
# percentage.
high_cpu_utilization_period = 60

# Trigger an alarm if the DB instance has a CPU utilization percentage above
# this threshold.
high_cpu_utilization_threshold = 90

# Sets how this alarm should handle entering the INSUFFICIENT_DATA state.
# Based on
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data.
# Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.
high_cpu_utilization_treat_missing_data = "missing"

# The period, in seconds, over which to measure the read latency.
high_read_latency_period = 60

# Trigger an alarm if the DB instance read latency (average amount of time
# taken per disk I/O operation), in seconds, is above this threshold.
high_read_latency_threshold = 5

# The period, in seconds, over which to measure the write latency.
high_write_latency_period = 60

# Trigger an alarm if the DB instance write latency (average amount of time
# taken per disk I/O operation), in seconds, is above this threshold.
high_write_latency_threshold = 5

# The ID of the Route 53 hosted zone into which the Route 53 DNS record should
# be written
hosted_zone_id = null

# Specifies whether mappings of AWS Identity and Access Management (IAM)
# accounts to database accounts is enabled. Disabled by default.
iam_database_authentication_enabled = false

# The instance type to use for the db (e.g. db.t3.micro)
instance_type = "db.t3.micro"

# The amount of provisioned IOPS for the primary instance. Setting this
# implies a storage_type of 'io1'. Can only be set when storage_type is 'gp3'
# or 'io1'. Set to 0 to disable.
iops = 0

# The Amazon Resource Name (ARN) of an existing KMS customer master key (CMK)
# that will be used to encrypt/decrypt backup files. If you leave this blank,
# the default RDS KMS key for the account will be used. If you set
# var.create_custom_kms_key to true, this value will be ignored and a custom
# key will be created and used instead.
kms_key_arn = null

# The period, in seconds, over which to measure the available free disk space.
low_disk_space_available_period = 60

# Trigger an alarm if the amount of disk space, in Bytes, on the DB instance
# drops below this threshold.
low_disk_space_available_threshold = 1000000000

# Sets how this alarm should handle entering the INSUFFICIENT_DATA state.
# Based on
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data.
# Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.
low_disk_space_available_treat_missing_data = "missing"

# The period, in seconds, over which to measure the available free memory.
low_memory_available_period = 60

# Trigger an alarm if the amount of free memory, in Bytes, on the DB instance
# drops below this threshold.
low_memory_available_threshold = 100000000

# Sets how this alarm should handle entering the INSUFFICIENT_DATA state.
# Based on
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data.
# Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.
low_memory_available_treat_missing_data = "missing"

# When configured, the upper limit to which Amazon RDS can automatically scale
# the storage of the DB instance. Configuring this will automatically ignore
# differences to allocated_storage. Must be greater than or equal to
# allocated_storage or 0 to disable Storage Autoscaling.
max_allocated_storage = 0

# The number of read replicas to deploy
num_read_replicas = 0

# Specifies whether Performance Insights are enabled. Performance Insights can
# be enabled for specific versions of database engines. See
# https://aws.amazon.com/rds/performance-insights/ for more details.
performance_insights_enabled = false

# The port the DB will listen on (e.g. 3306). Alternatively, this can be
# provided via AWS Secrets Manager. See the description of
# db_config_secrets_manager_id.
port = null

# If you wish to make your database accessible from the public Internet, set
# this flag to true (WARNING: NOT RECOMMENDED FOR REGULAR USAGE!!). The
# default is false, which means the database is only accessible from within
# the VPC, which is much more secure. This flag MUST be false for serverless
# mode.
publicly_accessible = false

# The domain name to create a route 53 record for the read replicas of the RDS
# database.
replica_domain_name = null

# Determines whether a final DB snapshot is created before the DB instance is
# deleted. Be very careful setting this to true; if you do, and you delete
# this DB instance, you will not have any backups of the data! You almost
# never want to set this to true, unless you are doing automated or manual
# testing.
skip_final_snapshot = false

# Specifies whether the DB instance is encrypted.
storage_encrypted = true

# The type of storage to use for the primary instance. Must be one of
# 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (general purpose
# SSD that needs iops independently), or 'io1' (provisioned IOPS SSD).
storage_type = "gp2"

# Trigger an alarm if the number of connections to the DB instance goes above
# this threshold.
too_many_db_connections_threshold = null

# Sets how this alarm should handle entering the INSUFFICIENT_DATA state.
# Based on
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data.
# Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.
too_many_db_connections_treat_missing_data = "missing"

}


Reference

Required

namestringrequired

The name used to namespace all the RDS resources created by these templates, including the cluster and cluster instances (e.g. mysql-stage). Must be unique in this region. Must be a lowercase string.

primary_instance_idstringrequired

An ID of the primary DB instance to create read replicas from

vpc_idstringrequired

The ID of the VPC in which to deploy RDS.

Optional

alarms_sns_topic_arnslist(string)optional

The ARNs of SNS topics where CloudWatch alarms (e.g., for CPU, memory, and disk space usage) should send notifications. Also used for the alarms if the share snapshot backup job fails.

[]

The list of network CIDR blocks to allow network access to RDS from. One of allow_connections_from_cidr_blocks or allow_connections_from_security_groups must be specified for the database to be reachable.

[]

The list of IDs or Security Groups to allow network access to RDS from. All security groups must either be in the VPC specified by vpc_id, or a peered VPC with the VPC specified by vpc_id. One of allow_connections_from_cidr_blocks or allow_connections_from_security_groups must be specified for the database to be reachable.

[]

Indicates whether major version upgrades (e.g. 9.4.x to 9.5.x) will ever be permitted. Note that these updates must always be manually performed and will never be automatically applied.

true

If true, both the CMK's Key Policy and IAM Policies (permissions) can be used to grant permissions on the CMK. If false, only the CMK's Key Policy can be used to grant permissions on the CMK. False is more secure (and generally preferred), but true is more flexible and convenient.

false
apply_immediatelybooloptional

Specifies whether any cluster modifications are applied immediately, or during the next maintenance window. Note that cluster modifications may cause degraded performance or downtime.

false

Indicates that minor engine upgrades will be applied automatically to the DB instance during the maintenance window. If set to true, you should set engine_version to MAJOR.MINOR and omit the .PATCH at the end (e.g., use 5.7 and not 5.7.11); otherwise, you'll get Terraform state drift. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance.html#engine_version for more details.

true

How many days to keep backup snapshots around before cleaning them up. Must be 1 or greater to support read replicas.

30
cmk_administrator_iam_arnslist(string)optional

A list of IAM ARNs for users who should be given administrator access to this CMK (e.g. arn:aws:iam::<aws-account-id>:user/<iam-user-arn>). If this list is empty, and kms_key_arn is null, the ARN of the current user will be used.

[]
cmk_external_user_iam_arnslist(string)optional

A list of IAM ARNs for users from external AWS accounts who should be given permissions to use this CMK (e.g. arn:aws:iam::<aws-account-id>:root).

[]
cmk_user_iam_arnslist(object(…))optional

A list of IAM ARNs for users who should be given permissions to use this CMK (e.g. arn:aws:iam::<aws-account-id>:user/<iam-user-arn>). If this list is empty, and kms_key_arn is null, the ARN of the current user will be used.

list(object({
name = list(string)
conditions = list(object({
test = string
variable = string
values = list(string)
}))
}))
[]
Example
  [
{
name = "arn:aws:iam::0000000000:user/dev"
conditions = [{
test = "StringLike"
variable = "kms:ViaService"
values = ["s3.ca-central-1.amazonaws.com"]
}]
},
]

Copy all the RDS instance tags to snapshots. Default is false.

false

If set to true, create a KMS CMK and use it to encrypt data on disk in the database. The permissions for this CMK will be assigned by the following variables: cmk_administrator_iam_arns, cmk_user_iam_arns, cmk_external_user_iam_arns, allow_manage_key_permissions.

false

Set to true if you want a DNS record automatically created and pointed at the RDS endpoints.

false
custom_parameter_groupobject(…)optional

Configure a custom parameter group for the RDS DB. This will create a new parameter group with the given parameters. When null, the database will be launched with the default parameter group.

object({
# Name of the parameter group to create
name = string

# The family of the DB parameter group.
family = string

# The parameters to configure on the created parameter group.
parameters = list(object({
# Parameter name to configure.
name = string

# Vaue to set the parameter.
value = string

# When to apply the parameter. "immediate" or "pending-reboot".
apply_method = string
}))
})
null
Details

The family of the DB parameter group.

Details

The parameters to configure on the created parameter group.

Details

Vaue to set the parameter.

Details

When to apply the parameter. "immediate" or "pending-reboot".

custom_tagsmap(string)optional

A map of custom tags to apply to the RDS Instance and the Security Group created for it. The key is the tag name and the value is the tag value.

{}

Parameters for the cpu usage widget to output for use in a CloudWatch dashboard.

object({
# The period in seconds for metrics to sample across.
period = number

# The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
# space.
width = number
height = number
})
{
height = 6,
period = 60,
width = 8
}
Details

The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
space.

Parameters for the database connections widget to output for use in a CloudWatch dashboard.

object({
# The period in seconds for metrics to sample across.
period = number

# The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
# space.
width = number
height = number
})
{
height = 6,
period = 60,
width = 8
}
Details

The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
space.

Parameters for the available disk space widget to output for use in a CloudWatch dashboard.

object({
# The period in seconds for metrics to sample across.
period = number

# The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
# space.
width = number
height = number
})
{
height = 6,
period = 60,
width = 8
}
Details

The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
space.

Parameters for the available memory widget to output for use in a CloudWatch dashboard.

object({
# The period in seconds for metrics to sample across.
period = number

# The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
# space.
width = number
height = number
})
{
height = 6,
period = 60,
width = 8
}
Details

The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
space.

Parameters for the read latency widget to output for use in a CloudWatch dashboard.

object({
# The period in seconds for metrics to sample across.
period = number

# The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
# space.
width = number
height = number
})
{
height = 6,
period = 60,
width = 8
}
Details

The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
space.

Parameters for the read latency widget to output for use in a CloudWatch dashboard.

object({
# The period in seconds for metrics to sample across.
period = number

# The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
# space.
width = number
height = number
})
{
height = 6,
period = 60,
width = 8
}
Details

The width and height of the widget in grid units in a 24 column grid. E.g., a value of 12 will take up half the
space.

Set to true to enable several basic CloudWatch alarms around CPU usage, memory usage, and disk space usage. If set to true, make sure to specify SNS topics to send notifications to using alarms_sns_topic_arn.

true

When true, enable CloudWatch metrics for the manual snapshots created for the purpose of sharing with another account.

true

Enable deletion protection on the RDS instance. If this is enabled, the database cannot be deleted prior to disabling

false
enable_perf_alarmsbooloptional

Set to true to enable alarms related to performance, such as read and write latency alarms. Set to false to disable those alarms if you aren't sure what would be reasonable perf numbers for your RDS set up or if those numbers are too unpredictable.

true

List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on engine): alert, audit, error, general, listener, slowquery, trace, postgresql (PostgreSQL) and upgrade (PostgreSQL).

[]

The period, in seconds, over which to measure the CPU utilization percentage.

60

Trigger an alarm if the DB instance has a CPU utilization percentage above this threshold.

90

Sets how this alarm should handle entering the INSUFFICIENT_DATA state. Based on https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data. Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.

"missing"

The period, in seconds, over which to measure the read latency.

60

Trigger an alarm if the DB instance read latency (average amount of time taken per disk I/O operation), in seconds, is above this threshold.

5

The period, in seconds, over which to measure the write latency.

60

Trigger an alarm if the DB instance write latency (average amount of time taken per disk I/O operation), in seconds, is above this threshold.

5
hosted_zone_idstringoptional

The ID of the Route 53 hosted zone into which the Route 53 DNS record should be written

null

Specifies whether mappings of AWS Identity and Access Management (IAM) accounts to database accounts is enabled. Disabled by default.

false
instance_typestringoptional

The instance type to use for the db (e.g. db.t3.micro)

"db.t3.micro"
iopsnumberoptional

The amount of provisioned IOPS for the primary instance. Setting this implies a storage_type of 'io1'. Can only be set when storage_type is 'gp3' or 'io1'. Set to 0 to disable.

0
kms_key_arnstringoptional

The Amazon Resource Name (ARN) of an existing KMS customer master key (CMK) that will be used to encrypt/decrypt backup files. If you leave this blank, the default RDS KMS key for the account will be used. If you set create_custom_kms_key to true, this value will be ignored and a custom key will be created and used instead.

null

The period, in seconds, over which to measure the available free disk space.

60

Trigger an alarm if the amount of disk space, in Bytes, on the DB instance drops below this threshold.

1000000000
Details

Default is 1GB (1 billion bytes)

Sets how this alarm should handle entering the INSUFFICIENT_DATA state. Based on https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data. Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.

"missing"

The period, in seconds, over which to measure the available free memory.

60

Trigger an alarm if the amount of free memory, in Bytes, on the DB instance drops below this threshold.

100000000
Details

Default is 100MB (100 million bytes)

Sets how this alarm should handle entering the INSUFFICIENT_DATA state. Based on https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data. Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.

"missing"
max_allocated_storagenumberoptional

When configured, the upper limit to which Amazon RDS can automatically scale the storage of the DB instance. Configuring this will automatically ignore differences to allocated_storage. Must be greater than or equal to allocated_storage or 0 to disable Storage Autoscaling.

0
num_read_replicasnumberoptional

The number of read replicas to deploy

0

Specifies whether Performance Insights are enabled. Performance Insights can be enabled for specific versions of database engines. See https://aws.amazon.com/rds/performance-insights/ for more details.

false
portnumberoptional

The port the DB will listen on (e.g. 3306). Alternatively, this can be provided via AWS Secrets Manager. See the description of db_config_secrets_manager_id.

null

If you wish to make your database accessible from the public Internet, set this flag to true (WARNING: NOT RECOMMENDED FOR REGULAR USAGE!!). The default is false, which means the database is only accessible from within the VPC, which is much more secure. This flag MUST be false for serverless mode.

false
replica_domain_namestringoptional

The domain name to create a route 53 record for the read replicas of the RDS database.

null

Determines whether a final DB snapshot is created before the DB instance is deleted. Be very careful setting this to true; if you do, and you delete this DB instance, you will not have any backups of the data! You almost never want to set this to true, unless you are doing automated or manual testing.

false
storage_encryptedbooloptional

Specifies whether the DB instance is encrypted.

true
storage_typestringoptional

The type of storage to use for the primary instance. Must be one of 'standard' (magnetic), 'gp2' (general purpose SSD), 'gp3' (general purpose SSD that needs iops independently), or 'io1' (provisioned IOPS SSD).

"gp2"

Trigger an alarm if the number of connections to the DB instance goes above this threshold.

null
Details

The max number of connections allowed by RDS depends a) the type of DB, b) the DB instance type, and c) the
use case, and it can vary from ~30 all the way up to 5,000, so we cannot pick a reasonable default here.

Sets how this alarm should handle entering the INSUFFICIENT_DATA state. Based on https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data. Must be one of: 'missing', 'ignore', 'breaching' or 'notBreaching'.

"missing"