Terraform adoption for Amazon Aurora Serverless v2 centers on a counterintuitive configuration pattern where the cluster resource is declared with enginemode = "provisioned" while individual cluster instances use instanceclass = "db.serverless" and the cluster carries a serverlessv2scalingconfiguration block. This pattern is documented across migration guides and Terraform module references, and it enables infrastructure as code management of both greenfield Serverless v2 deployments and zero-downtime migrations from provisioned Aurora clusters. The operational narrative is one of treating Serverless v2 capacity as an Aurora Replica that can be introduced as a reader, synchronized, and promoted through the built-in failover mechanism, with Terraform state management providing repeatable and auditable control over the instance class change.
The broader context for the pattern is the cost and scaling profile of Serverless v2. It is described as great for development environments, staging, and production workloads with variable traffic patterns. When workload is steady and predictable, provisioned instances remain the recommended choice. If consistently use around 16 ACU worth of capacity, a provisioned db.r6g.xlarge with 4 vCPU, 32GB may be cheaper depending on Region, engine, utilization pattern, and current AWS pricing. The mixed cluster approach with a provisioned writer and serverless readers is presented as giving the best of both worlds and is often the right choice for production.
Aurora Serverless v2 offers auto-scaling that scales compute capacity from 0.5 to 128 ACUs in seconds, cost efficiency through pay only for the capacity you use, high availability with built-in fault tolerance across multiple AZs, and performance up to 5x faster than standard MySQL. Before starting a migration, prerequisites include an RDS instance running MySQL 5.7+ or PostgreSQL 10+, AWS CLI configured with appropriate permissions, Terraform installed for infrastructure as code, application connection strings that can be updated, and a backup of the current database.
Prerequisites and Cluster Preparation
Cluster preparation begins with compatibility verification for the existing Aurora cluster. The migration strategy outlined for seamless switching from a provisioned cluster to Serverless v2 requires the existing Aurora cluster to be compatible with Serverless v2 before any change is made. The real world consequence for a team is that an incompatible engine version or parameter group can block the entire migration and force a rework of the baseline cluster. Compatibility checks therefore become a gate for the infrastructure pipeline.
The zero-downtime approach involves creating an Aurora read replica from RDS, promoting the replica to a standalone cluster, enabling Serverless v2 on the cluster, and switching application traffic with minimal disruption. The impact layer for this sequence is that the application continues to write to the provisioned writer while the Serverless v2 reader synchronizes, eliminating a maintenance window and preserving service level objectives.
Infrastructure as Code with Terraform
Terraform is used to manage the addition and conversion of instances to ensure repeatability and control. Terraform's state management allows the addition of a new resource without affecting the existing writer or provisioned readers. This property is critical because it permits the introduction of Serverless v2 capacity as a reader before promotion to writer.
A basic Aurora Serverless v2 cluster definition in Terraform follows this structure:
hcl
resource "aws_rds_cluster" "serverless" {
cluster_identifier = "myapp-serverless"
engine = "aurora-postgresql"
engine_version = "16.2"
engine_mode = "provisioned"
database_name = "myapp"
master_username = "app_admin"
master_password = var.db_password
db_subnet_group_name = aws_db_subnet_group.aurora.name
vpc_security_group_ids = [aws_security_group.aurora.id]
serverlessv2_scaling_configuration {
min_capacity = 0.5
max_capacity = 16
}
backup_retention_period = 14
preferred_backup_window = "03:00-04:00"
storage_encrypted = true
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "myapp-serverless-final"
enabled_cloudwatch_logs_exports = ["postgresql"]
tags = {
Name = "myapp-serverless"
Environment = var.environment
}
}
The serverlessv2scalingconfiguration block defines min and max ACU capacity, and Aurora handles the scaling. The key is that enginemode remains provisioned for Serverless v2. The writer instance is then created with instanceclass = "db.serverless".
hcl
resource "aws_rds_cluster_instance" "serverless_writer" {
identifier = "myapp-serverless-writer"
cluster_identifier = aws_rds_cluster.serverless.id
instance_class = "db.serverless"
engine = aws_rds_cluster.serverless.engine
engine_version =
This configuration is repeated across examples with different engine versions. One example uses engine = "aurora-postgresql" engineversion = "13.6" enginemode = "provisioned" with masterusername, masterpassword, port = 5432, databasename, vpcsecuritygroupids, dbsubnetgroupname, dbclusterparametergroupname, skipfinalsnapshot = true, applyimmediately = true.
The corresponding instance resource is:
hcl
resource "aws_rds_cluster_instance" "example" {
depends_on = [
null_resource.aws_rds_cluster_add_serverless_v2_scaling_configuration,
]
cluster_identifier = aws_rds_cluster.example.id
identifier = "${local.aurora_cluster_identifier}-serverless-instance"
engine = aws_rds_cluster.example.engine
engine_version = aws_rds_cluster.example.engine_version
instance_class = "db.serverless"
db_subnet_group_name = aws_db_subnet_group.example.name
db_parameter_group_name =
The depends_on reference illustrates the ordering requirement to ensure the scaling configuration exists before the serverless instance is created.
Adding Manual Reader Instances
The core strategy is to introduce new Serverless v2 capacity as a reader before promoting it to the writer. This is achieved by adding a manual reader instance to the existing provisioned cluster using Terraform. The reader is created with instance_class = "db.serverless" while the writer remains provisioned.
The impact for operations is that read traffic can be shifted to the Serverless v2 reader for validation, allowing the team to observe scaling behavior and cost metrics before committing write traffic. The contextual layer connects this step to the later failover step, because the reader must be fully synchronized and available before the primary endpoint switch.
When a traffic spike hits, it scales up as needed within the configured range. The scaling is automatic and occurs within seconds, which changes capacity planning from provisioning headroom to defining min and max ACU bounds.
Converting Existing Readers
If you already have provisioned reader instances, you can convert one of them directly to Serverless v2 using the db.serverless instance class via Terraform. This is often faster than provisioning a brand new instance. The recommendation is attributed to LinkedIn in the migration article.
Conversion reduces the time window where both provisioned and serverless instances exist simultaneously. The real world consequence is lower cost during migration because fewer provisioned hours accrue, and the Terraform plan shows a single in-place instance_class change rather than a create and destroy cycle.
The Terraform module terraform-aws-modules/rds-aurora/aws supports this pattern and provides fine grained control of individual cluster instances. Module configuration examples show homogenous clusters and instances with autoscaling enabled.
hcl
module "cluster" {
source = "terraform-aws-modules/rds-aurora/aws"
name = "test-aurora-db-postgres96"
engine = "aurora-postgresql"
engine_version = "17.5"
cluster_instance_class = "db.r8g.large"
instances = {
one = {}
two = {
instance_class = "db.r8g.2xlarge"
}
}
vpc_id = "vpc-12345678"
db_subnet_group_name = "db-subnet-group"
security_group_ingress_rules = {
ex1_ingress = {
cidr_ipv4 = "10.20.0.0/20"
}
ex1_ingress = {
referenced_security_group_id = "sg-12345678"
}
}
storage_encrypted = true
apply_immediately = true
monitoring_interval = 10
enabled_cloudwatch_logs_exports = ["postgresql"]
tags = {
Environment = "dev"
Terraform = "true"
}
}
The module supports autoscaling of read-replicas, global cluster, enhanced monitoring, serverless cluster v1 and v2, import from S3, custom endpoints, RDS multi-AZ support, Aurora Limitless, and Aurora DSQL cluster.
Zero Downtime Failover
Once the Serverless v2 reader instance is fully synchronized and available, it is time to switch the primary endpoint. The migration guide describes treating Serverless v2 as a standard Aurora Replica and utilizing the built-in failover mechanism. The failover is executed as a controlled, reproducible, and auditable infrastructure change through Terraform.
The impact layer is that application connection strings are updated to point to the new writer endpoint. Because Aurora handles replica promotion, write traffic moves with minimal disruption. The contextual layer ties this step back to the prerequisites of having application connection strings that can be updated and a backup of the current database.
The production tested migration strategy ensures zero downtime for applications. Step 1 is assess current RDS setup, step 2 plan Aurora Serverless v2 capacity, step 3 create Aurora read replica, step 4 implement the migration, step 5 post-migration optimization.
Capacity planning relies on metrics. Gathering metrics to properly size the Aurora Serverless v2 cluster involves commands such as:
bash
aws cloudwatch get-metric-statistics \
--namespace AWS/RDS \
--metric-name CPUUtilization \
--dimensions
The metric ServerlessDatabaseCapacity is referenced for understanding scaling patterns and optimizing costs.
Finalizing the Migration
The critical part is done once the cluster is running on Serverless v2. The final steps involve managing the legacy provisioned instances.
A. Convert or Remove Legacy Instances
The remaining provisioned reader or writer instances can be converted to serverless or removed. Conversion can be done via instance_class change to db.serverless. Removal reduces cost and eliminates operational overhead.
B. Post Migration Checks
Post migration checks include verifying replication lag is zero, confirming scaling configuration is respected, validating CloudWatch logs exports, and ensuring deletion protection and backup retention settings are correct.
The conclusion in the migration article emphasizes that by treating Serverless v2 as a standard Aurora Replica and utilizing built-in failover, a powerful low risk migration from a provisioned cluster can be executed. Leveraging Terraform for instance management ensures the complex operation is controlled, reproducible, and auditable.
Mixed Cluster Pattern and Cost Tradeoffs
The mixed cluster pattern with a provisioned writer and serverless readers is a particularly effective setup for production workloads that need both write consistency and read scalability. The pattern gives the best of both worlds.
A comparison of deployment models can be summarized as:
- Aurora Serverless v2 in Terraform is a provisioned cluster with serverlessv2scalingconfiguration and instances using instance_class = "db.serverless"
- You define min and max ACU capacity, and Aurora handles the scaling
- When traffic spike hits, it scales up as needed within the configured range
- Provisioned instances are recommended when workload is steady and predictable
- If consistently use around 16 ACU worth of capacity, provisioned db.r6g.xlarge may be cheaper depending on Region, engine, utilization pattern, and current AWS pricing
The impact for finance teams is that cost modeling shifts from fixed instance hours to variable ACU consumption. The contextual layer connects this to the monitoring of ServerlessDatabaseCapacity metric to understand scaling patterns and optimize costs.
Historical context is relevant. Aurora Serverless v2 reached GA on 2022/4/22. The Japanese Terraform implementation notes that on 2022/4/23 Aurora Serverless v2 was not yet supported in Terraform, and support arrived on 2022/4/28. This timeline illustrates the rapid adoption of Serverless v2 in infrastructure as code tooling.
Terraform Module Capabilities
The terraform-aws-modules/rds-aurora/aws module provides a single source for creating AWS RDS Aurora resources. Capabilities include autoscaling of read-replicas, global cluster, enhanced monitoring, serverless cluster v1 and v2, import from S3, fine grained control of individual cluster instances, custom endpoints, RDS multi-AZ support, Aurora Limitless, and Aurora DSQL cluster.
Configuration methods for creating instances within the cluster include creating a homogenous cluster of any number of instances and creating a homogenous cluster with autoscaling enabled. The module allows per instance overrides, as shown with instance_class differences between instances.
The module example with engine = "aurora-postgresql" engineversion = "17.5" clusterinstanceclass = "db.r8g.large" demonstrates production ready defaults such as storageencrypted = true, applyimmediately = true, monitoringinterval = 10, and enabledcloudwatchlogs_exports.
Monitoring and Optimization
Monitor the ServerlessDatabaseCapacity metric to understand scaling patterns and optimize costs. The metric reflects ACU utilization over time and informs whether mincapacity and maxcapacity are appropriately set.
The auto-scaling behavior scales compute capacity from 0.5 to 128 ACUs in seconds. The impact for developers is that latency spikes due to cold start are minimized, and capacity planning becomes declarative.
Cost efficiency is achieved by paying only for the capacity you use. High availability is built in with fault tolerance across multiple AZs. Performance is up to 5x faster than standard MySQL.
Post migration optimization includes reviewing the scaling configuration, adjusting mincapacity to avoid unnecessary idle cost, and adjusting maxcapacity to meet peak load requirements. The mixed cluster approach allows read heavy workloads to scale independently from write capacity.
Conclusion
Terraform orchestration of Aurora Serverless v2 is defined by the provisioned cluster with serverlessv2scalingconfiguration and db.serverless instances. The infrastructure as code pattern enables repeatable migrations from provisioned Aurora clusters using read replica introduction, synchronization, and failover. The zero downtime strategy preserves application availability while unlocking instant scaling and pay per use pricing.
The migration path leverages Terraform state management to add manual reader instances or convert existing readers to db.serverless, then promotes the Serverless v2 reader to writer through built in failover. Final steps involve converting or removing legacy provisioned instances and validating post migration health.
The mixed cluster pattern remains a pragmatic production choice, combining provisioned writer stability with serverless reader elasticity. Monitoring ServerlessDatabaseCapacity and aligning min and max ACU settings to actual traffic patterns drives cost optimization. Module based Terraform configurations provide fine grained control over instances, monitoring, security, and scaling, making Aurora Serverless v2 deployments auditable and reproducible across environments.
Enjoy the benefits of instant scaling and pay per use pricing with your new Amazon Aurora Serverless v2 deployment.