Terraform RDS Cluster Provisioning, Management, and Multi-Region Failover

AWS Relational Database Service provides hosted relational databases that are easier to operate and maintain than self-managed implementations. Terraform can provision, scale, and modify RDS, enabling you to manage the RDS instance and cluster life cycle programmatically, safely, and declaratively.

The standard Terraform workflow for RDS work covers provisioning an RDS instance, subnet group, and parameter group, modifying the RDS instance configuration, and provisioning a replica instance. These operations form the basis for building production-grade clusters with Aurora MySQL or Aurora PostgreSQL, serverless or provisioned modes, and cross-region resilience.

Core Terraform RDS Concepts

Terraform interacts with RDS through the AWS provider, which abstracts the AWS API into declarative resources. The provider configuration defines region, profile, and default tags that are applied to all created resources.

provider "aws" { region = local.region_0 profile = "<profile-name>" default_tags { tags = { Owner = "primary" Project = "AWS Multi Region rds with active/active setup" Provisioner = "Terraform" } } }

A secondary provider alias is used for multi-region architectures.

provider "aws" { alias = "secondory" region = local.region_1 profile = "<profile-name>" default_tags { tags = { Owner = "secondory" Project = "AWS Multi Region rds with active/active setup" Provisioner = "Terraform" } } }

Terraform data sources allow you to fetch information from your cloud provider and use it within your configuration. Data sources are essential for referencing existing VPCs, subnets, security groups, and Secrets Manager secrets without hard-coding identifiers.

Aurora Cluster Modules and Configuration Patterns

Community modules simplify Aurora cluster creation. A Terraform module to provision an RDS Aurora cluster for MySQL or Postgres supports Amazon Aurora Serverless. For a complete example, see examples/complete.

Module usage typically pins to a specific version.

module "rds_cluster_aurora_postgres" { source = "cloudposse/rds-cluster/aws" # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" name = "postgres" engine = "aurora-postgresql" cluster_family = "aurora-postgresql9.6" # 1 writer, 1 reader cluster_size = 2 # 1 writer, 3 reader # cluster_size = 4 # 1 writer, 5 reader # cluster_size = 6 namespace = "eg" stage = "dev" admin_user = "admin1" admin_password = "Test123456789" db_name = "dbname" db_port = 5432 instance_type = "db.r4.large" vpc_id = "vpc-xxxxxxxx" security_groups = ["sg-xxxxxxxx"] subnets = ["subnet-xxxxxxxx", "subnet-xxxxxxxx"] zone_id = "Zxxxxxxxx" }

Serverless configuration uses a different engine mode and scaling settings.

module "rds_cluster_aurora_mysql_serverless" { source = "cloudposse/rds-cluster/aws" # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" namespace = "eg" stage = "dev" name = "db" engine = "aurora" engine_mode = "serverless" cluster_family = "aurora5.6" cluster_size = 0 admin_user = "admin1" admin_password = "Test123456789" db_name = "dbname" db_port = 3306 instance_type = "db.t2.small" vpc_id = "vpc-xxxxxxxx" security_groups = ["sg-xxxxxxxx"] subnets = ["subnet-xxxxxxxx", "subnet-xxxxxxxx"] zone_id = "Zxxxxxxxx" enable_http_endpoint = true scaling_configuration = [ { auto_pause = true max_capacity = 256 min_capacity = } ] }

A simpler module for managing a simple Aurora Postgres cluster gets a list of inputs and creates an Aurora Postgres Cluster with a configurable number of instances. In addition, it creates a secret on AWS Secrets Manager to store credentials to access the recently created cluster. This output secret has the root user, password, endpoint and readerendpoint, that represents the read-only endpoint for the Aurora cluster, automatically load-balanced across replicas. You can see more information on awsrds_cluster documentation.

There is a naming convention for the created resources, and the caller is allowed to provide some prefixes and suffixes, that are used to build the names.

Module Parameters and Options

The Aurora cluster modules expose a large surface area for customization. Key parameters include:

Parameter Description Default Required
copytagsto_snapshot Copy tags to backup snapshots false no
databaseinsightsmode The database insights mode for the RDS cluster. Valid values are standard, advanced null no
dbclusterinstance_class This setting is required to create a provisioned Multi-AZ DB cluster null no
db_name Database name "" no
dbparametergroup_name The name to give to the created awsdbparameter_group resource. If omitted, the module will generate a name "" no
db_port Database port 3306 no
deletion_protection If the DB instance should have deletion protection enabled false no
delimiter Delimiter to be used between ID elements. Defaults to- (hyphen). Set to "" to use no delimiter at all null no
descriptor_formats Describe additional descriptors to be output in the descriptors output map. Map of maps null no

Engine and sizing choices drive architecture decisions.

Engine Typical Engine Mode Cluster Size Meaning Use Case
aurora-postgresql provisioned 1 writer + N readers Production OLTP with read scaling
aurora serverless 0 Variable load, cost optimization
aurora5.6 serverless auto scaling MySQL compatible serverless

The cluster_size parameter maps to instance count. A value of 2 represents 1 writer, 1 reader. A value of 4 represents 1 writer, 3 readers. A value of 6 represents 1 writer, 5 readers.

Password Management and Secrets Rotation

Managing DB passwords in AWS Secrets Manager is a recommended practice. The module creates a secret containing credentials to access the cluster.

A post about creating AWS RDS cluster and managing DB passwords in 2024 demonstrates creating Aurora PostgreSQL Serverless DB using an existing terraform module. The rotation schedule by default is 7 days.

And that's it. We created RDS cluster and managing master password in most secure way with enabled rotation.

In the next post I will be providing details on how to configure secure access to RDS instances using Terraform.

Password rotation automation relies on Secrets Manager integration and can be enabled via module outputs that expose secret ARN, endpoint, and reader_endpoint.

Multi-Region Deployment and Failover

Deploying a multi-region AWS RDS cluster with an automatic failover setup using Terraform leverages AWS RDS and Terraform to set up highly available, fault-tolerant database architectures across multiple regions. This ensures that your applications remain online even in the event of regional outages, providing resilience and scalability for critical applications.

Before starting, ensure you have the following:
- AWS Account: An active AWS account with the necessary permissions.
- AWS CLI: AWS CLI should be configured with your AWS credentials.
- Terraform Installed: Terraform must be installed on your local machine. You can download it from Terraform’s official site.

Multi-region patterns typically use separate provider aliases per region, shared security groups and subnet groups per region, and cross-region read replicas or global database configuration.

The provider file tells Terraform which provider you are using. Default tags are applied per provider to distinguish primary and secondary ownership.

Networking Prerequisites

RDS clusters require subnet groups spanning multiple Availability Zones. Terraform provisioning includes creation of an RDS instance, subnet group, and parameter group. Modifying the RDS instance configuration and provisioning a replica instance completes a baseline highly available setup.

Common networking inputs are:
- vpcid
- security
groups
- subnets
- zone_id

These inputs are passed to the module to ensure the cluster is placed in private subnets with controlled ingress.

Operational Considerations

Deletion protection can be toggled via deletion_protection parameter. When enabled, Terraform will prevent accidental destruction of the cluster.

Database insights mode can be set to standard or advanced to enable performance monitoring.

The dbparametergroup_name parameter allows custom parameter groups for engine tuning. If omitted, the module will generate a name.

The delimiter parameter controls naming conventions between ID elements. Defaults to hyphen.

Tag copying to snapshots is controlled via copytagsto_snapshot.

Instance class selection impacts cost and performance. Provisioned clusters use dbclusterinstanceclass for Multi-AZ deployments. Serverless clusters use scalingconfiguration with autopause, maxcapacity, min_capacity.

End-to-End Example Flow

