AWS Cloud Development Kit (CDK) Crash Course
Aug 16, 2023
AWS Cloud Development Kit (CDK) Crash Course
Learn how to use the AWS Cloud Development Kit (CDK) in this tutorial. The AWS Cloud Development Kit (AWS CDK) is an open-source software development framework to define your cloud application resources using familiar programming languages. We’ll go over the basics, do the CDK Workshop and then talk about some advanced features of CDK. ✏️ Matt Martz created this course. He is an engineer, AWS Community Builder, and CDK fanboi. 🔗 Twitter: https://twitter.com/martzcodes 🔗 Blog: https://matt.martz.codes 🔗 Landing Page / Social: https://martz.codes ⭐️ Course Contents ⭐️ ⌨️ (00:00) CDK Crash Course Intro ⌨️ (01:13) What we’ll cover ⌨️ (02:34) Resources [1, 2, 3, 4] ⌨️ (03:07) CDK Basics [5] ⌨️ (07:34) What are CDK Constructs? [6, 7, 8, 9, 10] ⌨️ (10:15) Level 3 Construct Examples [11, 12, 13] ⌨️ (12:08) Synthesis, Assets, Bootstrapping and Deploy [5] ⌨️ (14:53) CDK Workshop Speedrun - Cloud9 Prep [14, 15] ⌨️ (21:01) CDK Workshop Speedrun - New Project [14] ⌨️ (28:02) CDK Workshop Speedrun - Hello, CDK [14] ⌨️ (35:42) CDK Workshop Speedrun - Writing Constructs [14] ⌨️ (42:26) CDK Workshop Speedrun - Using Construct Libraries [14] ⌨️ (44:14) CDK Workshop Speedrun - Testing Constructs [14] ⌨️ (48:51) Advanced CDK [16, 17, 18, 2, 19, 20] ⌨️ (59:32) More Resources and Thanks! [21, 22, 23] ⭐️ References ⭐️ CDK Developer Guide: https://docs.aws.amazon.com/cdk/v2/gu … [1] CDK Slack: https://cdk.dev [2] The CDK Book: https://thecdkbook.com [3] CDKDay: https://cdkday.com [4] CDKDay talk: Creating Verifiable JSON Web Tokens with AWS CDK • April 2021 - Creating Verifiable JSON… [5] App Lifecycle: https://docs.aws.amazon.com/cdk/v2/gu … [6] CDK API Reference: https://docs.aws.amazon.com/cdk/api/v … [7] Access Analyzer L1 Construct: https://docs.aws.amazon.com/cdk/api/v … [8] Access Analyzer CloudFormation API: https://docs.aws.amazon.com/AWSCloudF … [9] DynamoDB Table L2 Construct: https://docs.aws.amazon.com/cdk/api/v … [10] DynamoDB Table CloudFormation API: https://docs.aws.amazon.com/AWSCloudF … [11] CDKPatterns.com: https://cdkpatterns.com [12] AWS Solutions Constructs: https://docs.aws.amazon.com/solutions … [13] Construct Hub: https://constructs.dev [14] CDK Workshop: https://cdkworkshop.com [15] Cross-account CI/CD Pipeline with CDK Pipelines: https://catalog.us-east-1.prod.worksh … [16] CloudFormation Custom Resources: https://docs.aws.amazon.com/AWSCloudF … [17] CDK Provider Framework: https://docs.aws.amazon.com/cdk/api/v … [18] Testing the Async Cloud with AWS CDK: https://dev.to/aws-builders/testing-t … [19] CDK Aspects: https://docs.aws.amazon.com/cdk/v2/gu … [20] Best Practices: https://docs.aws.amazon.com/cdk/v2/gu … [21] freeCodeCamp: AWS CDK v2 Tutorial: https://www.freecodecamp.org/news/aws … [22] OpenAPI Specs Without Deploying First: https://matt.martz.codes/openapi-spec … [23] Serverless Stack Framework: https://serverless-stack.com 🎉 Thanks to our Champion and Sponsor supporters: 👾 Raymond Odero 👾 Agustín Kussrow 👾 aldo ferretti 👾 Otis Morgan 👾 DeezMaster — Learn to code for free and get a developer job: https://www.freecodecamp.org Read hundreds of articles on programming: https://freecodecamp.org/news
Content
0 -> AWS cloud development kit is an open source
tool that allows developers to use their
5.12 -> favorite programming languages to write
infrastructures code for AWS, Matt marks is
10.24 -> an AWS community builder, and he will teach you
how to use the AWS cloud development kit. Hey,
16.56 -> I'm Matt Mart's. And I'm Brian. And I'm an
AWS community builder. And I'm here to give
23.52 -> you a CDK Crash Course from Free Code Camp. You
might be here because you're tired of manually
31.2 -> provisioning your resources via the console.
Or maybe like me, you hate writing yaml.
37.04 -> But CDK has also been in the news a lot lately. In
December, version two became generally available.
43.52 -> Version two was a massive improvement over version
one, since there is only one stable NPM library to
48.64 -> install, instead of one for each module. Among
other improvements, CDK was also featured fairly
56.24 -> prominently in Dr. Vogel's reinvent keynote.
And the CDK book was released. The CDK book
63.68 -> was written by a bunch of the AWS heroes, and
it will go into greater depth than what will
67.68 -> be covered in this crash course, there will be
overlap, but I still strongly recommend the book.
74.56 -> So what will we cover in this course, I'm going to
start by going over the basics of CDK definitions
81.76 -> of the app stacks, constructs and how it all
relates to CloudFormation. Then I'm going to do a
88.56 -> 30 minute speed run of the CDK workshop, which is
a workshop provided by AWS, and it's available at
96 -> CDK workshop.com. From there, we'll go into some
advanced topics like testing and best practices.
106.88 -> This course is split up into chapters on YouTube.
So if there are particular areas of interest,
112.8 -> feel free to jump around. I'll also provide
timestamp links in the description with
118.4 -> supplemental information. This will include useful
documentation, blogs, links, or anything else.
126.72 -> I'm going to go through the CDK workshop very
quickly, but you should do it yourself. The best
132 -> way to learn about CDK is by using it. And since
this is a YouTube video, feel free to speed me up,
140.08 -> slow me down, or rewatch sections if you need to.
144.56 -> If you think I've missed something in this crash
course, or you didn't understand something, let me
149.2 -> know in the comments or follow me on Twitter and
reach out there. I'll be happy to help. Here are
156.48 -> a few other resources I'd like to specifically
call out. The CDK community on Slack is very
162.24 -> active. It's full of friendly, knowledgeable
people that love to help out. The authors of the
166.88 -> CDK book are also very active there. Speaking
of Did you hear there's a CDK book out now.
174.64 -> Aside from that, there's also CBK day which
is an annual conference related to CDK.
180.24 -> Last year, I gave a 15 minute
lightning talk on creating verifiable
184.08 -> jots with CDK. And I'll add a link to that below.
189.12 -> And with that out of the way, I hope you're in
the right place. Let's move on to the basics.
196.32 -> CDK stands for cloud development kit.
It's open source software provided by AWS
203.04 -> that enables you to write imperative code to
generate declarative CloudFormation templates.
209.6 -> It enables you to define the how so that you can
get the what that means you can focus more on
216.16 -> the architecture of your app instead of the nitty
gritty details of IAM roles and policy statements.
222.72 -> CDK is available in JavaScript, TypeScript,
Python, Java, C sharp, and it's in a developer
229.84 -> preview for go CDK itself is no GS based.
Even if you use one of the other languages,
237.12 -> the CDK code itself will be executed
via no GS. So no J S is a requirement.
245.68 -> Okay, so CDK generates CloudFormation. But what's
that cloud formation is an AWS service that
254 -> provisions AWS resources and stacks. AWS
resources are things like lambda functions,
260.32 -> s3, buckets, DynamoDB, tables, pretty much
anything that AWS offers. A CloudFormation stack
267.76 -> is just a collection of AWS resources. Cloud for
me, CloudFormation uses JSON or YAML files as a
274.56 -> template that describes the intended state of all
the resources you need to deploy your application.
280.72 -> The stack implements and manages the group
of resources outlined in your template
285.44 -> and it allows the state and dependencies
of those resources to be managed together.
290.24 -> When you update a CloudFormation
template, it creates a change set.
294.24 -> A change set is a preview of changes that
will be executed by stack operations to create
300.16 -> Update or remove resources so
that the template becomes in sync.
307.6 -> So CDK generates cloud formation and cloud
formation provisions, AWS resources. What does
313.52 -> the CDK app look like and how does it relate? The
root of CDK is the CDK app. It's a construct that
322 -> coordinates the lifecycle of the stacks within it.
There is no CloudFormation equivalent for an app.
328.4 -> Within the app, you can have multiple CDK stacks,
and CDK stacks can even have nested stacks.
335.44 -> CDK stacks are one to one equivalent
with CloudFormation stacks,
339.36 -> and nested stacks are also one to one equilibrium
equivalent with CloudFormation stacks. When you
345.12 -> run CDK, synth or CDK deploy the output is the
CloudFormation template for this app structure.
360.4 -> The CDK app is a special route construct
that orchestrates the lifecycle of the stacks
365.68 -> and the resources within it. The app lifecycle
constructs the tree of the app in a top down
371.84 -> approach, and then it executes the methods for
the constructs within it. You typically don't need
378.08 -> to directly interface with any of the prepare,
validate or synthesize methods of the constructs,
383.2 -> but they can be overridden. The final stage
of the apps lifecycle is the deploy phase,
389.44 -> where the cloud formation artifact is uploaded to
cloud formation. The unit of deployment in CDK is
397.44 -> called a stack. All resources defined within the
scope of a stack, either directly or indirectly,
404.08 -> are provisioned as a single unit CDK stacks have
the same limitations as CloudFormation stacks.
411.52 -> Stacks are powerful in cloud formation. In order
to deploy a template to multiple environments,
416.96 -> you need to use cloud formation parameters.
But these are only resolved during deployment.
422.96 -> In cloud formation, if you want to conditionally
include a resource based on a parameter,
427.68 -> you have to use the CloudFormation condition.
But in CDK, you don't have to use either, you
433.84 -> can simply use an if statement to check a value
whether the resource should be defined or not,
438.56 -> it ends up being much simpler. You can use cloud
formation parameters and conditions in CDK. But
446 -> they're discouraged since they only resolve during
deployment, which is well after CDK synthesis.
456.4 -> We've heard a lot about
constructs. But what are they?
459.76 -> There are four levels of constructs. Level
zero constructs are just basic resources.
465.44 -> All of the higher levels inherit from level
zero, there's no specific type tied to it.
471.12 -> Level one constructs are one to one
representations of CloudFormation resources.
476.08 -> They are all prefixed in the CDK API with
the letters C F n, we which is a short form
483.12 -> of CloudFormation. The way I remember this is
level one is one to one with CloudFormation.
491.36 -> Level two constructs aren't improved
or extended level one constructs.
496.16 -> They're provided by the CDK team and offer
helper methods and sensible defaults.
501.92 -> Level three constructs are
combinations of constructs,
506.16 -> which could be an intermingling of level
one, two and three constructs together.
511.6 -> More often than not, you'll be interacting
with level two or three constructs.
516.4 -> Some modules in CDK don't have level two
constructs yet. But pretty much all of the
521.04 -> level one constructs exist for the corresponding
CloudFormation API. The CDK team is very fast at
527.52 -> implementing changes to level one constructs
and more frequently used level two constructs.
534.48 -> for level one construct, let's look at the access
analyzer module. In this case, the module doesn't
541.36 -> have any level two constructs available, so
there's only the level one CFN analyzer construct.
549.84 -> As you can see, this is a one to one
representation with the CloudFormation API.
556.72 -> The CFN analyzer construct has the same properties
defined as the CloudFormation API for the same.
564.56 -> There are also new helper utility
methods on the CFN analyzer construct.
571.44 -> For level two construct, let's look
at the DynamoDB table construct.
576.24 -> It doesn't have a CFN prefix and
includes many sensible defaults.
580.96 -> For example, the billing mode defaults to pay per
request, unless you specify replication regions.
588.88 -> If you specify replication regions, it becomes
provisioned and if it becomes provisioned,
594.32 -> the default Read and Write capacities get
set and defaulted to five The default removal
600.96 -> policy of the table is retained. And the
table has helper methods to create global
607.28 -> or local secondary indexes, and to create varying
levels of access to the table and it streams.
616.88 -> For level three constructs, the CDK doesn't offer
anything specific out of the box. These tend to
623.12 -> be created at the individual organization or
community level, and provided as libraries.
630.08 -> An example level three construct would be
to create a notifying bucket. This construct
635.44 -> creates an s3 bucket along with an SNS topic.
It then adds an object created notification
642.08 -> coming from the s3 bucket to target the SNS
topic. All you have to do to use this is add
649.36 -> a new notifying bucket to your app. And it will
provision all of these resources automatically.
655.52 -> There are several great resources in the
community that I'd also like to call out. CDK
663.2 -> patterns.com is a resource that enables you
to search by community provided examples,
668.96 -> and it's cross referenced by the different
components used within it. AWS also offers another
677.12 -> open source extension of the CDK with their AWS
solutions constructs. These provide multi service
684.72 -> well architected patterns for quickly defining
solutions in code for frequently used patterns.
691.92 -> This is available as an NPM library that you
can install and use right out of the box.
700.56 -> There's also the construct hub. The construct
hub is a central destination for discovering
705.84 -> and sharing cloud application design patterns
and reference architectures designed for CDK
711.92 -> CDK for Kubernetes, and CDK. For TerraForm, and
other construct based tools, construct hub pulls
720.08 -> from the NPM registry, all CDK constructs that
support multiple languages and are correctly
726.08 -> annotated. Great. So I think we have a handle
on constructs. Now, let's go a little deeper.
735.76 -> How do we generate the CloudFormation template. In
order to do that the app needs to be synthesized.
744.08 -> To do this, we can run CDK. Since this
traverses the app tree and invokes synthesize
750.32 -> on all of the constructs, this ends up generating
unique IDs for the CloudFormation resources
756 -> and generates the respective EML
along with any assets that are needed.
764.4 -> Okay, so what are assets? Assets
are the files bundled into CDK apps.
771.68 -> They include things like the lambda handler
code, Docker images, layer versions, files,
777.6 -> going into an s3, bucket, etc. They can
represent any artifact that the app needs.
785.36 -> When you run CDK synth or deploy, these get output
to a CDK dot out folder on your local machine.
794.8 -> Okay, so what does CDK do with these assets? How
do they get put into CloudFormation? Well, that's
802.08 -> where bootstrapping comes into play. Bootstrapping
creates a CDK toolkit cloud formation stack
808.88 -> deployed to your account. This account includes
an s3 bucket and various permissions that are
814.4 -> needed for CDK to do the deployments and upload
the assets. bootstrapping is required when your
820.72 -> app has assets or your CloudFormation templates
become larger than 50 kilobytes. So it's pretty
826.8 -> much always required, you're almost always
going to have some sort of asset in your stack.
832.96 -> For CDK version to administrator access is needed
to create the roles that CDK toolkit stack needs
839.44 -> in order to do deployments. You won't need
administrator access after CDK is bootstrapped.
848.48 -> With the bootstrapping done,
we can move on to deploying.
852.56 -> When you run CDK deploy, the app is
initialized or constructed into an app tree.
859.04 -> Once the construction is done, the app goes
through preparation, validation and synthesize
864.4 -> steps. So each construct calls its prepare method,
then each construct calls its validate method. And
871.92 -> then each construct calls its synthesized method.
Up to this point, this is what CDK sent us.
879.76 -> From there, the app uploads the template and any
other artifacts to cloud formation, and cloud
885.84 -> formation deployment begins. Once this handoff
is done, it's all in the hands of CloudFormation.
894.4 -> Now that we've defined some of the basic
pieces of CDK let's move on to the workshop.
899.6 -> The word stops at CDK workshop calm. You
should do this first and then come back.
908.08 -> Perfect. Once you come back, we'll do the
30 Minute speed round through the workshop.
912.72 -> We're gonna get started with this workshop
by creating a cloud nine environment.
916 -> To do that, I'm going to steal some instructions
from the CDK pipelines workshop, it's going to
920.24 -> have a screen and I enroll for Cloud Nine that
has full access. This is going to be used in
924.4 -> bootstrapping the account for CDK. Version two
links for the CDK pipelines workshop will be in
929.6 -> the description below. It's a great workshop and
you should work through it if you have the time.
935.12 -> First, we're going to go to the cloud
nine console and create an environment.
940.48 -> I'm just going to name it CDK workshop,
and we don't need a description.
945.28 -> Then we select an instance type, I did this
workshop with a T three small instance. But the
949.84 -> M five large would probably be better. All
the other options can use the defaults.
955.12 -> While CLOUD NINE spins up, I want to note
that both the T three small and N five large
958.72 -> instances are not free tier eligible. So it might
cost you some money. I was getting some memory
964.16 -> errors towards the end with the T three small
instance. But it still worked. To create the
969.44 -> I am role. The CDK pipelines workshop has a deep
link that will take you to the role creation page.
976 -> From there, we confirm that it's AWS service
entity and for easy to and then go to permissions.
983.6 -> Make sure that administrator access is selected.
We don't need new tags, so we can skip that.
991.44 -> And then we're going to give it a name, we're
going to name this CDK admin and create the role.
1002.56 -> With the role created, we can go back to the CDK
pipeline workshop and see that we need to actually
1008.16 -> go in and attach the roll to the EC two instance.
There is a deep link. But since we had named
1014.4 -> the EC two instance, something else we actually
need to go to the EC to console, go to instances.
1022.4 -> And then select the instance that with
our cloud nine instance that's running.
1028.56 -> Go to actions, security and modify Iam role.
1036.08 -> From here we're going to select the IAM roles
that we just created CDK admin and save it.
1043.76 -> Now if we go to the CDK workshop, Cloud Nine
and refresh, it will automatically have the role
1050.88 -> that we need. Next, we need to do some cloud nine
housekeeping and setup, we're going to remove the
1057.6 -> AWS manage temporary credentials. These prevent
us from using the role that we attached to the
1062.32 -> Cloud Nine easy to instance, in the upper
right corner of cloud nine, go to settings
1069.92 -> and then scroll down to AWS settings and
turn off AWS manage temporary credentials.
1076.16 -> To make doubly sure that the credentials are gone,
we're going to remove the credentials folder.
1089.28 -> Next, we're going to do some environment
config, we need to install JQ using yum.
1103.52 -> And then we're going to export some environment
variables with AWS account information.
1117.44 -> To check to make sure that the AWS region was set
correctly, we're going to do this test command.
1130.48 -> And finally, we're going to export the account
1133.28 -> ID and region and make sure
AWS is configured correctly.
1142.16 -> Now we need to make sure that Cloud Nine
is easy to instances using the right a
1146 -> Iam role. To do that, we're going to use this STS
get color identity command. It's gonna fail here
1153.28 -> because we actually named the role CDK admin. So
if we update the command to check for CDK admin,
1160.96 -> we'll get the that the im role is valid like this.
1172.72 -> At this point, we can switch back to the actual
CDK intro workshop. We're going to go to the
1179.28 -> prerequisites tab and start checking things to
make sure that everything is like it should be.
1190.8 -> The AWS CLI is already installed and we've
already set up the AWS account and user.
1197.36 -> Next we want to make sure that we have a
good node version installed In Cloud Nine,
1202.72 -> CLOUD NINE comes with Node installed.
So let's just check the version.
1208.32 -> And here version 16 is fine. We're
also gonna want to check CDK.
1213.76 -> Now, this is a CDK to workshop. So we want
to make sure that we actually bumped up
1219.68 -> the version of CDK. So if we
do NPM i for install AWS CDK.
1226.8 -> Globally, we're gonna get this error because he's
the Cloud Nine instance of easytouse weird, so you
1231.84 -> actually have to force it. In this case, the CDK
pipeline tutorial also goes through this as well.
1239.04 -> Now that we've forced installed it, we
can see that version 2.3 is installed.
1249.2 -> We're already using AWS cloud nine, we
just checked the CDK version. And that
1256.72 -> concludes the prerequisites. Next,
we can begin the actual workshop.
1267.76 -> So let's get started, we'll go to the
CDK. And next step, the first thing we
1272 -> need to do is create a directory to work in.
So we're gonna make the CDK workshop directory
1280.88 -> and change into it. Now we need
to actually admit the project. So
1287.04 -> we're gonna run CDK and it sample
app with the language TypeScript.
1296.88 -> This creates a Git repo, and NPM installs all
the dependencies for a basic CDK two project
1306.08 -> CDK two is a massive improvement over CDK
version one because it bakes in all of the
1311.36 -> stable modules into one NPM dependency CDK version
one had individual NPM libraries for each module
1318.16 -> like DynamoDB, lambda SNS, etc. In version two,
you just have one, and that avoids a lot of the
1324.96 -> dependency management hell. Now that the thug
project is initialized to CDK workshop is going to
1330.96 -> want us to run the watch command in the background
to compile the TypeScript into JavaScript.
1342.72 -> So we're going to create a new terminal,
change directories into the project folder,
1348.88 -> and then run the NPM run watch
command in the background.
1362.72 -> With that done, we can move on to
the next step and actually check
1367.28 -> out the project structure of what
was what's been initialized so far.
1372.48 -> So let's go back to the Cloud Nine environment,
we'll open up the project folder, and let's start
1378.56 -> looking at some files. Let's start where
CDK starts with the bin slash CDK workshop
1385.04 -> TypeScript file. This file instantiates the
CDK app by creating stacks. That is to say,
1391.6 -> when you run CDK center CD kit, boy, it starts
here to generate the CloudFormation templates.
1398.08 -> CDK stacks are one to one equivalent with
CloudFormation stacks. An app can have multiple
1404 -> stacks, and each stack would end up creating
a new stack in cloud formation. In the case
1408.96 -> of our sample app, there's only one stack, the
CDK workshop stack. So let's look at that next.
1415.76 -> The sample stack is pretty simple. It uses
two level two constructs. One to create an
1421.2 -> SQ SQ and one to create an SNS topic, then
subscribes the queue to the topic. That's
1428.16 -> it. The workshop goes into similar detail with
these. But let's move on to our first CDK synth.
1436.64 -> As described before, when CDK apps are executed,
they produce an AWS CloudFormation template for
1442.24 -> each stack defined in the app. Switching back
to cloud nine, let's run CDK Seth, I'm going to
1447.76 -> output to a template dot Yamo file to make it
a little easier to read. Now, there are two
1453.84 -> important concepts I want to call out here. CDK is
both imperative it describes the how the app will
1459.28 -> be built. But it's also item potent, given the
same inputs, it will produce the same outputs.
1469.44 -> See here, we use the same code between the
CDK workshop in my cloud nine instance.
1474.8 -> And the cloud formation that was generated as
the same. For example, the resource hash hashes
1479.6 -> match between the two. This is because we used
all the same inputs that the CDK workshop did.
1485.36 -> If I went and change the topic or cue ID, the
hash would change and we'd have something else.
1490.08 -> This is going to be important
in unit testing later.
1494.24 -> Now that we've sent, let's deploy. In order
to do that we need to bootstrap the account
1505.12 -> Let's open up a new console window and
go to cloud formation. And this account,
1508.88 -> the only one running right now should
be the one that's used for cloud nine.
1515.84 -> Right here. So let's go back to the Cloud
Nine terminal and run the Bootstrap.
1525.52 -> This is why we needed to create an im role
with administrator access. And it's actually
1529.6 -> the only time you need admin access when you're
bootstrapping the account. In order for CDK,
1535.44 -> to deploy apps, it needs to store
the assets somewhere. The Bootstrap
1539.92 -> creates its own cloud formation template that
we'll see when we go back to cloud formation.
1545.28 -> And that includes a number of roles and policies
that enable it to store assets for deployment.
1595.12 -> As you can see here, the CDK toolkit stack
was just created from the bootstrap process.
1604.08 -> Now, if we switch back to cloud nine,
we can actually run the deploy command.
1613.6 -> The deploy command resynthesize is the
app. And if there's any IAM policy changes
1622.08 -> in the census, it will display them and ask
to make sure that you want to continue. Here,
1630 -> since we're subscribing the queue to the
topic, a IAM policy needs to be in place
1638.4 -> in order to make that happen. So yeah, we
do want that to happen. So let's deploy it.
1647.36 -> While CloudFormation is spinning up, if we
refresh CloudFormation, we'll see the CDK
1651.84 -> workshop stack create is in progress. And we can
actually view the resources as they're created.
1657.6 -> So here we can see that there's a metadata
entry along with the queue and topic,
1661.84 -> but there's no actual subscription
yet or policies related to it.
1672.24 -> Now that the crate is complete, we
can go back to the resources and see
1676.72 -> that yes, there is a queue
policy and a subscription.
1688.64 -> Well, that was fun. But now
let's get her hands dirty.
1692.88 -> The CDK workshop is going to take you through a
couple steps at this point. We're going to clean
1696.88 -> up the stack by removing the SNS topic and the SQ
sq. And then we're going to create a simple API
1703.68 -> gateway backed by lambda. So let's get started.
We're going to delete the sample code from our
1708.4 -> stack. And then we're going to do a diff to
see what it shows. Go back to the stack file.
1719.12 -> And delete the queue topic and the topic
that adds description along with the imports.
1734.96 -> That are on the CDK diff command.
1743.12 -> What CDK diff does is it re synthesizes the
1746.88 -> CloudFormation app and compares the yam all
from one to the other. And we can see here
1753.52 -> that it's destroying the queue queue
policy subscription and the topic.
1760.96 -> Next we can CDK deploy as it's deploying,
1768.48 -> the only thing that the CloudFormation stack
should be left with is the CDK metadata entry.
1778.4 -> Till we go back to cloud formation, we can check
1781.68 -> the progress of this by refreshing
the resources as it is progressing.
1798.48 -> They're done Now let's go back to cloud nine
and create the lambda. We'll create a folder
1806.08 -> called lambda, and put a hello.js file in it.
1818.72 -> Inside of that, we'll put some basic lambda code.
Next, we need to create the lambda in the stack,
1824.64 -> we'll add the lambda import from CDK to
then create the actual lambda function.
1832.72 -> One of the biggest benefits of creating AWS
resources using CDK is the IntelliSense.
1837.84 -> Having imported from AWS lambda, I can create
a new function using new lambda dot function,
1844.56 -> pass the stack and ID of the lambda
in and give it some properties.
1854.72 -> In this case, we needed to find the runtime using
1862.56 -> lambda.runtime.no, Gs 14 where the code
lives, which we use code dot from asset
1876.48 -> and then lambda, which uploads the
lambda folder as an asset to s3.
1883.92 -> And then they were the handlers. In
this case, our handlers and Hello,
1888.72 -> the Hello file, and it's named handler. Now
we can run the diff. And this will show us
1895.28 -> that it's going to create a im role for
the lambda and the lambda function itself.
1908.88 -> Which this looks good to me. So let's just deploy
it. I'm going to speed this part up a little bit.
1933.2 -> And we can see the function and the role in cloud
formation. So let's test out the lambda itself. In
1945.6 -> the code source area of the lambda console, we can
create a test event by clicking the test button.
1956.16 -> We'll select API gateway AWS proxy, because
ultimately, we'll be connecting this to an
1961.52 -> API gateway. Don't forget to give
it a name. And doesn't like spaces.
1972 -> And hit create. What do we get test
again, it'll invoke the lambda.
1977.36 -> And now we can see the status of 200. And
that the body has the correct response.
1984.32 -> So let's add an API gateway. First, we'll
import the API gateway module from CDK.
1996.56 -> And then we'll create a lambda REST
API. Lambda rest API's are just rest
2004.32 -> API's with a greedy proxy that sends
everything to the defined lambda.
2010.8 -> We'll pass in the stack construct
and give the REST API an ID.
2016.64 -> And then we'll tell it our hello
function as the API handler.
2028.88 -> Now we can run a diff. And I'll also show that
there's actually no API gateway already defined
2037.04 -> by going to the API gateway
console. And here, there's no API's.
2053.76 -> So let's deploy it. I'm going to speed
this up again. But what it's doing is
2063.92 -> it's creating a bunch of resources
automatically. There's the API gateway
2068.08 -> itself permissions for the gateway, and
for it to invoke the lambda, etc, etc.
2085.2 -> Now that it's done, we can see we went from
three resources to 15 in CloudFormation. And
2092.56 -> this was all handled with a couple lines of
code. And if I go and refresh the lambda page
2104.64 -> We can see that the API gateway is added
to the lambda console as a trigger.
2111.52 -> Similar, we can see the API is
defined on the API gateway console.
2118.96 -> So let's test it. We'll grab the API URL that
was automatically output as part of the deploy,
2129.04 -> and send it a curl request.
Nice. And let's try another one.
2141.04 -> Very nice.
2148 -> All we've done so far is use a few level two
constructs. Let's make our own level three
2153.84 -> construct. We'll make an interceptor lambda that
writes to the DynamoDB table, and then invokes any
2159.44 -> targeted downstream lambda. Let's get started.
We'll create a new hit counter type script file
2170.4 -> in the lib folder, and put
some boilerplate construct code
2177.04 -> in here. All this does is extend
the construct and to find the props.
2183.84 -> Next, let's create our interceptor lambda
and the lambda folder, we'll create
2188.32 -> hit counter dot j, s. And we'll copy
the code over from the workshop.
2195.2 -> what this code does is it uses two modules from
the AWS SDK to interact with both Dynamo DB and
2201.44 -> lambda will use Update Item from Dynamo DB to
increment a hit counter for a path. And we'll use
2208.16 -> the lamda client to invoke the downstream lambda,
and then return the response from that lambda
2214.64 -> with the table and lambda will be passed into
this interceptor lambda via environment variables.
2224.88 -> Now that that's done, we need to
create both the table and the lambda,
2228.8 -> we'll add the DynamoDB module from
CDK. And then create the table
2238.72 -> using new DynamoDB dot table, we'll pass in
the stack construct and give the table an ID.
2247.92 -> And DynamoDB also needs to define a partition
key. So we'll go ahead and do that as well.
2257.68 -> Next, we'll create the lambda, this
follows the same pattern as before
2266.24 -> do lambda dot function, pass in this give it
a ID and set the runtime which is no Jess.
2291.28 -> The handler, which in this
case is hit counter dot handler
2301.04 -> and then the code coming from
code dot from asset lambda
2310.72 -> we need to pass in the environment variables.
2314.08 -> And I'll make a tweak to the lambda Id
just to be consistent with the workshop.
2321.36 -> Now we're going to want to expose the lamda
as a read only property of the construct.
2326.72 -> So add this Public Read Only line to the class.
And we'll assign the lambda to the property.
2335.84 -> Now this construct is great as is,
but it's not being used anywhere.
2339.52 -> So let's fix that. We'll go
back to the main workshop stack.
2348.56 -> And use the construct. It's the same
pattern as a level two construct.
2354.8 -> So we can do a new hit counter
pass in the stack, give it an ID.
2363.04 -> And in our case, the properties here is the
downstream lambda that we want to invoke. So we'll
2368.24 -> set downstream to Hello. And I will do a trick
to import the hit counter from the local file.
2380.48 -> But now we need to make the API use this
lambda instead. So we will move the API
2387.68 -> below and change the handler of the
API from hello to hello with counter
2398.64 -> and this is why we expose The Read
Only property for the handler,
2401.52 -> it's so that the API actually has access to the
lambda within the construct. So let's deploy it.
2415.84 -> With some editing magic, we'll skip ahead again.
2428.08 -> Now that we're deployed, we can test it. The
CDK workshop builds in snares to expose some
2432.72 -> nice things about LTU constructs. As we can
see, the request here failed. In order to see
2439.92 -> why we'll need to look at the logs. So let's
switch to the lambda console in the console.
2445.84 -> Click the Monitor tab, and
click view logs in cloud watch.
2456.8 -> If we go to the latest log stream,
2462.48 -> we can see that there's an invoke error, and
it's because of an Access Denied exception.
2467.68 -> And if you read a little further, it says
basically that the lambda is not authorized
2472.48 -> to perform Dynamo DB Update Item on the
resource. We never gave it permission.
2480.88 -> So let's go back to the hit counter file. We're
going to use the tables L to construct helper
2488.96 -> method of grant readwrite data to apply
the correct policy statements to lamda.
2499.12 -> The workshop also forgot to add the
permission for the lambda to be able
2503.2 -> to invoke the downstream lambda. So we're
just going to go ahead and add that now.
2512.8 -> Now if we deploy again, and skip
forward and we test the function
2523.12 -> we'll get a successful response because
everything has the correct permissions.
2539.12 -> From here, if we go to Dynamo DB, and refresh
the items in the table, we can see that the
2543.44 -> right endpoints are being tracked. From the CDK
workshop, we're going to npm install the CDK
2557.52 -> Dynamo table viewer library into our project.
With it installed, we can switch to our stack
2571.6 -> and import the table viewer from
the library. Then we're going to go
2578.32 -> and create a new instance of it. This table viewer
library is an L three construct because it groups
2584.4 -> multiple L two constructs together, just like we
did with the hit counter L three construct that we
2588.88 -> made in the previous section. The table viewer
construct expects us to pass in the DynamoDB
2594.24 -> table from our other construct, but we didn't
expose that. So let's go back to our construct
2603.52 -> add the table property and assign
the table to that property.
2623.68 -> With that, we can pass the hello with counter dot
table property into our third party construct.
2635.12 -> Now if we deploy and skip ahead, we'll see
that the table viewer construct created a
2641.28 -> separate API gateway and its own
endpoint defined in the outputs.
2646.4 -> If we go there, it will end up
displaying what's in the DynamoDB table.
2660.4 -> Testing constructs is one of the
most powerful things about CDK.
2664.4 -> The CDK workshop walks you through two types
of tests, assertion tests and validation tests.
2671.2 -> For the first assertion test,
we're going to create a stack
2674.56 -> and use our hit counter construct and then
verify that one DynamoDB table was created.
2681.76 -> So let's go back to the code. Create
the test and remove the old ones
2702 -> Now we can run it.
2726.32 -> And one DynamoDB table was created.
2730.72 -> Next we'll move on to checking the lambda. The
CDK assertions library has some useful features
2735.52 -> like capture, which can intercept different
properties as part of the template synthesis.
2740.64 -> In this case, we use CAPTCHA to verify
that the correct downstream function and
2744.32 -> table names are being passed into the hit
counter lambda. When we run this test,
2750.32 -> we expect it to fail because I didn't copy
the references from the synthesized output.
2754.56 -> But making it fail actually makes it easier
to find them. So we'll grab the correct names
2767.68 -> and update the test with the right ones.
2778.8 -> Now when we run it, it'll pass. Next, let's switch
to a test driven development mindset. And say we
2789.04 -> want to make sure our table is using server
side encryption, we can assert that DynamoDB
2793.44 -> table resource has server side encryption
enabled. So when we run the test, it'll fail.
2808.32 -> From a development perspective, that
means we need to go back to the construct
2814.4 -> and make sure that server
side encryption is enabled.
2828.16 -> Now if we run the test again, it'll
pass. Since we don't actually want that,
2835.12 -> I'm going to remove it from the
construct and remove the test.
2843.68 -> Next, let's talk about validation testing.
Let's say as part of your construct, you want
2848.8 -> to make sure a sane number of read capacity
units are being used in the DynamoDB table.
2855.6 -> We can add a read capacity property that gets
passed into the construct. Use it in the table.
2867.76 -> And then in the constructor, we can
validate that the value passed in
2871.36 -> is reasonable, say between five and
20. If it's not, we'll throw an error.
2879.52 -> Now let's add a test that passes in a value out
of range to a three and verify that the error
2887.44 -> is thrown. When we run the test, it'll
pass because the error is being thrown.
2897.52 -> This error would be thrown as part
of stack synthesis. So let's see that
2902.64 -> we'll go back to our workshop stack.
2906.8 -> Add an out of bounds read capacity
value and run the stack synthesis.
2918.48 -> As you can see there is validation
testing is super useful. At my work,
2923.6 -> I use it to help enforce some naming conventions,
2926.56 -> and also to log or throw deprecation warnings
when property inputs or defaults change.
2933.04 -> Great job with the workshop.
Now that the workshops done,
2937.28 -> we can move on to some advanced topics
like aspects and best practices.
2943.76 -> In the workshop, we went over fine grained
assertions by checking for things like
2948.08 -> number of tables created and ensuring encryption
was turned on. We're checking to make sure the
2953.52 -> lamda environment variables being passed in or
the right one. But you could also use snapshot
2960 -> testing to check the entire template if you want
to do and use gests match snapshot functionality.
2968.08 -> We also went over validation testing as part of
the workshop. We checked the properties being
2972.8 -> passed into the construct to make sure read
capacity units were within a specific range.
2979.76 -> In my organization, we also use this
to help enforce some naming conventions
2984 -> as well as throw some deprecation warnings in
the event we have to significantly change the
2988.56 -> construct. In this case, the warnings won't
block deployment, but it will show up in the
2993.68 -> console when doing synthetic deploy, where
developers can pick them up and fix them.
2999.6 -> You are aren't limited to just
logging errors to the console though,
3003.12 -> when you sent you're executing the actual
code. So you could also log to an external
3008.4 -> service like a platform service that tracks
deployments, or logs to cloud watch itself.
3015.44 -> The last form of testing is integration testing.
With CDK, you can use AWS custom resources to test
3022.16 -> that the resources are working together correctly
as part of the CloudFormation deployment. If
3027.2 -> something breaks, it will automatically
roll back the CloudFormation deployment.
3034.88 -> CDK has a provider framework for interfacing
with CloudFormation custom resources.
3040.16 -> These custom resources enable you to write
custom provisioning logic and templates that
3044.56 -> CloudFormation runs anytime you create,
update or delete stacks. We can make use
3050.16 -> of this to do integration testing across
our stack. Let's say you have an event bus,
3054.64 -> a lamda. And a DynamoDB table that you want
to make sure are interacting with each other.
3059.92 -> You could use the provider framework to spin up
a lambda to emit a test event on an Event Bus,
3065.44 -> all part of the CloudFormation deployment. And
then the custom resource can query DynamoDB
3071.12 -> waiting for the change. If the change
doesn't happen in a set amount of time,
3076.08 -> the build will fail and CloudFormation
will automatically roll back the changes.
3082.4 -> Matt Morgan has an excellent blog post about
this called testing the async cloud with AWS CDK.
3089.84 -> The CDK book also has a section on this.
3095.2 -> Another advanced topic for the CDK are aspects
aspects are a very powerful tool in CDK.
3103.28 -> There are a way to apply an operation
to all constructs in a given scope.
3108.08 -> The aspect could modify the constructs such as by
adding tags, or it could verify something or about
3113.6 -> the state of the constructs such as
ensuring that all the buckets are encrypted.
3119.76 -> During the Prepare phase CDK calls the visit
method of the object for the construct and each of
3125.76 -> its children in a top down order. The visit method
is free to change anything in the construct.
3134.24 -> In this example, the bucket version checking
class implements a visit method that checks
3139.52 -> if s3 bucket versioning is enabled. Here it
throws an error, but you could just as easily
3145.28 -> modify the construct to enable versioning.
Everything that the stack is applied to
3151.44 -> that is every construct within the stack
is evaluated by this visit method. Which
3157.52 -> is why we need to check the instance of the node
being evaluated to make sure it's the CFN bucket.
3164.72 -> The nodes will all end up being the level
one construct of the resource in question.
3169.36 -> Even if you use a level two bucket
construct within your stack code.
3176.32 -> For best practices, AWS breaks up their
best practice recommendations into four
3181.76 -> different areas. Organization
coding construct an application.
3190.16 -> For organization best practices,
AWS recommends having a team of
3194.24 -> CDK experts help set standards and train
or mentor developers in the use of CDK.
3200.64 -> This doesn't have to be a large team. It
could be as small as one or two people
3204.88 -> or it could be a center of excellence
if you have a large organization.
3210.08 -> AWS also recommends the practice of deploying
to multiple AWS accounts. For example,
3215.6 -> having separate production, QA and development
accounts. You should use continuous integration
3222.08 -> and continuous deployment tools like CDK pipelines
for deploying beyond development accounts.
3230.08 -> For coding best practices, AWS recommends to
only add complexity where you actually need it.
3236.72 -> Don't architect for all possible scenarios up
front. So the keep it simple, stupid principle.
3244.08 -> It also recommends to use the
well architected framework
3250.08 -> AWS CDK apps are a mechanism to codify and
deliver well architected best practices.
3256.24 -> As you follow these principles, you can create
and share components that implement them. Earlier
3264.4 -> I stated it's possible to have multiple apps in a
project, which is true, but it's not recommended.
3270.8 -> Best practice is to not do that and to only have a
single app per repo. In a CI CD world changes the
3279.6 -> one app could unnecessarily trigger the deployment
of another app, even if it didn't change.
3286.88 -> Finally, your CDK code and the code
that implements your runtime logic
3290.88 -> should be in the same package. They don't need
to live in separate repositories or packages.
3300.16 -> For construct best practices, you should be
building constructs of your logical units of code.
3306.4 -> If you consistently build websites with
s3, buckets, API gateways and lambdas,
3311.6 -> make that a construct and then
use the construct in your stack.
3316.88 -> It's a bad practice to use environment
variable lookups within your constructs.
3321.36 -> environment variable lookups should
happen at the top level of a CDK app,
3325.28 -> and then be passed to the stacks and constructs as
properties. By using environment variable lookups,
3333.04 -> and constructs you lose portability and
make your constructs harder to reuse.
3339.92 -> If you avoid network lookups during synthesis
and model all your production stages in code,
3345.12 -> you can run a full suite of unit tests at
build time consistently in all environments.
3352.96 -> Be careful how you fact refactor your code
that may result in changes to the logical ID.
3358.88 -> The logical ID is derived from the ID you
specify when you instantiate a construct,
3364.16 -> and the constructs position in the app tree.
Changing the logical idea of a resource results
3371.76 -> in the resource being replaced with a new one at
the next deployment, which you almost never want.
3378.88 -> constructs are great, but they're
not built to enforce compliance.
3383.68 -> Compliance is better suited to using Service
control policies and permission boundaries.
3394 -> For application best practices, make your
decisions at synthesis time. Don't use cloud
3399.68 -> formation conditions and parameters. For
example, a common CDK practice of iterating
3404.96 -> over a list and instantiating a construct for each
isn't possible using CloudFormation expressions.
3413.84 -> Treat CloudFormation as an implementation
detail and not a language target.
3418.56 -> You're not writing CloudFormation templates,
you're writing code that happens to generate them.
3424 -> If you leave out resource names, CDK will generate
them for you. And it will do so in a way that
3428.48 -> won't cause problems when you end up refactoring
your code later. CDK does its best to keep you
3434.64 -> from losing data by defaulting to policies that
retain everything you create. But Cloud watch is
3439.84 -> expensive. Go through and set your own retention
policies. CDK also has helper methods that will
3446.72 -> empty an s3 bucket using a custom resource prior
to destroying a stack which is very useful.
3455.04 -> Consider keeping stateful resources like databases
in a separate stack from stateless resources. You
3462.72 -> can turn on termination protection for stateful
stacks, while keeping it off for stateless once.
3469.12 -> Stateful resources are more sensitive to
construct renaming, which is another reason
3473.2 -> to keep them in a separate stack. It reduces
risk when reorganizing your app later. Determine
3481.52 -> determinism is key to successful
CDK deployments. CDK context is a
3487.04 -> mechanism for recording a snapshot of the non
deterministic values coming from synthesis.
3494.56 -> This allows future synthesis operation
to produce the same exact template. non
3500.405 -> deterministic values results in using things like
a constructs from lookup where you're looking
3506.32 -> up an external resource. These from LOOKUP
values are cached in CDK context dot JSON.
3516.08 -> The grant convenience methods allow you
to greatly simplify the IAM process.
3522.24 -> Manually defining roles or using
predefined roles in your AWS account
3526.32 -> causes a big loss and flexibility
in how you design your applications.
3532.16 -> Service control policies and permission boundaries
are better alternatives to predefined roles.
3540.8 -> Another CDK best practice is to
create a stack for each environment.
3545.68 -> When you synthesize your application, the cloud
assembly created in the CDK dot out folder
3550.96 -> contains a separate template for each
environment. Your entire build is deterministic.
3559.28 -> Most of the level two constructs in CDK have
convenience methods to help in the creation of
3564.64 -> metrics, which you can easily use to generate
CloudWatch dashboards and alarms use them.
3574.48 -> Finally, there are a few more resources that
I'd like to call out. Free Code Camp has a
3579.92 -> great blog post about how to use CDK version two
to create a three tier serverless application.
3587.44 -> I have several posts on my blog related to
CDK but one in particular shows how much
3592.4 -> using a general purpose programming language
enables you to extend the CDK even further.
3598.64 -> In my open API specs from CDK. Without deploying
first article, I show how you can traverse an API
3606.08 -> gateways endpoint structure during synthesis to
output an open API spec first without deploying.
3614.48 -> Lastly, serverless stack framework is pretty
neat. It extends the CDK and enables local
3620.64 -> lamda development. It has a pretty neat console
for observability when doing development too.
3626.8 -> Definitely worth checking out
3632 -> if you made it this far through
the lesson, thanks for watching.
3635.44 -> Thanks. You can follow me on Twitter at marks
codes. And my other socials and my blog posts
3642.88 -> are located at marks dot codes. This was a
Free Code Camp CDK Crash Course. Thanks bye bye
Source: https://www.youtube.com/watch?v=T-H4nJQyMig