Creating a High-Performance AWS RDS Database Instance Using Terraform: A Step-By-Step Guide

Creating a High-Performance AWS RDS Database Instance Using Terraform: A Step-By-Step Guide

As an Infrastructure-as-Code (IaC) tool, Terraform allows you to programmatically build, modify, and provision cloud infrastructure. AWS Relational Database Service (RDS) is a service that offers scalable and reliable database solutions for various platforms, such as MySQL, PostgreSQL, Oracle, and SQL Server. By using Terraform to create an AWS RDS database, you can automate the creation and management of database components right from your coding environment.

In this tutorial, you'll learn how to create an AWS RDS database using Terraform.

Prerequisites

Before you start this tutorial, make sure you have the following tools installed and ready to use:

  • Terraform CLI - To start using Terraform, you need to install it in your local environment. You can easily do that by downloading and installing the binary package or compiling it from source. Visit the link below to follow the step-by-step installation process for your operating system: learn.hashicorp.com/tutorials/terraform/ins..
  • AWS CLI - After installing Terraform, it is equally important to install AWS CLI because that will enable us to communicate directly with your AWS environment from the terminal. After installing AWS CLI, run aws configure on your terminal. This will prompt you to provide your AWS access and secret keys for authentication. After entering it, you have successfully connected your command line to the AWS environment.

Setting Up The project

For this tutorial, we'll set up a demo project folder on our local computer and then open the folder in a code editor.

You can manually create your project folder in your preferred code editor or from your command line. Run the following command if you prefer the latter:

mkdir terraform-rds-demo-db

Navigate to the folder by running: cd terraform-rds-demo-db

These commands will create a new folder named terraform-rds-demo-db and change our working directory to that folder.

Creating The Terraform Files

Before defining our RDS instance resources, let's explore some of the terraform files we'll use.

In this tutorial, we'll use of 3 main files: rds.tf , vars.tf, and providers.tf.

  • rds.tf - this folder will hold all the definitions of our RDS infrastructure. It will contain the template configuration for AWS to follow when creating our DB instance.
  • vars.tf - This is a variable file. It will hold the access key, region, and secret key of our AWS environment, as well as other custom variables we might want to declare.
  • provider.tf - this file will tell Terraform that we're using AWS as our infrastructure provider while supplying the necessary AWS credentials like access key, secret key, and region.

You can create the three files by running the following command in your project directory: touch rds.tf vars.tf provider.tf

You can also create the files manually inside the project folder

Creating The RDS Instance

After creating the required files, the next step is to populate each file with the appropriate configurations.

1. Writing the DB instance configurations

In the rds.tf file, put the following configuration;

resource "aws_db_instance" "default" {
# Allocate the storage for database instance.
  allocated_storage    = 10
# Define the database engine and engine_version
  engine               = var.engine
  engine_version       = var.engine_version
# Declare the instance class
  instance_class       = var.instance_class
  name                 = var.name
# User to connect the database instance 
  username             = var.username
# Password to connect the database instance 
  password             = var.password
  parameter_group_name = var.parameter_group_name
}

In the code above, the resource keyword allows us to tell Terraform which AWS resource we are about to create. Specifying the aws_db_instance resource creates all the necessary queries to include when making an API call to AWS to provision our RDS instance.

  • The allocate_storage parameter allows us to specify the storage size of our database in GiB.
  • The engine and engine_version parameters specify which type of database we choose to create. We will create a MySQL database in this tutorial. Other database engines you can choose from includes PostgreSQL, MariaDB, Oracle and SQL Server.
  • The instance_class specifies the AWS hardware instance on which we want to run our database. We will use the AWS t3.micro instance class, accompanied by any name we want; "my-database" in this case.
  • The parameter_group_name parameter defines the configuration of our database engine.

You should notice that all the values of the parameters so far in the rds.tf file are placeholder variables. We'll declare and define the values of the variables in the next steps.

2. Declaring and assigning values to the variables

In the vars.tf file, paste the following code:

variable "engine" {}
variable "engine_version" {}     
variable "instance_class" {}
variable "name"  {}       
variable "username" {}  
variable "password" {} 
variable "parameter_group_name" {}

This code will declare the variables we use in the rds.tf file.

To not hard-code our variables' values and avoid security compromise because of secret credentials like passwords and username, create a new file in the project directory and name it terraform.tfvars and paste the code below.

engine               = "mysql"
  engine_version       = "5.7"
  instance_class       = "db.t3.micro"
  name                 = "mydb"
  username             = "user1"
  password             = "my_password"
  parameter_group_name = "default"

When Terraform creates our AWS RDS instance, the instance will be:

  • MySQL version 5.7 database
  • Running on a t3.micro engine
  • Admin username of user1
  • Password of my_password

Note: The parameter_group_name in our terraform.tfvars file has a value of default. So, we need to define the configuration for "default". Include the code below in the rds.tf file:

resource "aws_db_parameter_group" "default" {
  name        = "${var.rds_instance_identifier}-param-group"
  description = "Terraform example parameter group for mysql5.6"
  family      = "mysql5.6"
  parameter {
    name  = "character_set_server"
    value = "utf8"
  }
  parameter {
    name  = "character_set_client"
    value = "utf8"
  }
}

