How can I encrypt an unencrypted Amazon RDS instance for MySQL or MariaDB with minimal downtime?

Last updated: 2019-06-05

I attempted to create an encrypted read replica of my unencrypted Amazon Relational Database Service (Amazon RDS) instance for MySQL or MariaDB. However, I received the following error:

"You cannot create an encrypted Read Replica from an unencrypted DB instance. (Service: AmazonRDS; Status Code: 400; Error Code: InvalidParameterCombination; Request ID:"

How can I encrypt an unencrypted DB instance with minimal downtime?

Short Description

You can't modify an existing unencrypted Amazon RDS instance to make the instance encrypted. Also, you can't create an encrypted read replica from an unencrypted instance to be promoted as your new encrypted Amazon RDS master instance. However, you can use the Amazon RDS snapshot feature to encrypt an unencrypted snapshot that's taken from an unencrypted Amazon RDS read replica of the instance that you want to encrypt. You can restore the encrypted snapshot to deploy a new encrypted Amazon RDS instance. Then, you can manually replicate the new, restored encrypted Amazon RDS instance of the original unencrypted instance. After the encrypted replica instance is caught up with the master unencrypted instance, you can switch to the new encrypted instance. This approach requires minimal downtime, because you must stop traffic to the unencrypted instance, verify that the encrypted DB instance is in sync, and then redirect the traffic to the encrypted DB instance.

For more information about these limitations, see Limitations of Amazon RDS Encrypted DB Instance

Resolution

1.    Create a temporary read replica for the source unencrypted Amazon RDS instance.

Note: Be sure that the value for Seconds_Behind_Master is 0.

2.    Stop the replication and log in to master user on the read replica. Then, execute the following:

MySQL > call mysql.rds_stop_replication;
+---------------------------+
| Message                   |
+---------------------------+
| Slave is down or disabled |
+---------------------------+

3.    After the read replica instance catches up with the primary instance, review the output by running SHOW SLAVE STATUS\G. Note the parameters for manual replication later.

4.    Set the binlog retention hours parameter to preserve binlogs for the time required to complete the operation.

5.    Run the SHOW SLAVE STATUS command, and save the replication status data in a local file. (This is required when setting up the replication on the DB instance in the destination account.) Then, log in to the master user on the read replica and execute the following command:

MySQL> show slave status;

Note: The following information is required to set up the read replica manually: Relay_Master_Log_File and Exec_Master_Log_Pos.

6.    Create a snapshot of the read replica that you stopped.

7.    Copy the snapshot that was created in the same AWS Region, and change Enable Encryption to Yes. For more information, see How do I encrypt Amazon RDS snapshots?

8.    Restore the DB instance from this encrypted snapshot.

9.    Modify the inbound rule of the source unencrypted DB instance's security group to allow traffic from that the security group attached to the new encrypted DB instance. If the same security group is used on both instances, you can use the same security group reference as a source. From the Amazon RDS console, choose the instance, and then choose the Connectivity pane. Choose the Security group, and then select the Inbound view. Choose Edit, enter your security group ID, and then choose Save.

10.    Create a user for manual replication on DB Instance in the source unencrypted DB instance by running a command similar to the following:

create user replicationuser identified by '<password>';
grant replication slave on *.* to replicationuser;

11.    Set up manual replication using mysql.rds_set_external_master between the destination encrypted DB instance and the source unencrypted DB instances. Log in as the master user on the new restored encrypted instance, and then execute a command similar to the following:

call mysql.rds_set_external_master(
'<Master_Host>',
<Master_Port>,
'<replication user>',
'<replication user password>',
'<Master_Log_File>',
<Read_Master_Log_Pos>,
<SSL setting>
);

Important: The following step results in downtime to your database. Downtime is required for the encrypted RDS instance to synchronize with the unencrypted RDS source, during which time no changes are allowed to the unencrypted source. Downtime is required to re-point applications and clients to the encrypted RDS instance.

12.    Stop all application servers or clients that connect to the unencrypted source RDS instance to verify that no new changes are made to the unencrypted RDS instance from this point on. Optionally, you can temporarily lock down the security group that is used by the unencrypted RDS instance. This prevents inbound traffic from any application or client, except for traffic from the encrypted RDS instance and the host from which the administrator is performing these actions.

13.    Run SHOW SLAVE STATUS\G and review the output to confirm that the encrypted RDS instance has caught up to the unencrypted RDS instance by confirming that Seconds_Behind_Master reports a value of 0.

14.    As the master user, connect to the encrypted RDS instance by using a MySQL client tool. Then, stop replication by running a command similar to the following:

MySQL > call mysql.rds_stop_replication;

Important: After you run this command, the encrypted DB instance no longer replicates data from the source unencrypted DB instance.

15.    Permanently disable replication between the unencrypted and encrypted RDS instances by calling the rds_reset_external_master procedure on the encrypted RDS instance:

MySQL > call mysql.rds_reset_external_master;

16.    Point all applications to the encrypted RDS instance by specifying the instance's DNS endpoint in all connection strings. You can also rename the encrypted instance to have the same name as the old instance and the same DNS endpoint as the unencrypted RDS instance.

17.    Confirm that the security group rules on the encrypted RDS instance allow inbound traffic from the appropriate applications and clients.

18.    Delete the temporary read replica that you created in step 1.

19.    After the applications and clients have been successfully pointed to the new encrypted RDS instance and the environment has been tested, you can delete the original unencrypted RDS instance, if you choose.

Tip: It's a best practice to test this operation on a restored instance before applying this operation in a production environment.


Did this article help you?

Anything we could improve?


Need more help?