Multi-region Deployments with CDK
Code Included!
- Installed the AWS CLI
- Installed the CDK CLI
- Configured IAM credentials
- Bootstrapped at least two regions in an AWS account using the cdk bootstrap command
- We develop a clear hierarchy
- The main benefit of this is dependency management since we create a clear route by which we can pass information both up and back down the tree
- We create a point of centralization that we can use to build dependencies that are used by many dependents
- For example, if we have an SQS queue that is used globally within the application, we can build it in the root stack and pass it through to the props of the application stacks
- We have a “non-regional” stack to house global resources
- Building on the last point, we have a stack that handles deploying for things that aren’t regional in AWS (IAM, S3, etc.).
- The stack itself is tied to a region, but there’s no reason that the resources the stack deploys also have to be tied to that region.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { AppStack } from './app-stack/app-stack';
export class MultiRegionExampleStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const regions = ['us-east-1', 'eu-west-1'];
// store the regional stacks in an object for debugging
const regionalStacks = regions.reduce((accu, region) => {
const regionalStack = new AppStack(this, region, {
env: { region },
});
return { ...accu, [region]: regionalStack };
}, {});
}
}
- If you’re familiar with the NestedStack construct, you are probably thinking “What a perfect use case!”. Sadly at the time of writing this, it seems that NestedStacks have to be deployed in the same region that the source stack is deployed in. I don’t believe this is a CDK limitation, but instead a CloudFormation one. There is an open issue with some discussion around implementing this in CDK, however it does seem to be rather complicated. But hey if this is a blocker for you, get active and let them know!
- Another Cloudformation feature that is commonly used to solve this problem is Stack Sets. At the time of writing this, there is no support out of the box in CDK. But there is a CDK Labs construct in the experimental phase you can try out. But per their readme, I would avoid getting overly tied to its implementation until it is generally released.
- In theory, you shouldn’t need to reference values from an application stack deployed in Region A in an application stack deployed in Region B. As they are siblings, so dependencies should be managed via prop drilling. However reality is often finicky, so if you do end up in this situation, I would recommend storing the dependency value in ParameterStore and dynamically referencing it in the dependent stack. If you’d like to learn more, I wrote a deep-dive here that you may find useful.
- Instantiate your region-specific stack however many times you need in the
/bin/app.ts
file. You can find a full example here in the CDK docs. As well as this branch in the repository. - Instantiate your region-specific stack once in the
/bin/app.ts
file, and use the cdk deploy command to deploy it to the regions you desire. This branch has one approach you might take.
- Higher level constructs
- If like many others you are on a Serverless journey, you may be looking to migrate to Fargate. One of my personal favorites in the CDK library is the ApplicationLoadBalancedFargateService. It’s a mouthful because it does a lot for very little. In ~30 lines (or less) of code, it will deploy an ECS cluster, service, and task definition. As well as provide one-line APIs for wiring in the cluster, load balancer, and any VPC configuration you may need to do. All of this would be hundreds of lines of Cloudformation templating.
- Component libraries
- If the standard library can’t meet your needs, constructs.dev is an open-source marketplace that houses thousands of constructs. Ranging from monitoring tools, linters, and everything else you can imagine codifying in the cloud.
- Not only are there public libraries, but you can also create centralization within your organization through private ones. Making it possible to standardize higher-level patterns in the cloud.