  1. Define providers for primary and secondary regions with distinct tags.
  2. Reference existing VPC data sources for subnet and security group IDs.
  3. Declare the Aurora cluster module with engine, clusterfamily, clustersize, and networking inputs.
  4. Output the cluster endpoint, reader_endpoint, and Secrets Manager secret ARN.
  5. For multi-region failover, create a second cluster in the secondary region and configure cross-region replication or global database.

This workflow enables you to manage the RDS instance and cluster life cycle programmatically, safely, and declaratively.

Conclusion

Terraform RDS cluster management spans from basic provisioning of an RDS instance, subnet group, and parameter group to sophisticated multi-region active/active architectures with automatic failover. Modules such as cloudposse/rds-cluster/aws accelerate adoption by encapsulating best practices for Aurora Postgres and MySQL, serverless and provisioned modes, Secrets Manager integration, and naming conventions.

Key capabilities demonstrated across references include programmatic creation of Aurora clusters with configurable instance counts, serverless scaling with auto_pause and capacity bounds, password rotation with a default 7 day schedule, and multi-region provider configurations with default tags for ownership tracking. The combination of provider aliasing, data sources, and module outputs provides a repeatable path to highly available, fault-tolerant database architectures while keeping secrets and credentials managed securely in AWS Secrets Manager.

Sources

  1. https://developer.hashicorp.com/terraform/tutorials/aws/aws-rds
  2. https://github.com/cloudposse/terraform-aws-rds-cluster
  3. https://dev.to/aws-builders/terraform-deploying-multi-region-aws-rds-cluster-with-failover-setup-using-terraform-4ahg
  4. https://github.com/madelabs/terraform-aws-rds-cluster
  5. https://dev.to/aws-builders/create-rds-cluster-and-manage-passwords-in-2024-4n3d

Related Posts