Manage AWS RDS instances
AWS's Relational Database Service (RDS) provides hosted relational databases, which are easier to operate and maintain than self-managed implementations. Terraform can provision, scale, and modify RDS, enabling you to manage the RDS instance and cluster life cycle programmatically, safely, and declaratively.
In this tutorial, you will use Terraform to provision an RDS instance, subnet group, and parameter group, modify the RDS instance configuration, and provision a replica instance.
Prerequisites
This tutorial assumes that you are familiar with the standard Terraform workflow. If you are new to Terraform, complete the Get Started tutorials first.
For this tutorial, you will need:
- Terraform 0.14+ installed locally
- an AWS account with credentials configured for Terraform
- psql 14.2+
Note
Some of the infrastructure in this tutorial may not qualify for the AWS free tier. Destroy the infrastructure at the end of the guide to avoid unnecessary charges. We are not responsible for any charges that you incur.
Clone the sample repository
Clone the sample repository for this tutorial, which contains Terraform configuration for an RDS instance, parameter group, security group, and subnet group.
Change into the repository directory.
Review resource configuration
Open the main.tf
file in your editor to review the sample configuration.
Networking components
The first resources defined are the VPC and subnets, using the terraform-aws-vpc
module.
Warning
For simplicity, this RDS tutorial instance is publicly accessible. Avoid configuring database instances in public subnets in production, since it increases the risk of security attacks.
Subnet group
The next resource is an aws_db_subnet_group
, which designates a collection of
subnets that your RDS instance can be provisioned in. This subnet group uses
the subnets created by the VPC module.
This subnet group resource is an optional parameter in your aws_db_instance
block below. Without it, Terraform creates your RDS instances in the default
VPC.
Database instance
Review the aws_db_instance
configuration.
Note the following arguments.
username
andpassword
: The credentials for the root user.publicly_accessible
: Set totrue
for this tutorial's configuration. Use the default offalse
for production systems.skip_final_snapshot
: Set totrue
to disable taking a final backup when you destroy the database later in this tutorial.
You can review all of the supported arguments on the aws_db_instance
resource documentation
page.
Parameter group
Now review the definition for the aws_db_parameter_group
.
This configuration enables connection logging for all instances using this
parameter group. Note that the family
parameter must correspond with the
engine version of the RDS instance.
The parameter group resource contains all of the database-level settings for your RDS instance, which will be specific to the database engine and version you use.
Custom parameter groups are optional, and AWS will create the instance using a default parameter group if you do not supply one. However, you cannot modify the settings of a default parameter group, and changing the associated parameter group for an AWS instance always requires a reboot, so it is best to use a custom one to support modifications over the RDS life cycle.
Input variables
Note that the aws_db_instance
root user password relies on an input variable.
Open the variables.tf
file to review its configuration.
Take note of the sensitive
meta-argument for the db_password
variable.
This argument tells Terraform to hide the password from the output during
Terraform operations. However, Terraform will store the password in plaintext
in the state file.
Tip
To learn more about sensitive variables, check out the Protect Sensitive Input Variables tutorial.
Output variables
Now review the contents of the outputs.tf
file.
These outputs return details for the RDS instance that you will use to construct the database connection string later in this tutorial.
Provision resources
Now that you have reviewed the configuration, provision the RDS instance and associated resources.
First, set the db_password
variable as an environment variable.
Initialize the Terraform configuration.
Next, apply the configuration. Respond yes
to the prompt to confirm.
Terraform will now provision your resources. It may take 5-7 minutes for AWS to provision the RDS instance.
Verify your configuration by using the endpoint, the password, and username
outputs to connect to the database using psql. Enter the password hashicorp
when prompted.
You are now connected to the database instance, verifying that the resource is provisioned as expected.
Create a new database called "hashicorp" within this instance.
Now verify that the hashicorp
database is included in the list of databases
in the instance by using the /list
command. Along with the database you
created, the list includes the default databases created in Postgres RDS
instances.
You will use this database to verify replication later in this tutorial.
Leave the terminal by typing exit
.
Modify instance configuration
In addition to initially provisioning resources, you will likely need to modify the RDS configuration over the instance life cycle.
In main.tf
, change the allocated storage from 5 to 10GB.
Apply your changes. Respond to yes
to the prompt to confirm.
Even after the apply completes successfully, the change will still be pending.
Verify by running terraform plan
.
Though some RDS configuration changes are safe to apply immediately, others (such
as engine_version
) require an instance reboot or may cause performance
degradation (such as allocated_storage
). By default, AWS will defer applying
any changes that can cause degradation or outage until your next scheduled
maintenance window. For a detailed breakdown of which attributes require a
reboot, consult the AWS RDS
documentation.
To make the changes take effect immediately, add the apply_immediately
argument to aws_db_instance
and set it to true
.
Apply your changes again. The proposed modifications will include the
still-pending storage resize and the apply_immediately
argument. Respond yes
to
the prompt to apply your changes.
This apply step will take longer than the previous one since Terraform will wait for the instance reboot to complete.
Once this update is complete, run terraform plan
.
There are no pending changes remaining, confirming that Terraform resized the RDS instance. You can also verify this by navigating to your instance in the RDS console for your region and reviewing the database instances.
Warning
Use the apply_immediately
argument with caution since it can allow unexpected instance reboots and downtime.
Provision a Read Replica
A read replica is one way to reduce load on the primary database. AWS will asynchronously copy all data from the primary database to the replica, to which you can then target all read queries.
Add the following configuration block to the main.tf
file to declare a
replica RDS instance.
This provisions a read replica instance based on the
aws_db_instance.education
RDS instance. Since there is a
replicate_source_db
set, you don't need to set the required arguments for
engine
, allocated_storage
, username
, and password
— Terraform will
determine them from the corresponding values on the source RDS instance.
You will also need to enable backup retention on the primary instance to use it
as a source database. Add the backup_retention_period
argument to the primary
instance configration.
For the primary instance, you constructed the database connection string by
passing the individual outputs to the psql
parameters. You can also construct
and output the entire connection string using Terraform's string interpolation
functionality.
Add the output variable for the connection string for the new replica instance
to the outputs.tf
file.
Apply your changes to provision this additional instance. Respond yes
to the
prompt to confirm.
As with the original instance, it may take 5-7 minutes to provision the replica, and a few additional minutes to make updates to the primary instance.
Once it is complete, use the new endpoint to connect to the replica database instance to verify your configuration.
Enter the password hashicorp
when prompted.
Now, confirm that the replica instance has the database you created in the
primary RDS instance. Use the /list
command to see all of the databases.
Notice that the hashicorp
database you created in the source RDS instance is
in the database list for the replica instance, confirming that this instance is
properly replicated from the primary.
Leave the terminal by typing exit
.
Clean up infrastructure
In this tutorial you provisioned and modified an RDS instance and read replica using
Terraform. Clean up the infrastructure you have created. Respond yes
to the
prompt to confirm destroying the resources.
Next steps
Terraform allows you to easily provision and manage AWS RDS instances using infrastructure as code. Since data storage resources are critical components of infrastructure, a declarative way to manage the resources over their life cycle will add an extra level of safety and consistency.
To learn more about managing RDS and other databases with HashiCorp tools:
Review the provider documentation for the
aws_db_instance
resource.Check out the RDS module to learn more about configuration options of RDS and related resources.
Follow the tutorial for generating dynamic database credentials using HashiCorp Vault.