Skip to content

Instantly share code, notes, and snippets.

@jonico
Last active September 14, 2023 15:13
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jonico/68fba04eff64885ef18faf68aff869a6 to your computer and use it in GitHub Desktop.
Save jonico/68fba04eff64885ef18faf68aff869a6 to your computer and use it in GitHub Desktop.
How to create an RDS database that is suitable for PlanetScale's import feature

MySQL on RDS configured for import to PlanetScale example

This folder contains an example Terraform configuration that deploys a MySQL database - using RDS in an Amazon Web Services (AWS) account - that is properly configured for PlanetScale's DB import feature.

It will make sure that the RDS database has the binlog exposed, gtid-mode set to ON and is using ROW-based replication. All these are pre-requisites for imports to work without zero downtime.

If you are going to write a lot of data in your database in a very short amount of time, don't forget the only manual step after the Terraform setup.

Pre-requisites

Quick start

Please note that this example will deploy real resources into your AWS account.

Configure your AWS access keys as environment variables:

export AWS_ACCESS_KEY_ID=(your access key id)
export AWS_SECRET_ACCESS_KEY=(your secret access key)

Optionally, select a password for your database and export it as a Terraform variable:

export TF_VAR_db_password="your_secret_password"

If you do not set this variable, Terraform will query you for the password in the next step

Optionally, edit the variables.tf to change the name of the database and main.tf to change the region or add replicas.

Create the RDS database:

terraform init
terraform apply

Now, you can connect with mysql:

mysql -u admin -p$TF_VAR_db_password -h `terraform output -raw address`

(or, if you have not set your password in a variable)

mysql -u admin -pyour_secret_password -h `terraform output -raw address`

Before you connect PlanetScale for DB import

Before you import

In order for the replication log not being to small, you would need to type the following in the mysql command prompt:

call mysql.rds_set_configuration('binlog retention hours', 24);

Now, you can follow the steps for PlanetScale import.

Destroying the RDS database once the import successfully finished

Clean up when you're done:

terraform destroy
terraform {
required_version = ">= 0.12"
}
provider "aws" {
region = "us-east-2"
}
resource "aws_db_parameter_group" "parameter-group-gtid-mode-ON" {
name = "parameter-group-gtid-on"
description = "Parameter Group to turn on GTID mode"
family = "mysql8.0"
parameter {
apply_method = "pending-reboot"
name = "gtid-mode"
value = "ON"
}
parameter {
apply_method = "pending-reboot"
name = "enforce_gtid_consistency"
value = "ON"
}
parameter {
apply_method = "pending-reboot"
name = "binlog_format"
value = "ROW"
}
parameter {
name = "max_connections"
value = "500"
}
}
resource "aws_db_instance" "example" {
identifier_prefix = "rds-import"
engine = "mysql"
allocated_storage = 10
instance_class = "db.t2.medium"
username = "admin"
name = var.db_name
skip_final_snapshot = true
password = var.db_password
publicly_accessible = true
parameter_group_name = "${aws_db_parameter_group.parameter-group-gtid-mode-ON.id}"
backup_retention_period = 1
vpc_security_group_ids = [aws_security_group.rds.id]
apply_immediately = true
}
#resource "aws_db_instance" "example-replica" {
# identifier_prefix = "terraform-up-and-running"
# replicate_source_db = aws_db_instance.example.id
# allocated_storage = 10
# instance_class = "db.t2.micro"
# skip_final_snapshot = true
#}
resource "aws_security_group" "rds" {
name = var.rds_security_group_name
# Allow inbound HTTP requests
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# Allow all outbound requests
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
data "aws_vpc" "default" {
default = true
}
data "aws_subnet_ids" "default" {
vpc_id = data.aws_vpc.default.id
}
output "address" {
value = aws_db_instance.example.address
description = "Connect to the database at this endpoint"
}
output "port" {
value = aws_db_instance.example.port
description = "The port the database is listening on"
}
# ---------------------------------------------------------------------------------------------------------------------
# REQUIRED PARAMETERS
# You must provide a value for each of these parameters.
# ---------------------------------------------------------------------------------------------------------------------
variable "db_password" {
description = "The password for the database"
type = string
}
# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# These parameters have reasonable defaults.
# ---------------------------------------------------------------------------------------------------------------------
variable "db_name" {
description = "The name to use for the database"
type = string
default = "rds_database"
}
variable "rds_security_group_name" {
description = "The name of the security group for the RDS"
type = string
default = "allow-access-from-everywhere"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment