Creating multiple stacks in AWS CDK

In AWS CDK (Cloud Development Kit), a stack is a deployable unit that represents a collection of AWS resources. Sometimes, there's a need to manage multiple stacks either for logical separation, different environments, or to manage AWS resource limits.

In this post, we will create multiple stacks in the app and deploy them.

Why create multiple stacks?

  1. Logical Separation: You might want to separate resources logically, like networking resources in one stack and database resources in another.
  2. Resource Limits: AWS CloudFormation has a limit on the number of resources per stack; dividing resources among multiple stacks can be a solution.
  3. Environment Management: Manage different environments like development, staging, and production with distinct stacks
  4. Maintainability: It's easier to maintain multiple stacks than a single stack with a large number of resources.

Creating multiple stacks

Start a new project by running the following command:

cdk init app --language python

1. Create the first stack

Rename the cdk_app_stack.py file to first_stack.py and modify the code as follows:

from aws_cdk import (
    Stack,
    aws_s3 as s3,
    RemovalPolicy,
)

from constructs import Construct

class FirstStack(Stack):

    BUCKET_ID = "MyFirstBucket"

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        s3.Bucket(self, id="MyFirstBucket", removal_policy=RemovalPolicy.DESTROY)

This is the same code that we used in the previous post to create a bucket with a destroy policy.

2. Create the second stack

Create a new file called second_stack.py under the cdk_app folder and modify the code as follows:

from aws_cdk import (
    Stack,
    aws_lambda as _lambda
)

from constructs import Construct

class SecondStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        _lambda.Function(self, 
            id="MyFirstLambda",
            runtime=_lambda.Runtime.PYTHON_3_7,
            code=_lambda.Code.from_inline("def main(event, context):\n\tprint('Hello World')"),
            handler="index.main",
        )

This simple stack creates a Lambda function that prints "Hello World" to the console when invoked.

3. Modify the app.py file

The original app.py only has the default single stack that was created when we initialized the project. This stack no longer exists, so we need to modify the app.py file to include the two new stacks.

We first import the two new stacks:

from cdk_app.first_stack import FirstStack
from cdk_app.second_stack import SecondStack

Then we add the two stacks to the app:

app = cdk.App()

FirstStack(app, "FirstStack")
SecondStack(app, "SecondStack")

The final app.py file looks like this:

import os
import aws_cdk as cdk

from cdk_app.first_stack import FirstStack
from cdk_app.second_stack import SecondStack


app = cdk.App()

FirstStack(app, "FirstStack")
SecondStack(app, "SecondStack")

app.synth()

4. Synthesize multiple stacks

Synth of the stacks is done in the same way as before:

cdk synth

This will synthesise both stacks and create the CloudFormation templates for in the cdk.out folder.

5. Deploy multiple stacks

To get the list of stacks that are available in the app, run the following command:

cdk ls

cdk ls output

While deploying, we can either deploy only one stack, or all stacks together. To deploy a single stack, we have to specify the stack name:

cdk deploy FirstStack

And to deploy all stacks, we can simply run the following command:

cdk deploy --all

6. Destroy multiple stacks

To destroy a single stack, we have to specify the stack name:

cdk destroy FirstStack

And to destroy all stacks, we can simply run the following command:

cdk destroy --all
Need Help? Open a discussion thread on GitHub.

Related Posts