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
andengine_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 AWSt3.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.
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.
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.