Aurora Engine Upgrade with Cloudformation
05 June, 2023
Recently I was tasked with updating an Aurora MySQL database engine from version 5.7 to 8.0 via Cloudformation. According to various internet sources, this usually includes disowning the resources from the Cloudformation stack and updating manually. Mangling the Cloudformation state is both inconvenient and stressful, so here is a guide on how to handle the upgrades in place without data loss.
NOTE!
Following these steps will cause downtime unless blue/green RDS deployments are configured
Example infrastructure
Consider this simplified example running an Aurora MySQL cluster with a single DB instance. The cluster is running latest MySQL 5.7 engine version, and both have a custom parameter group:
ClusterParamGroup:
Type: "AWS::RDS::DBClusterParameterGroup"
Properties:
Description: Aurora cluster parameters
Family: "aurora-mysql5.7"
Parameters:
...
InstanceParamGroup:
Type: "AWS::RDS::DBParameterGroup"
Properties:
Description: Aurora instance parameters
Family: "aurora-mysql5.7"
Parameters:
...
Cluster:
Type: "AWS::RDS::DBCluster"
Properties:
DBClusterIdentifier: !Ref Cluster
DBClusterParameterGroupName: !Ref ClusterParamGroup
Engine: aurora-mysql
EngineVersion: "5.7.mysql_aurora.2.03.2"
...
Instance:
Type: "AWS::RDS::DBInstance"
Properties:
DBClusterIdentifier: !Ref Cluster
DBParameterGroupName: !Ref InstanceParamGroup
DBSubnetGroupName: !Ref RDSSubnetGroup
Engine: aurora-mysql
...
Swap to default parameter groups
Start by updating the resources to use the default parameter groups appropriate for the current engine version.
Cluster:
Type: "AWS::RDS::DBCluster"
Properties:
DBClusterIdentifier: !Ref Cluster
DBClusterParameterGroupName: "default.aurora-mysql5.7" # default for 5.7
Engine: aurora-mysql
EngineVersion: "5.7.mysql_aurora.2.03.2"
Instance:
Type: "AWS::RDS::DBInstance"
Properties:
DBClusterIdentifier: !Ref Cluster
DBParameterGroupName: "default.aurora-mysql5.7" # default for 5.7
DBSubnetGroupName: !Ref RDSSubnetGroup
Engine: aurora-mysql
...
Update engine and parameter groups
set the engine version to upgrade target, change the parameter groups to use the upgrade target defaults.
Cluster:
Type: "AWS::RDS::DBCluster"
Properties:
DBClusterIdentifier: !Ref Cluster
DBClusterParameterGroupName: "default.aurora-mysql8.0" # default for 8.0
Engine: aurora-mysql
EngineVersion: "8.0.mysql_aurora.3.03.1" # new engine version
Instance:
Type: "AWS::RDS::DBInstance"
Properties:
DBClusterIdentifier: !Ref Cluster
DBParameterGroupName: "default.aurora-mysql8.0" # default for 8.0
DBSubnetGroupName: !Ref RDSSubnetGroup
Engine: aurora-mysql
...
At this point the Aurora cluster and instances will be upgraded. Unless you have blue/green deployments configured, this will cause downtime, the length of which depends largely on the size of the database.
Switch back to custom parameter groups
Once the engine upgrade is done, switch back to using custom the parameter groups.
Keep in mind that major engine upgrades usually include breaking changes, so modify the parameters accordingly.
ClusterParamGroup:
Type: "AWS::RDS::DBClusterParameterGroup"
Properties:
Description: Aurora cluster parameters
Family: "aurora-mysql8.0" # change family to match engine version
Parameters:
...
InstanceParamGroup:
Type: "AWS::RDS::DBParameterGroup"
Properties:
Description: Aurora instance parameters
Family: "aurora-mysql8.0" # change family to match engine version
Parameters:
...
Cluster:
Type: "AWS::RDS::DBCluster"
Properties:
DBClusterIdentifier: !Ref Cluster
DBClusterParameterGroupName: !Ref ClusterParamGroup # custom parameter group
Engine: aurora-mysql
EngineVersion: "8.0.mysql_aurora.3.03.1"
...
Instance:
Type: "AWS::RDS::DBInstance"
Properties:
DBClusterIdentifier: !Ref Cluster
DBParameterGroupName: !Ref InstanceParamGroup # custom parameter group
DBSubnetGroupName: !Ref RDSSubnetGroup
Engine: aurora-mysql
Conclusions
If everything went according to plan, you should now have an upgraded Aurora cluster running. If upgrade downtime is not acceptable, configuring blue/green deployments for Aurora is pretty simple.