This document assumes you have completed initial setup and other steps described in the Migration Guide.
For apps where avoiding downtime is critical, we recommend a dual-stack migration strategy. The idea is to duplicate the key parts of the stack using the pattern, test, and, once confident, switch DNS to point to the new stack.
Stage 1: dual-stack
graph TD
A(example.gutools.co.uk)
A --> B[Legacy API Gateway instance & Lambdas]
A .-> C[New API Gateway instance & Lambdas]
Stage 2: switch DNS
graph TD
A(example.gutools.co.uk)
A .-> B[Legacy API Gateway instance & Lambdas]
A --> C[New API Gateway instance & Lambdas]
Stage 3: cleanup
graph TD
A(example.gutools.co.uk)
A --> C[New API Gateway instance & Lambdas]
This stage creates a new version of your app's infrastructure, according to CDK’s best practices. Note that some resources (e.g. Dynamo tables) will not be duplicated as part of the pattern.
At the end of this stage, you should have a functional copy of your application, which can be used for testing purposes. Riff-Raff will have been configured to deploy to both versions of your infrastructure, so you can operate in this state for as long as you need to.
-
Identify the correct GuCDK pattern
If your app serves all requests via a single Lambda function, you will need
GuApiLambda
.If your app routes different requests to different Lambda functions, you will need
GuApiGatewayWithLambdaByPath
. -
Create an instance of the pattern
Use your existing stack as a guide. For example, you will likely need to create some custom IAM permissions and add them to your Lambda.
There's an example of this here.
-
Update your
riff-raff.yaml
to deploy application code to your new Lambda function(s)As we will be using a dual-stack migration strategy, we want Riff-Raff to update the application code for old (CFN-defined) and new (GuCDK-defined) versions of the Lambda function(s) as part of every deployment.
There's an example of this here.
Note that you must use the
functionNames
parameter for this to work. The alternative strategy (which useslookupByTags
), will not work with the dual-stack approach.
This stage routes all traffic to your new (GuCDK-defined) infrastructure, by updating the mapping between your custom domain name and your API Gateway instance.
At the end of this stage, all traffic should be running via the new resources that we created in Stage 1. The equivalent old resources should still be part of your stack, but they should be redundant by the end of this stage.
These instructions assume that you are using a custom domain name with your API Gateway instance.
If this is the case, you should find a resource of type AWS::ApiGateway::DomainName
in your CloudFormation template.
If you do not have a custom domain name, please contact DevX to discuss alternative migration strategies.
-
Identify the
AWS::ApiGateway::DomainName
andAWS::ApiGateway::BasePathMapping
resources in your CloudFormation template. -
Create an instance of the
CfnDomainName
andCfnBasePathMapping
classes in your template.In order to avoid downtime, pass the logical id of your
AWS::ApiGateway::DomainName
into theCfnDomainName
class and the logical id of theAWS::ApiGateway::BasePathMapping
into yourCfnBasePathMapping
class.Ensure that the properties passed into these classes line up with those specified in your CloudFormation template.
There's an example of this change here.
For more information on safely incorporating these stateful resources, see these docs.
-
At this stage, create a CloudFormation change set and confirm that no resources are identified for replacement.
-
Deploy this change to your
CODE
environment using Riff-Raff and confirm that resources are not replaced and that your API still works as expected. -
Raise a PR and merge it (once approved).
It's helpful to ship a PR at this point as it allows us to rollback easily if something goes wrong after migrating the DNS.
-
Modify your
CfnBasePathMapping
class to point at your new API Gateway Instance and your API Gateway Stage.There's an example of this here.
This stage removes all redundant resources from your original template.
At the end of this stage, the vast majority of your resources will be created via the CDK pattern. Some resources, such as Dynamo tables, may still be defined in your original CFN template.
-
View request count metrics for old vs new API Gateway instances in CloudWatch.
You should not proceed until you have confirmed that the old API Gateway instance is receiving 0 requests.
-
Identify redundant resources in your original CFN template.
For example, all API Gateway resources, Lambda functions, previous alarms, etc.
-
Remove the redundant resources from your original CFN template.
In simple cases it may be possible to remove the whole file. If so, you should also be able to remove the
CfnInclude
block. -
Remove the old function names from your
riff-raff.yaml
-
Deploy this change manually using Riff-Raff.
Note that you will need to deploy this change manually in order to bypass Riff-Raff's built-in safety mechanisms. In order to avoid the accidental deletion of resources, Riff-Raff will not delete certain AWS resources (e.g. API Gateway instances) by default. To instruct Riff-Raff to do this, select
Advanced settings
and chooseDangerous
from theUpdate strategy
dropdown. -
After the deployment has finished, confirm that your app still works as expected.