Ping Me! (Intro: IaC and Prep Work)
Tags: aws, typescript, devops, tutorial
Published: 2021-07-23 09:24:45

## Introduction

Hello, everyone! Welcome to _Ping Me!_, a short series of articles in which we are going to build out and compare three different solutions - [VPC Peering](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html), [Site-to-Site VPN](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html) and [Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html) - for connecting VPCs together.

The building part will be done using [AWS Cloud Development Kit](https://docs.aws.amazon.com/cdk/latest/guide/home.html). Then, we will prove that each connection works by deploying two EC2 instances, one on each end of the connection, and making a successful ping between them.

## Infrastructure as Code (IaC)

Before we jump headfirst into hacking out our infra, I'd like to take a minute to talk about [Infrastructure as Code (IaC)](https://en.wikipedia.org/wiki/Infrastructure_as_code), and why it is important. IaC is a powerful concept! Thanks to it instead of clicking through graphical user interfaces you can code your infrastructure exactly the same way you would code any other application. And since it is code, then it means you can apply all the best coding practices to it, e.g. version control, static code analysis, peer review, etc. With IaC your infra can be immutable, replicable, less error-prone than manual changes (especially when a lot of repetitiveness is involved); it works great at scale, can be automated, you can write tests for it... I'd daresay there's no DevOps without IaC. [Everything as Code](https://www.hashicorp.com/resources/everything-as-code-the-future-of-ops-tools)? Hell yeah!!!

There are many tools to pick and choose from when it comes to implementing Infrastructure as Code; [Puppet](https://puppet.com/), [Chef](https://www.chef.io/products/chef-infra) and [Ansible](https://www.ansible.com/) just to name a few. [Hashicorp's Terraform](https://www.terraform.io/) is one that shines exceptionally bright on the IaC firmament. [Despite just reaching the v1](https://github.com/hashicorp/terraform/releases/tag/v1.0.0), it is a mature and battle-tested tool that [has been used by both big and small in recent years](https://www.hashicorp.com/resources?content_type=Case%20Study&product=Terraform).

Nonetheless, a new kid showed up on the block recently, the name's AWS CDK, and may soon disturb the peace. [AWS CDK is a software development framework for defining cloud infrastructure in code and provisioning it through AWS CloudFormation](https://docs.aws.amazon.com/cdk/latest/guide/home.html).

What that means is that instead of declaring your resources and their interconnections in YAML (like you would do in Ansible, for instance) or in JSON (like you could do in CloudFormation, which also supports YAML) or in a [Domain-Specific Language](https://en.wikipedia.org/wiki/Domain-specific_language) (as is the case with Terraform and its Hashicorp Configuration Language (HCL); JSON is also supported if you're a masochist) you can actually code in TypeScript or Javascript or Python or Java or C# ([or, in Developer Preview, Go](https://aws.amazon.com/blogs/developer/getting-started-with-the-aws-cloud-development-kit-and-go/)).

One apparent limitation of the CDK is that, [at least for the nonce](https://github.com/aws/aws-cdk-rfcs/issues/217), it can only be used with AWS (there are two notable projects in the work right now that will greatly expand CDK's reach: [cdk8s](https://github.com/awslabs/cdk8s) and [cdktf](https://github.com/hashicorp/terraform-cdk)). With Terraform you can use choose from [a plethora of providers](https://registry.terraform.io/browse/providers). Hell, I was able to set up [my home network running on Unifi Dream Machine using Terraform](https://github.com/rafalkrol-xyz/ubiquity-unifi-dream-machine-setup-example). How cool is that?!

PS. [Pulumi](https://www.pulumi.com/), ~~which I haven't fiddled with yet but definitely will~~, deserves an honorable mention in this little digression of mine, since it might be just the right mix of [Terraform's providers](https://www.pulumi.com/docs/intro/vs/terraform/#using-terraform-providers) and [CDK's general-purpose languages support](https://www.pulumi.com/docs/intro/vs/cloud_template_transpilers/#aws-cdk-and-troposphere).

## Prerequisites

If you want to follow me along, you'll need to have:

**a)** access, with [adequate permissions](https://stackoverflow.com/questions/57118082/what-iam-permissions-are-needed-to-use-cdk-deploy), to [an AWS account](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)

**b)** [AWS CLI v2](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) that's properly [configured](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html)

**c)** [Node v10.3 or higher](https://nodejs.org/en/) (I'll be using node v14.14.0 with npm v6.14.9)

+ I recommend installing it with [NVM](https://github.com/nvm-sh/nvm), e.g.:

```bash
nvm install v14.14.0
nvm use v14.14.0
```

**d)** CDK

```bash
npm install -g aws-cdk
```

**e)** TypeScript

```bash
npm install -g typescript
```

**f)** some dollars to spend // **even with the free tier on, be prepared to incur a few dollars of costs (be sure to destroy your stacks as soon as possible to avoid incurring much bigger costs!!!)**

## Preparations

Before we commence with provisioning any resources, we ought to do some prep work. Let's kick-off by creating a folder for our project and entering it:

```bash
➜  ~$ mkdir ping-me-cdk-example && cd $_
```

Now, we shall scaffold our project using CDK's neat `init` command specifying `app` as the template and `typescript` as the language:

```bash
➜  ping-me-cdk-example$ cdk init app --language=typescript
Applying project template app for typescript
# Welcome to your CDK TypeScript project!

This is a blank project for TypeScript development with CDK.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Useful commands

 * `npm run build`   compile typescript to js
 * `npm run watch`   watch for changes and compile
 * `npm run test`    perform the jest unit tests
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk synth`       emits the synthesized CloudFormation template

Executing npm install...
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated request-promise-native@1.0.9: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN ping-me-cdk-example@0.1.0 No repository field.
npm WARN ping-me-cdk-example@0.1.0 No license field.

✅ All done!
```

You should end up with the following structure:

```bash
ping-me-cdk-example # we're here
├── bin
│   └── ping-me-cdk-example.ts
├── lib
│   └── ping-me-cdk-example-stack.ts
├── node_modules
│   └── ... # Many, many subfolders here
├── test
│   └── ping-me-cdk-example.test.ts
├── .gitignore
├── .npmignore
├── cdk.json
├── jest.config.js
├── package-lock.json
├── package.json
├── README.md
└── tsconfig .json
```

As you can see, CDK has created a rather intimidating host of files and subdirectories for us. Well, not so intimidating if you've ever worked with Node and/or TypeScript before. Most of it is boilerplate and throughout these articles we shall only deal with the `ping-me-cdk-example/bin/ping-me-cdk-example.ts` file and the `ping-me-cdk-example/lib` directory.

Let's remove `ping-me-cdk-example/lib/ping-me-cdk-example-stack.ts` and `ping-me-cdk-example/test/ping-me-cdk-example.test.ts` as they'd just get in the way:

```bash
➜  ping-me-cdk-example$ rm lib/ping-me-cdk-example-stack.ts test/ping-me-cdk-example.test.ts
```

Also, [let's wipe clear the contents of the `ping-me-cdk-example/bin/ping-me-cdk-example.ts` file](https://superuser.com/questions/90008/how-to-clear-the-contents-of-a-file-from-the-command-line):

```bash
:> bin/ping-me-cdk-example.ts
```

Okay, seems the groundwork's done and thus we're ready to peer some VPCs. [Follow me](https://dev.to/rafalkrolxyz/ping-me-part-1-vpc-peering-using-cdk-2kpd)!