Book Image

AWS CDK in Practice

By : Mark Avdi, Leo Lam
3.5 (2)
Book Image

AWS CDK in Practice

3.5 (2)
By: Mark Avdi, Leo Lam

Overview of this book

As cloud applications are becoming more complex, multiple tools and services have emerged to cater to the challenges of running reliable solutions. Although infrastructure as code, containers, and orchestration tools, such as Kubernetes, have proved to be efficient in solving these challenges, AWS CDK represents a paradigm shift in building easily developed, extended, and maintained applications. With AWS CDK in Practice, you’ll start by setting up basic day-to-day infrastructure while understanding the new prospects that CDK offers. You’ll learn how to set up pipelines for building CDK applications on the cloud that are long-lasting, agile, and maintainable. You’ll also gain practical knowledge of container-based and serverless application development. Furthermore, you’ll discover how to leverage AWS CDK to build cloud solutions using code instead of configuration files. Finally, you’ll explore current community best practices for solving production issues when dealing with CDK applications. By the end of this book, you’ll have practical knowledge of CDK, and you’ll be able to leverage the power of AWS with code that is simple to write and maintain using AWS CDK.
Table of Contents (17 chapters)
1
Part 1: An Introduction to AWS CDK
4
Part 2: Practical Cloud Development with AWS CDK
9
Part 3: Serverless Development with AWS CDK
12
Part 4: Advanced Architectural Concepts

Introduction to AWS CDK

In the introduction to this chapter, we covered a basic history of IaC and how these software tools lack the expressiveness of modern programming languages. AWS without a doubt is the frontrunner in the cloud industry, and its answer to difficult infrastructure setup is CDK.

In AWS’s own definition, CDK is an open source software development framework—notice how AWS is not calling it an infrastructure provisioning framework—that defines AWS resources for a cloud application using familiar programming languages.

AWS’s definitiomeans, for example, that instead of defining the EC2 instance using declarative configuration files as we did with Terraform’s HashiCorp Configuration Language (HCL) in the intro, you can define the same instance as the following:

import * as cdk from '@aws-cdk/core'
import * as ec2 from '@aws-cdk/aws-ec2'
 export class MyAppStack extends Stack {
  public readonly default_vpc: IVpc;
  public readonly my_virtual_machine: Instance;
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    this.default_vpc = Vpc.fromLookup(this, 'VPC', {
      // This will get the default account VPC
      isDefault: true,
    });
    this.my_virtual_machine = new Instance(this, 'single-intance', {
      // The type of instance to deploy (e.g. a 't2.micro')
      instanceType: new InstanceType('t2.micro'),
      // The type of image to use for the instance
      machineImage: new AmazonLinuxImage(),
      // A reference to the object representing the VPC
      vpc: this.default_vpc,
    });
  }
}

Note

Don’t worry about running the code in this section; we will get into that after we’ve completed setting up your local machine for CDK development.

You might (rightfully) think that in terms of lines of code, this doesn’t really save you much time. It’s more or less the same amount of configuration we declare. Let’s see what happens if we want to declare 100 EC2 instances:

import * as cdk from '@aws-cdk/core'
import * as ec2 from '@aws-cdk/aws-ec2'
 export class MyAppStack extends Stack {
  public readonly default_vpc: IVpc;
  public readonly my_virtual_machines: Instance[];
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    this.default_vpc = Vpc.fromLookup(this, 'VPC', {
      isDefault: true,
    });
    this.my_virtual_machines = [...Array(100).keys()].map(
      i =>
        new Instance(this, `single-intance-${i}`, {
          instanceType: new InstanceType('t2.micro'),
          machineImage: new AmazonLinuxImage(),
          vpc: this.default_vpc,
        }),
    );
  }
}

Are you excited yet? Let’s now imagine we want to deploy 100 EC2 instances and we want every odd one to be a t2.large instance type instead. Let’s also throw in a Simple Storage Service (S3) bucket too and give all the programs that run within our VMs read access to some files in this S3 bucket. Perhaps there is a shell script in there that we want them to run as soon as they spin up. The following CDK code does exactly that:

import { RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib/core';
import { Instance, InstanceType, AmazonLinuxImage, Vpc, IVpc } from 'aws-cdk-lib/aws-ec2';
import { Bucket } from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
export class MyAppStack extends Stack {
  public readonly bucket: Bucket;
  public readonly default_vpc: IVpc;
  public readonly my_virtual_machines: Instance[];
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    this.default_vpc = Vpc.fromLookup(this, 'VPC', {
      isDefault: true,
    });
    this.my_virtual_machines = [...Array(100).keys()].map(
      i =>
        new Instance(this, `single-intance-${i}`, {
          instanceType: new InstanceType(i % 2 ? 't2.large' : 't2.micro'),
          machineImage: new AmazonLinuxImage(),
          vpc: this.default_vpc,
        }),
    );
    this.bucket = new Bucket(this, 'MyBucket', {
      removalPolicy: RemovalPolicy.DESTROY,
    });
    this.my_virtual_machines.forEach(virtual_machine => {
      this.bucket.grantRead(virtual_machine);
    });
  }
}

As you can see, CDK is an extremely versatile IaC framework. It unleashes the power of programming languages and compilers to declare highly complex AWS infrastructure with code that is, compared to the alternatives, easily readable and extensible. We can loop, map, reference, write conditions, and—more importantly—use the helper functions CDK provides to simplify the previously daunting task of implementing IaC.

This is a revolutionary concept. Full stack developers no longer must learn convoluted domain-specific languages (DSLs) to interact with AWS services; they can bring their current development skills to the world of cloud provisioning. There is no longer a context switch between development and DevOps. You no longer need to leave your IDE, and you can build and deploy the CDK infrastructure using common tools you’ve previously used—for example, npm.

Additionally, CDK has powerful customization and component sharing baked in. You can create batches of stacks, with your own set of governance and compliance requirements as reusable components. A set of certain EC2 machines with AWS Systems Manager parameter store configuration, security groups, certificates, and load balancers that is common within your stack can then be defined as a component (or in CDK terms, a construct) and then initialized and reused as many times as you desire. This is the true power of CDK, and it unleashes countless new opportunities for developers, as we will explore in the following chapters.

Till now, we’ve learned why CDK is cool. We hope you grow to love the toolset just as much as I do as you apply it to your own programming stack. Let’s now get into the good bits and start off by setting up your local machine for CDK development.