Tips and tricks for getting started in CDK (a.k.a. IaC is great! Daheck is typescript?)

I’ve been doing IaC in AWS for years now, primarily through Cloudformation and scripting languages like powershell and python. IaC is great, but these tools have some short comings like yaml being very verbose, and the powershell AWS SDKs not handling idem potency for you.

Because of those short comings, I was very excited when AWS released AWS CDK a little over a year ago now. It cuts down on a lot of copying and pasting yaml files like you do in cloudformation, and gives you easier access to higher level language constructs like loops and if statements. It also comes with options for strong typing, which lets you get compile time errors instead of deploy time errors (anyone watched a complex cloudformation stack deploy for 30 minutes, only to have a syntax error on the last resource and watch it all role back?)

From a very high level typescript is a superset of javascript, and adds some nice features like strong typing. CDK is a framework and CLI for managing AWS resources.

All of that sounds great, but it can be intimidating to start using a new framework and a new language at the same time. I was new to typescript when I started using CDK, so I figured I’d share some of the tips and tricks I learned along the way. I know CDK supports other languages, but we found that most of the examples are in typescript, so we wanted to stay as mainstream as possible.

Do some reading before you start 

AWS is strongly motivated to make it easy for you to get started in CDK. From their perspective the easier it is for you to create resources, the easier it is for you to spend money with them. So before you start hacking away take a few minutes to read some helpful resources like

A few minutes of background research can help you frame up how your project should look, and save you a lot of time once you’re started.

Start with and modify an example project

If you’re new to typescript and CDK start by getting a small example project up and running. There are a ton of good examples in this github repoaws-samples/aws-cdk-examples
You can’t perform that action at this time. You signed in with another tab or window. You signed out in another tab or…github.com

If you pick one of the serverless examples you can usually stay in the free tier to avoid paying for your learning.

If you’re really trying to avoid spending money use

cdk synth

while you’re experimenting to make sure you can produce a valid cloudformation template without actually creating any resources. This is a good way to test changes and get fast feedback

Get familiar with a few key npm features

I’m not (and don’t really want to be) a nodejs developer, but if you’re working in typescript it will help to know some basic NPM commands like

  • Use npm install -g aws-cdk to install and update CLI tools like cdk globally. This is very different from…
  • Using npm install @aws-cdk/aws-ec2 to install packages locally in your project and your package.json file
  • Use a ^ before your version number to let npm upgrade packages when you run npm install in your project, take the ^ to pin a version. e.g. "@aws-cdk/aws-ec2": "^1.20.0" vs "@aws-cdk/aws-ec2": "1.20.0" 
  • Use npm run build to get errors that might not show up in the output of cdk deploy , but use tsc --build --clean afterwards to remove compiled .js fles — otherwise cdk deploy may not pick up your changes
  • If you need to downgrade your CDK package version for any reason you can pin the version and then run an npm install to get to an older version

Take advantage of itellisense in VS Code (or your editor of choice)

One of the main advantages of CDK is it’s ability to predict what your typing based on strong types. If you declare types for your objects like

const gateway_nlb_tg:elbv2.NetworkTargetGroup = new elbv2.NetworkTargetGroup....

your editor will be able to offer you methods and their parameters as you’re working

Get ready to be active in the CDK open source community

You’re using a pretty new open source project, and your best bet for help when you run into issues (in my experience) is to open an issue in the github project.

Keep in mind you’re not opening a support ticket with a vendor, so you need to bring all of the information you can to help some else help you solve your problem (e.g. the versions of CDK and packages you’re using, what you expected to happen, the errors you got, etc).

As long as you open an issue with a reasonable amount of information the community is very willing to help.

Conclusion

Those are the tips I wish I’d known when I started using CDK. Best of luck!

VS Code Remote Development With Docker Containers on Windows

This is a topic I’ve been curious about for a long time. My team supports windows and linux environments which presents some unique challenges

  1. We have to move in and out of shell environments
  2. We have to understand tools on both systems (grep vs find, etc)
  3. We have to understand nuances of running languages on multiple OSs (pathing is always a joy)

The company mostly issues Windows laptops (and some Macs), so we’ve used a number of different approaches to get run time in both environments including

  1. Local VMs running on our laptops
  2. VMs running in a VMWare cluster
  3. Straight EC2 instances
  4. Cloud9
  5. Docker containers
  6. WSL

They all have pros and cons, but I’ve been curious about Remote Development with VS Code for a while so I gave it a try to see if it could make sense to add to the list.

I’m working on a Windows 10 laptop with Docker Desktop installed. I found this article and started running through it.

First I installed the VS code extension for remote development with containers: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers

No problems on install. It creates a new side bar icon for remote options and some helpful info about the containers you have available. It also shows you the container’s volume mount, which is helpful context.

I cloned the node example repo, and the popup in the article came up no problem, and within seconds I was debugging a node process. Not bad.

Now with PowerShell

As usual, I gotta tie it back to PowerShell. My team does a lot of development in PowerShell, and we’re starting to do some PowerShell Core development targeted at Linux. This feels like it could be a good fit.

I created an empty directory with a .devcontainer directory

The I mimicked the devcontainer.json file from the node sample repo

{
    "name": "PS Sample",
    "dockerFile": "Dockerfile",

    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash" // Hoping to switch to pwsh later
    }
}

And then created a one line docker file

FROM mcr.microsoft.com/powershell

When I clicked on the remotes icon a popup offered to reopen the folder inside my dev container. I let it build and it dropped me right into a bash window

So I added a hello world powershell script through VS Code

write-host "hello world!";

Like I expected the file showed up inside of the container and I could run it with pwsh HelloWorld.ps1

Debugging PowerShell

Next I wanted to debug my powershell script. At first I was disappointed because it looked like the extension wouldn’t pick that up by default

But I found this article on debugging inside of a dev container and it had a helpful link to this extension.

I struggled with it for a few minutes before realizing the VS Code was seeing the extension already installed on my local machine, but not in my dev container. I added that to the extension list in my devcontainer.json file like so

{
    "name": "PS Sample",
    "dockerFile": "Dockerfile",

    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash" // Hoping to switch tp pwsh later
    },
    "extensions": [
        "ms-vscode.powershell"
    ]
}

Rebuilt the container, and just like that debugging showed up!

Lastly, adding this to an existing project was just a matter of copying over the .devcontainers folder (I won’t show any screen shots, because it’s an active project).

I will note the powershell modules are a sub section of a larger project that includes work in other languages (typescript, python, etc). I had to put the .devcontainer directory in the root of the powershell section of the project.

Conclusion

There is a little magic happening here, like installing support for VS Code extensions inside of the container. But for the most part it’s pretty standard Docker features like volume mapping, interactive terminals, etc. Just grouped together for convenience.

Remote development will go into our list of tools for spending time in other languages!