Skip to main content

CDK Organizer

Project description

CDK Organizer Python Library

This library contains the core features to handle CDK projects including:

  • Logging
  • Configuration Resolver
  • Stack Groups Loader
  • Naming Utils

Full documentation: https://cdk-organizer.github.io/

Installation

pip install cdk-organizer[terraform,aws]

Extras

  • terraform: Include cdktf as a dependency.
  • aws: Include aws-cdk-lib as a dependency.

CDK Start Script

The content of the app.py file should be as follows:

AWS CDK

import aws_cdk as cdk
from cdk_organizer.miscellaneous.logging import setup_logging
from cdk_organizer.stack_group import StackGroupLoader

app = cdk.App()
logger = setup_logging(__name__, app.node.try_get_context("loglevel") or "INFO")
loader = StackGroupLoader(app)

loader.synth()
app.synth()

CDK for Terraform

from cdk_organizer.miscellaneous.logging import setup_logging
from cdk_organizer.stack_group import StackGroupLoader
from cdktf import App

app = App()
logger = setup_logging(__name__, app.node.try_get_context("loglevel") or "INFO")
loader = StackGroupLoader(app)

loader.synth()
app.synth()

Context Variables

The following context variables are required to the CDK Organizer to work properly:

  • env
  • region

The variables can be set in the cdk.json file:

{
  ...
  "context": {
    ...
    "env": "dev",
    "region": "us-east-1"
    ...
  }
  ...
}

Or passed as arguments to the CDK CLI:

cdk synth --context env=dev --context region=us-east-1

In the cdktf CLI the context variables cannot be passed as arguments, so they need to be set in the cdk.json file. https://github.com/hashicorp/terraform-cdk/issues/2019 The env variable can also be set as an environment variable CDK_ENV.

Project Structure

To apply the pattern purposed in this library for CDK projects, the following structure is required:

.
+-- cdk.json
+-- app.py

Stack Structure

the stack class needs to inherit from class cdk_organizer.aws.stack.Stack for AWS CDK and cdk_organizer.terraform.stack.Stack for Terraform CDK.

AWS CDK

from constructs import Construct
from cdk_organizer.aws.stack import Stack
from cdk_organizer.aws.stack_group import StackGroup


class MyStack(Stack):
    def __init__(
        self,
        scope: Construct,
        id: str,
        stack_group: StackGroup,
        **kwargs
    ) -> None:
        super().__init__(scope, id, stack_group, **kwargs)

Terraform CDK

from constructs import Construct
from cdk_organizer.terraform.stack import Stack
from cdk_organizer.terraform.stack_group import StackGroup


class MyStack(Stack):
    def __init__(
        self,
        scope: Construct,
        id: str,
        stack_group: StackGroup,
        **kwargs
    ) -> None:
        super().__init__(scope, id, stack_group, **kwargs)

Using S3 Backend

To use S3 terraform backend, the following resources are required:

  • S3 Bucket
  • DynamoDB Table

Add the following object to the environment configuration file:

s3_backend:
  bucket: "<bucket-name>"
  region: "<aws-region>"
  dynamodb_table: "<dynamodb-table-name>"

Stack Group Structure

Create a stacks folder in the root of the project and structure it as follows:

.
+-- cdk.json
+-- app.py
+-- stacks/
| +-- <groupName>/
|   +-- stacks.py

The stack groups files follow this pattern:

AWS CDK

import aws_cdk as cdk
from dataclasses import dataclass
from cdk_organizer.aws.stack_group import StackGroup

@dataclass
class MyStackGroupConfig:
    domain: str
    ipv6: bool = True


class MyStackGroup(StackGroup[MyStackGroupConfig]):
    def _load_stacks(self) -> None:
        MyStack(
            self.app,
            self.get_stack_name('my-stack'),
            stack_group=self,
            parameters=MyStackParameters(
                domain=self.data.domain,
                ipv6=self.data.ipv6
            )
        )

Terraform

import cdktf
from dataclasses import dataclass
from cdk_organizer.terraform.stack_group import StackGroup

@dataclass
class MyStackGroupConfig:
    domain: str
    ipv6: bool = True


class MyStackGroup(StackGroup[MyStackGroupConfig]):
    def _load_stacks(self) -> None:
        MyStack(
            self.app,
            self.get_stack_name('my-stack'),
            stack_group=self,
            parameters=MyStackParameters(
                domain=self.data.domain,
                ipv6=self.data.ipv6
            )
        )

Using Stack Attributes from Other Stack Groups

In some cases, you may want to use the attributes of another stack group. For example, refer the DNS Hosted Zone created by a shared stack group.

To resolve the group use the self.resolve_group function in the stack group class, like the example below:

import aws_cdk as cdk
from dataclasses import dataclass
from cdk_organizer.aws.stack_group import StackGroup
from stacks.dns import DNSStackGroup

@dataclass
class MyStackGroupConfig:
    domain: str
    ipv6: bool = True


class MyStackGroup(StackGroup[MyStackGroupConfig]):
    def _load_stacks(self) -> None:
        MyStack(
            self.app,
            self.get_stack_name('my-stack'),
            stack_group=self,
            parameters=MyStackParameters(
                domain=self.data.domain,
                zone=self.resolve_group(DNSStackGroup).zone
                ipv6=self.data.ipv6
            )
        )

The function get_stack_name generates the stack name based on following pattern.

Pattern: {module_path}-{name}-{region}-{env}

Consider the following example:

module_path: myproject.myapp.www name: spa region: us-east-1 env: dev

Stack name will be:

  • myproject-myapp-www-spa-us-east-1-dev.

Config Structure

Create a config folder in the root of the project and structure it as follows:

.
+-- cdk.json
+-- app.py
+-- config/
| +-- <env>/
|   +-- config.yaml
|   +-- <region>/
|     +-- config.yaml
|     +-- <groupName>/
|         +-- config.yaml

The first two levels are reserved to the environment name and the region name, the next levels needs to match the stack group structure.

Example:

.
+-- cdk.json
+-- app.py
+-- config/
| +-- config.yaml
| +-- dev/
|   +-- config.yaml
|   +-- us-east-1/
|     +-- config.yaml
|     +-- app1/
|       +-- config.yaml
+-- stacks/
| +-- app1/
|   +-- stacks.py
+-- templates/
|   +-- stacks/

Examples

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cdk_organizer-1.11.0.tar.gz (13.2 kB view hashes)

Uploaded source

Built Distribution

cdk_organizer-1.11.0-py3-none-any.whl (17.2 kB view hashes)

Uploaded py3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page