Upgrade RDS major version
Terraform enables you to manage your Amazon Relational Database Service (RDS) instances over their lifecycle. Using Terraform's built-in lifecycle arguments, you can manage the dependency and upgrade ordering for tightly coupled resources like RDS instances and their parameter groups.
In this tutorial, you will perform a major version upgrade on your RDS instance using Terraform and review how Terraform can handle dependency ordering for your resource management.
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 v0.15+ installed locally
- an AWS account with credentials configured for Terraform
- the AWS CLI
- psql
Clone example repository
Clone the example repository for this tutorial, which contains configuration for an RDS instance and parameter group.
Change into the repository directory.
Review configuration
Open main.tf
in your code editor to review the resources you will provision.
This configuration defines:
- an AWS VPC to provision your RDS instance in
- an RDS subnet group, which designates a collection of subnets for RDS placement
- a security group that will allow access to your RDS instance on port
5432
- an RDS parameter group
- an
aws_db_instance
, initially configured with Postgres 15
The aws_db_parameter_group
resource's family
attribute corresponds to the major version of your aws_db_instance
. In this
case, the parameter group family is postgres15
, so the RDS engine version is
Postgres v15.
While you could use the default AWS parameter groups, it is best practice to maintain a custom one for your RDS instance. You cannot modify the parameters on the default parameter groups maintained by AWS. If you plan on changing an RDS setting in the future, you will need to create a new parameter group anyway.
The configuration also declares input variables for the AWS region and database
password in the variables.tf
file, and output values to use to connect to the
RDS instance in the outputs.tf
file.
Create an RDS instance
In your terminal, initialize the Terraform configuration to install the modules and providers used.
Your configuration requires the master database password as an input variable. To avoid committing sensitive values to version control, we recommend you set the variable either using a command line flag or an environment variable.
Create an environment variable for the password.
Next, apply your configuration to create your resources. Enter yes
when
prompted to confirm the operation. Note that it can take up to 10 minutes to
create an RDS instance.
Seed database with mock data
Next, connect to the database and seed it. The coffees.sql
file in the
repository contains commands that will populate your database with mock data
about HashiCorp-themed coffee beverages.
psql
can access your password using thr PGPASSWORD
environment variable.
Set your Postgres password as an environment variable.
Then, execute the script.
Connect to your database to inspect your records.
In the psql prompt, list all of the coffees in your database.
Type exit
to exit psql.
Update configuration
When managing an RDS instance and a parameter group, you need to bump the engine version and the parameter group family in lockstep for a major version upgrade. Changing the parameter group family is a destructive change, while you can change the database version in-place.
In this Terraform configuration, the aws_db_instance
resource references the
aws_db_parameter_group
, creating an implicit dependency
between the two. As a result, Terraform would first try to upgrade the
parameter group, but would error out because the destructive update would
attempt to remove a parameter group associated with a running RDS instance.
Terraform offers lifecycle meta-arguments to help you manage more complex
resource dependencies such as this one. In this case, you will use the
create_before_destroy
argument to ensure that Terraform provisions the new
parameter group and upgrades your RDS instance before destroying the original
parameter group.
In your main.tf
file, make the following changes:
In the aws_rds_parameter_group
resource definition, update the family
argument to postgres16
and add the lifecycle
argument, as shown below.
Update the version
argument for the aws_db_instance
resource to 16
.
Take an RDS snapshot
Before performing an upgrade, be sure to create a backup of your data. Backing up your data is a good practice when performing operations on your databases, so that you have a point of recovery in the event of data loss or error.
Use the AWS CLI to create an RDS snapshot of your instance.
Navigate to the AWS console to verify that your snapshot exists. Wait until the status is "Available" before moving on to the next section.
Upgrade RDS instance
In your terminal, apply your configuration changes to replace the parameter
group and upgrade the engine version of your RDS instance. Enter yes
when
prompted to approve the operation.
Note
This upgrade may take up to 20 minutes.
Verify upgrade
Verify that the RDS instance is using Postgres 16.
Destroy infrastructure
Use the AWS CLI to delete the RDS snapshot you created earlier.
Once you have completed the tutorial, destroy your infrastructure to avoid
incurring unnecessary costs. Type yes
when prompted to confirm the operation.
Next steps
In this tutorial, you learned how you can use Terraform's lifecycle arguments to manage a major version upgrade of your RDS instances. To learn more about the concepts used in this configuration, review the following tutorials:
- Learn about other lifecycle meta-arguments Terraform supports
- Learn more about navigating common errors and troubleshooting Terraform