Terraform - 3 mins read

Terraform Mastery: Adding Databases to RDS Instances effortlessly

Learn to scale AWS RDS databases using Terraform

RF logo

Dhanesh kumar

DevOps Engineer & Consultant

Introduction:

In this blog post, I will demonstrate a smooth and reliable process for scaling existing MySQL and PostgreSQL databases in AWS RDS using Terraform. Efficiently scaling databases while ensuring data integrity is crucial for modern businesses, and leveraging Terraform’s infrastructure as code capabilities enables us to achieve this seamlessly within the AWS environment.

Let’s explore the step-by-step process of scaling databases with confidence and ease.

Overview:

This Terraform configuration extends an AWS RDS setup by adding additional databases for both MySQL and PostgreSQL engines. It ensures that the scaling process is smooth and does not disrupt ongoing database operations.

Steps: Preparation:

Ensure the Terraform version is 1.0 or higher. Verify necessary providers are defined in providers.tf file.

terraform {
 required_version = ">= 1.0"
 required_providers {
   aws = {
       source = "hashicorp/aws"
       version = "> 4.0"
   }

   random = {
       source  = "hashicorp/random"
       version = "~> 3.0"
   }

   mysql = {
       source = "TakatoHano/mysql"
   }

   postgresql = {
       source = "cyrilgdn/postgresql"
       version = "1.22.0"
   }
 }
}

For MySQL Database:

  • Define a random password resource for MySQL using random_password module in main.tf file.

  • I have used random_password to generate the MySQL Master password for login.

  • Configure additional MySQL database resources (mysql_database) as required, ensuring unique names as shown below.

resource "random_password" "MysqlMasterPassword" {
   length           = 16
   special          = true
   override_special = "$%!)1"
}

resource "aws_db_instance" "MySQLDatabaseInstance" {
   identifier                  = "rds-mysql-poc"
   engine                      = "mysql"
   engine_version              = "8.0"
   instance_class              = "db.t3.micro"
   allocated_storage           = 30
   storage_type                = "gp3"
   db_name                     = "rdspoc"
   username                    = "rdspocadmin"
   password                    = random_password.MysqlMasterPassword.result
   port                        = 3306
   parameter_group_name        = "default.mysql8.0"
   multi_az                    = false
   auto_minor_version_upgrade  = true
   backup_window               = "03:00-06:00"
   backup_retention_period     = 7
   maintenance_window          = "Sun:00:00-Sun:03:00"
   deletion_protection         = false
   final_snapshot_identifier   = "rds-poc-final-snapshot"
   apply_immediately           = true
   db_subnet_group_name        = "default-vpc-ID"
   vpc_security_group_ids      = ["sg-ID"]
   publicly_accessible         = true
}

provider "mysql" {
   endpoint = "${aws_db_instance.MySQLDatabaseInstance.endpoint}"
   username = "${aws_db_instance.MySQLDatabaseInstance.username}"
   password = "${aws_db_instance.MySQLDatabaseInstance.password}"
}

resource "mysql_database" "app1" {
 name = "db_01"
}

resource "mysql_database" "app2" {
 name = "db_02"
}

For PostgreSQL Database:

  • Define a random password resource for PostgreSQL using random_password module in main.tf file.
  • Configure additional PostgreSQL database resources (postgresql_database) as necessary, ensuring unique names as shown below.
resource "random_password" "PgMasterPassword" {
   length           = 16
   special          = true
   override_special = "$%!)1"
}

resource "aws_db_instance" "PostgresDatabaseInstance" {
   identifier                      = "rds-pg-poc"
   engine                          = "postgres"
   engine_version                  = "16.1"
   instance_class                  = "db.t3.micro"
   allocated_storage               = "30"
   storage_type                    = "gp3"
   apply_immediately               = "true"
   db_name                         = "rdspoc"
   username                        = "rdspocadmin"
   password                        = random_password.PgMasterPassword.result
   port                            = "5432"
   db_subnet_group_name            = "default-vpc-ID"
   vpc_security_group_ids          = ["sg-ID"]
   multi_az                        = "false"
   auto_minor_version_upgrade      = "true"
   backup_window                   = "03:00-06:00"
   backup_retention_period         = "7"
   maintenance_window              = "Sun:00:00-Sun:03:00"
   deletion_protection             = "false"
   performance_insights_enabled    = "false"
   final_snapshot_identifier       = "rds-poc-final-snapshot"
   parameter_group_name            = "rds-pg-poc-db-paramter-group"
   publicly_accessible             = true
}

provider "postgresql" {
   host        = "${aws_db_instance.PostgresDatabaseInstance.address}"
   username    = "${aws_db_instance.PostgresDatabaseInstance.username}"
   password    = "${aws_db_instance.PostgresDatabaseInstance.password}"
   port        = "${aws_db_instance.PostgresDatabaseInstance.port}"
}

resource "postgresql_database" "app1" {
 name = "db_01"
}

resource "postgresql_database" "app2" {
 name = "db_02"
}

After making the above changes in the terraform config files execute the below commands:

  • Run the terraform plan and apply command.
  • Terraform applies changes, adding new databases to the existing RDS instances.

Now, let’s check and ensure:

  • Databases are successfully added without interrupting existing operations.
  • Verify data integrity in both existing and newly added databases.

Conclusion:

By utilizing Terraform’s infrastructure as code capabilities and AWS RDS, we have efficiently added new databases to the existing RDS instance without causing disruptions to ongoing operations. This demonstrates the scalability and reliability of our infrastructure, allowing us to adapt to evolving business needs seamlessly.

Testing Considerations:

It’s important to note that the provided code is tested with a publicly accessible RDS instance. If you wish to test with a private RDS instance, it’s recommended to set up a Jump host within the same VPC.

In my case, I utilized Jenkins in conjunction with Terraform to provision AWS resources, ensuring smooth deployment regardless of the instance’s accessibility settings. This approach ensures flexibility and security, enabling hassle-free scaling of databases in various network configurations.

I trust that this guide will prove invaluable in your journey of managing AWS RDS instances. Stay tuned for further insights and best practices as I continue to explore the realm of AWS database management

Thank you for reading.

Written by Dhanesh kumar

Other blogs

You may also like


Your one-stop shop for expert RoR services

join 250+ companies achieving top-notch RoR development without increasing your workforce.