Encrypting WordPress RDS and Enforcing MySQL TLS

The Amazon RDS for MySQL database used by my production WordPress blog was not encrypted at rest. Because encryption cannot be enabled in place on an existing RDS instance, the migration required copying a snapshot, restoring a new instance, and switching the application endpoint. I also enforced TLS for traffic between WordPress and RDS, in addition to enabling encryption at rest.

Checks before the migration

  • Normal responses from WordPress core and the main public URLs
  • Record counts in the posts and options tables
  • The existing database endpoint and parameter group
  • Whether the application could connect with TLS options
  • A configuration backup for reverting to the previous endpoint if something went wrong

The RDS encryption migration sequence

  1. Create a manual snapshot of the existing unencrypted RDS instance
  2. Create an encrypted copy of the snapshot using the AWS-managed RDS KMS key
  3. Restore a new RDS instance from the encrypted snapshot
  4. Check the attached security groups and parameter group
  5. Connect to the new endpoint over TLS and compare record counts
  6. Switch the WordPress database endpoint
  7. Test reading posts and writing, reading, and deleting options
  8. Delete the previous RDS instance and temporary snapshots after sufficient validation

Making MySQL TLS mandatory

I applied require_secure_transport=ON to the new parameter group. With this setting, the server rejects unencrypted MySQL connections. For WordPress mysqli connections, I used the SSL client flag and checked that a TLS cipher was set for the actual session.

define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL );

I initially tried to enforce certificate validation at the same time, but the configuration was incompatible with the current PHP/MySQL client setup and WordPress could not connect. I immediately reverted that flag to restore service, then combined a supported SSL connection method with enforcement on the RDS server. This reinforced the need to apply security settings incrementally while checking compatibility with the actual runtime.

A negotiated TLS cipher confirms that the connection is encrypted. It does not, by itself, demonstrate server certificate or hostname verification; those require separate client configuration.

Checks after the migration

  • Confirm that the new RDS instance reports StorageEncrypted=true as its storage encryption setting
  • Confirm that the parameter group is in-sync with the instance
  • Confirm that plaintext MySQL connections are rejected
  • Check the WordPress bootstrap and administrator login page
  • Confirm HTTP 200 responses from the REST API, robots.txt, categories, and individual posts
  • Create, retrieve, and delete a test option

Delete resources only after validation

I did not immediately delete the previous database just because the new instance was reported as healthy. I first tested actual reads and writes through WordPress and checked the site in a browser, then deleted the previous RDS instance. I also removed the temporary migration snapshots at the end, in line with my cost policy.

Backup policy is a separate decision

For this personal blog, I deliberately do not use automated RDS backups or PITR because of cost. That is an availability and recovery policy separate from encryption. For a typical business system, it is safer to define automated backups and recovery point objectives first. Consider the importance of the data alongside cost instead of copying this blog’s decision directly.

Conclusion

After this migration, the data stored in RDS is encrypted with KMS, and TLS is enforced between WordPress and MySQL. The most important part was defining the checks before and after the switch, along with clear rollback criteria, rather than the commands used to create the new resources.

Related articles

Leave a Comment

Your email address will not be published. Required fields are marked *