34
Ping Me! (Intro: IaC and Prep Work)
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, Site-to-Site VPN and Transit Gateway - for connecting VPCs together.
The building part will be done using AWS Cloud Development Kit. 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.
Before we jump headfirst into hacking out our infra, I'd like to take a minute to talk about Infrastructure as Code (IaC), 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? Hell yeah!!!
There are many tools to pick and choose from when it comes to implementing Infrastructure as Code; Puppet, Chef and Ansible just to name a few. Hashicorp's Terraform is one that shines exceptionally bright on the IaC firmament. Despite just reaching the v1, it is a mature and battle-tested tool that has been used by both big and small in recent years.
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.
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 (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).
One apparent limitation of the CDK is that, at least for the nonce, 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 and cdktf). With Terraform you can use choose from a plethora of providers. Hell, I was able to set up my home network running on Unifi Dream Machine using Terraform. How cool is that?!
PS. Pulumi, 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 and CDK's general-purpose languages support.
If you want to follow me along, you'll need to have:
a) access, with adequate permissions, to an AWS account
b) AWS CLI v2 that's properly configured
c) Node v10.3 or higher (I'll be using node v14.14.0 with npm v6.14.9)
- I recommend installing it with NVM, e.g.:
nvm install v14.14.0
nvm use v14.14.0
d) CDK
npm install -g aws-cdk
e) TypeScript
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!!!)
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:
➜ ~$ 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:
➜ 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 [email protected]: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated [email protected]: 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 [email protected]: this library is no longer supported
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] No repository field.
npm WARN [email protected] No license field.
✅ All done!
You should end up with the following structure:
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:
➜ ping-me-cdk-example$ rm lib/ping-me-cdk-example-stack.ts test/ping-me-cdk-example.test.ts
:> bin/ping-me-cdk-example.ts
Okay, seems the groundwork's done and thus we're ready to peer some VPCs. Follow me!
34