rds (terraform)
Introduction
Serverless v2 (intro)
A database has a cluster and one o more instances:
DB cluster name: "${local.env}-${local.ci}-cluster"
DB instance name: "${local.env}-${local.ci}-instance-1"
Reference
Terraform migration from Serverless v1 to v2
https://www.reddit.com/r/Terraform/comments/zrvs1x/terraform_with_aurora_serverless_v2/
Easier to understand indications for upgrading Serverless v1 to v2
Sample: Upgrade Amazon Aurora Serverless v1 to Serverless v2
With Terraform "This is not possible. AWS clear states, you should do snapshot first. Restore on provisioned instance, upgrade to 14.x and then you can add a server less V2 instance reader . you can fail over it if you like to have it like writer. Then you can import in Terraform. But you need to have two resources, cluster and at least 1 instance (in your case V2)."
With the AWS console (Serverless v1 to v2)
10) In RDS > Databases
[Modify] DB cluster identifier, add suffix "-v1", eg:
"env-ci-cluster-v1"
[Continue]
"Apply immediatly"
[Modify cluster]
Wait until 'Status' changes to 'Availale'
20) Amazon RDS, select DB
[Actions >Take snapshot]
Choose Snapshot type : "DB cluster"
DB cluster: eg: env-ci-cluster
Snapshot name: v1-TICKET-N
[Take snapshot]
Wait until it finishes. Refresh the snapshots view from time to time.
30) Choose the snapshot & "Actions>Restore snapshot"
Capacity type: Provisioned
Avaiable versions: default major version 13, eg: 13.12
DB instance identifier: "env-ci-instance-1"
DB instance class: Serverless v2
Virtual Private cloud (VPC): <the same one where the original database was>
DB subnet group: env-ci-rds-subnet-group
VPC Security Group: env-ci-rds-sg (leave only this one, remove 'default' if was automatically added)
[Restore DB cluster] (might take ~15 minutes)
40) [Refresh] until the DB cluster changes to 'Available'
Note: Database doesn't need to be ready, only the cluster!
50) Select the cluster & [Modify]
DB engine version: Choose the default for major version 13, eg: 13.12
DB cluster identifier: env-ci-cluster
[Continue]
"Apply immediatly"
[Modify cluster] (might take ~20 minutes)
[60] Once the cluster and database have status 'Available', select the DATABASE
and choose [Modify]
DB instance class: Serverless v2
[Continue] button
Apply immediately
[Modify DB instance] button
Wait for status change to 'Available'
With terraform (Serverless v1 to v2)
Now that the database is already Serverless v2, lets remove the v1 cluster resource from terraform and import the v2 cluster and instance.
a) Remove the Serverless v1 RDS cluster
#resource "aws_rds_cluster" "default"
b) Add the Serverless v2 RDS Cluster
Note: Use the same cluster id, so that Terraform is able to atomatically refresh the new cluster
# RDS DB Cluster (Serverless v2) #### ####
# - Query Editor (Data API) w/ PostgeSQL Serverless v2 > https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Concepts.Aurora_Fea_Regions_DB-eng.Feature.Data_API.html#Concepts.Aurora_Fea_Regions_DB-eng.Feature.Data_API.apg
resource "aws_rds_cluster" "default" {
lifecycle {
ignore_changes = [
availability_zones,
engine_version #Comment line for upgrading DB version
]
}
allow_major_version_upgrade = true #(Optional) allow major engine version upgrades when changing engine versions
apply_immediately = true #(Optional) whether any cluster modifications are applied immediately, or during the next maintenance window
availability_zones = var.rds_availability_zones
cluster_identifier = var.cluster_identifier
backup_retention_period = var.backup_retention_period
copy_tags_to_snapshot = true
database_name = var.database_name
db_subnet_group_name = aws_db_subnet_group.rds_subnet_group.name #NOTE: This must match the db_subnet_group_name specified on every aws_rds_cluster_instance in the cluster
delete_automated_backups = false #(Optional) Specifies whether to remove automated backups immediately after the DB cluster is deleted
deletion_protection = true #(Optional) The database can't be deleted when this value is set
enable_http_endpoint = var.enable_http_endpoint
enable_local_write_forwarding = false
enabled_cloudwatch_logs_exports = ["postgresql"]
engine_mode = var.engine_mode #"provisioned" for Serverless v2
engine_version = var.engine_version
engine = var.engine
master_username = var.master_username
master_password = var.cluster_master_password
serverlessv2_scaling_configuration {
max_capacity = var.rds_cluster_max_capacity #Detaults to 16. 1 to 128 in increments of 0.5
min_capacity = var.rds_cluster_min_capacity #0.5 to 128 in increments of 0.5
}
skip_final_snapshot = var.skip_final_snapshot
vpc_security_group_ids = [var.sg_database_id]
}
# CloudWatch log group for RDS cluster (enabled_cloudwatch_logs_exports = ["postgresql"])
resource "aws_cloudwatch_log_group" "cluster_log" {
name = "/aws/rds/cluster/${aws_rds_cluster.regional.cluster_identifier}/postgresql"
retention_in_days = var.log_retention_in_days
}
c) Add at least one Serverless v2 RDS Cluster instance
# RDS DB Cluster Instance (Serverless v2) #### ####
resource "aws_rds_cluster_instance" "instance_1" {
apply_immediately = true
auto_minor_version_upgrade = true
#availability_zone #(Optional, Computed, Forces new resource) EC2 Availability Zone that the DB instance is created in.
#ca_cert_identifier
cluster_identifier = aws_rds_cluster.default.id
copy_tags_to_snapshot = true
#custom_iam_instance_profile
#db_parameter_group_name
#db_subnet_group_name
engine_version = aws_rds_cluster.default.engine_version
engine = aws_rds_cluster.default.engine
#identifier_prefix
identifier = "${local.env}-${local.ci}-instance-1" #(Optional, Forces new resource) Identifier for the RDS instance, if omitted, Terraform will assign a random, unique identifier.
instance_class = "db.serverless"
#monitoring_interval
#monitoring_role_arn
#performance_insights_enabled
#performance_insights_kms_key_id
#performance_insights_retention_period
#preferred_backup_window
#preferred_maintenance_window
promotion_tier = 1
publicly_accessible = false
#tags #(Optional) Map of tags to assign to the instance. If configured with a provider default_tags configuration block present, tags with matching keys will overwrite those defined at the provider-level.
}
d) Import the Serverless v2 instance(s) into the terraform aws_rds_cluster_instance resource(s)
In main.tf, add the block:
import {
id = "${local.env}-${local.ci}-instance-1"
to = module.rds.aws_rds_cluster_instance.instance_1
}