3. Specifying the provider As we explained earlier, the providers.tf file will contain the details of our cloud provider, including the availability region we will create our database instance. Open the providers.tf file and pass the following code:

required_providers {
    aws = {
    source  = "hashicorp/aws"
    version = "~> 3.27"
    region = "us-east-2"
    }

4. Creating the RDS instance on AWS After populating our configuration files with the appropriate declarations, parameters, and values, the next is to tell AWS to create our database with the specified attributes.

First we will run:

terraform init

This will initialize Terraform in our project directory and load all the necessary plugins for it to communicate with AWS from our command line. If things go well, you'll see a message like the image below on the CLI.

Response from initializing Terraform

Then, we go through an optional confirmation step by running: terraform plan This command will show an overview of the actions Terraform will perform. It is advisable to go through this step because it can be beneficial in figuring out errors in your configuration files before moving on to creating the resources on AWS.

Response from running terraform plan

And finally, to build our RDS instance on AWS, we run: terraform apply This command will display all the resources to be created and ask if you're ready to continue. If you're ready, type: yes.

This will apply all the configurations we specified in our terraform files and create our RDS instance. Terraform might take a few minutes to do all the hard work of connecting the references from all of our files to create our database. After creating our RDS instance on AWS, terraform shows a success message on your command line.

Note: You can confirm that your RDS instance is up and running by viewing it from your AWS management console.

Creating RDS Instance in a VPC

Suppose you want to launch your RDS instances in a particular VPC and subnet group(s). In that case, you can create the VPC and subnet groups and then specify the configuration of your RDS in the subnet group.

To do this, we'll create a new file in our project directory and name it db-subnet.tf.

First, we create the VPC using the following code:

resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}

Then we'll create 2 subnet groups, one from different availability zones.

This will create a subnet, private-subnet1, in the availability zone.

resource "aws_subnet" "private-subnet1" {
vpc_id = "${aws_vpc.main.id}"
cidr_block = "10.0.2.0/24"
availability_zone = "AZ-a of the Region"
}

This will create our second subnet, private-subnet2, in the availability zone you specify.

resource "aws_subnet" "private-subnet2" {
vpc_id = "${aws_vpc.main.id}"
cidr_block = "10.0.3.0/24"
availability_zone = "AZ-b of the region"
}

And finally, we create a subnet group containing the 2 subnets we created above:

resource "aws_db_subnet_group" "db-subnet" {
name = "DB subnet group"
subnet_ids = ["${aws_subnet.private-subnet1.id}", "${aws_subnet.private-subnet2.id}"]}

Also, we need to create a security group in the VPC to which our database subnets will belong:

resource "aws_security_group" "rds" {
  name        = "terraform_rds_security_group"
  description = "Terraform example RDS MySQL server"
  vpc_id      = "${aws_vpc.vpc.id}"
  # Keep the instance private by only allowing traffic from the web server.
  ingress {
    from_port       = 3306
    to_port         = 3306
    protocol        = "tcp"
    security_groups = ["${aws_security_group.default.id}"]
  }
  # Allow all outbound traffic.
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags {
    Name = "terraform-example-rds-security-group"
  }
}

After doing all that, we'll include a db_subnet_group_name parameter in the aws_db_instance declaration of our rds.tf file and reference the database subnet.

db_subnet_group_name = "${aws_db_subnet_group.db-subnet.name}"

Now we can run terraform plan to overview what changes we're about to make, and then terraform apply to execute it in our AWS environment. This will effectively create a VPC and 2 subnets, and create our RDS instance in both subnets of our VPC.

Creating an RDS Instance from an Existing Database

To create our RDS instance from an existing database snapshot, assume that we have a blank rds.tf file.

Paste the following code in the blank rds.tf file:

data "aws_db_snapshot" "db_snapshot" {
most_recent = true
db_instance_identifier = "testinstance"
}

The most_recent parameter checks for the latest database snapshot in the testintance instance, which we specified as the value of db_instance_identifier.

Now we will create a new resource in the rds.tf file and pass the snapshot identifier for Terraform to create our RDS from the snapshot

resource "aws_db_instance" "db_test" {
instance_class = "db.t2.small"
identifier = "newtestdb"
username = "test"
password = "Test@54132"
publicly_accessible = false
db_subnet_group_name = "${aws_db_subnet_group.db-subnet.name}"
snapshot_identifier = "${data.aws_db_snapshot.db_snapshot.id}"
vpc_security_group_ids = ["sg-00h62b79"]
skip_final_snapshot = true
}

After having all the necessary files and parameters in place, we can now run terraform plan and terraform apply, accordingly, and Terraform will create our new RDS database instance from the snapshot.

Conclusion

Provisioning cloud infrastructure using an IaC tool like Terraform makes it easier to manage small and large infrastructures and avoid the bunch of clicking around involved in using a graphical interface. With this tutorial, you now know how to create an AWS RDS database for your projects using Terraform.