Ryan Scott Brown

I build cloud-based systems for startups and enterprises. My background in operations gives me a unique focus on writing observable, reliable software and automating maintenance work.

I love learning and teaching about Amazon Web Services, automation tools such as Ansible, and the serverless ecosystem. I most often write code in Python, TypeScript, and Rust.

B.S. Applied Networking and Systems Administration, minor in Software Engineering from Rochester Institute of Technology.

    How to run CDK CloudASM from a ZIP

    For all my funsies projects (except the Rust ones), I use pantsbuild to build and deploy my code. It’s a great tool, and but its separation between artifacts requires that CDK code be run during the build step.

    Artifacts that contain multiple files to be output in the pants package need to be archives. For my use case, I have a single Python file that builds every CDK stack and merges them into a single Cloud Assembly. For example, here is a simplified build file:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
    # take the CDK python script and package it into a PEX file
    python_source(
        name="stacks",
        source="bin/build-stacks.py",
        dependencies=["//project1:stacks", "//project2:stacks"],
    )
    pex_binary(
        name="cdkapp",
        dependencies=[":stacks"],
        venv_site_packages_copies=True,
        execution_mode="venv",
        entry_point="bin/build-stacks.py",
    )
    
    # run the earlier pex file to build the CloudASM
    shell_command(
        # build cloud assembly zip given the cdk.json and stack objects
        name="cdk",
        tools=["node", "python3.12"],
        command="./cdkapp.pex .",
        execution_dependencies=[":cdkapp"],
        output_files=[
            "*.assets.json",
            "asset.*",
            "*.template.json",
            "cdk.out",
            "manifest.json",
            "tree.json",
        ],
        output_directories=[
            "asset.*",
        ],
    )
    # zip the CloudASM into a package artifact
    archive(name="cloudasm", format="zip", files=[":cdk"])
    

    This will create a dist/cloudasm.zip file that contains all the files needed to deploy the CDK stacks. The CDK CLI can deploy CloudASM without running any of your application code. By default, the tree of templates and artifacts (Lambda zips, etc) are stored in the cdk.out directory. Usually CloudASM is used like this:

    cdk deploy --app cdk.out Project1
    

    This reads the already-rendered template without re-running your CDK code. However, because we have the CloudASM in a zip file that doesn’t quite work. We need to extract the CloudASM from the zip file and then run the cdk command. Here’s a simple bash script that does that:

    #!/usr/bin/env bash
    set -euo pipefail
    
    if [[ ! -f "${1}" ]] ; then
      echo "Could not find cloudassembly zip '${1}'"
      exit 1
    fi
    
    DIR=$(mktemp -d -t cloudasm)
    
    unzip -q -d "${DIR}" "${1}" 1>&2
    
    echo "${DIR}"
    

    With this script in build-support, we can run the CDK command like this:

    cdk deploy -a "$(build-support/inline-cloudassembly.sh ./dist/whatever.zip)/sub/path"
    

    The same script is also useful if you’ve got approval steps in your deployment pipeline, or want to keep artifacts to enable rollbacks. If you have a pipeline that doesn’t save artifacts it’s worth considering adding a step to have a history of past deploys for troubleshooting.

    Design by Sam Lucidi (samlucidi.com)