Your first AWS CDK app
You've read Getting started with the AWS CDK? Great! Now let's see how it feels to work with the AWS CDK by building the simplest possible AWS CDK app. In this tutorial you'll learn about the structure of a AWS CDK project, how to work with the AWS Construct Library, and how to use the AWS CDK Toolkit command-line tool.
The standard AWS CDK development workflow is similar to the workflow you're already familiar with as a developer, just with a few extra steps to synthesize your stack to an AWS CloudFormation template and deploy it.
-
Create the app from a template provided by the AWS CDK
-
Add code to the app to create resources within stacks
-
Build the app (optional; the AWS CDK Toolkit will do it for you if you forget)
-
Synthesize one or more stacks in the app to create an AWS CloudFormation template
-
Deploy one or more stacks to your AWS account
The build step catches syntax and type errors. The synthesis step catches logical errors in defining your AWS resources. The deployment may find permission issues. As always, you go back to the code, find the problem, fix it, then build, synthesize and deploy again.
Don't forget to keep your AWS CDK code under version control!
This tutorial walks you through creating and deploying a simple AWS CDK app, from initializing the project to deploying the resulting AWS CloudFormation template. The app contains one stack, which contains one resource: an Amazon S3 bucket.
We'll also show what happens when you make a change and re-deploy, and how to clean up when you're done.
Create the app
Each AWS CDK app should be in its own directory, with its own local module dependencies. Create a new directory for your app. Starting in your home directory, or another directory if you prefer, issue the following commands.
mkdir hello-cdk cd hello-cdk
Be sure to name your project directory hello-cdk
, exactly
as shown here. The AWS CDK project template uses the directory name to name
things in the generated code, so if you use a different name, some of the code in
this
tutorial won't work.
Now initialize the app using the cdk init command, specifying the desired template ("app") and programming language.
cdk init
TEMPLATE
--languageLANGUAGE
That is:
If you don't specify a template, the default is "app," which is the one we wanted anyway, so technically you can leave it out and save four keystrokes.
The cdk init command creates a number of files and folders inside the
hello-cdk
directory to help you organize the source code for your AWS CDK
app. Take a moment to explore. The structure of a basic app is all there; you'll fill
in the
details as you progress in this tutorial.
If you have Git installed, each project you create using cdk init is also initialized as a Git repository. We'll ignore that for now, but it's there when you need it.
Build the app
In most programming environments, after making changes to your code, you'd build (compile) it. This isn't strictly necessary with the AWS CDK—the Toolkit does it for you so you can't forget. But you can still build manually whenever you want to catch syntax and type errors. For reference, here's how.
If your project was created with an older version of the AWS CDK Toolkit, it may not automatically build when you run it. If changes you make in your code fail to be reflected in the synthesized template, try a manual build. Make sure you are using the latest available version of the AWS CDK for this tutorial.
List the stacks in the app
Just to verify everything is working correctly, list the stacks in your app.
cdk ls
If you don't see HelloCdkStack
, make sure you named your app's
directory hello-cdk
. If you didn't, go back to Create the app and try again.
Add an Amazon S3 bucket
At this point, your app doesn't do anything useful because the stack doesn't define any resources. Let's define an Amazon S3 bucket.
Install the Amazon S3 package from the AWS Construct Library.
Next, define an Amazon S3 bucket in the stack using an L2 construct, the Bucket class.
Bucket
is the first construct we've seen, so let's take a closer look. Like
all constructs, the Bucket
class takes three parameters.
-
scope: Tells the bucket that the stack is its parent: it is defined within the scope of the stack. You can define constructs inside of constructs, creating a hierarchy (tree).
-
Id: The logical ID of the Bucket within your AWS CDK app. This (plus a hash based on the bucket's location within the stack) uniquely identifies the bucket across deployments so the AWS CDK can update it if you change how it's defined in your app. Buckets can also have a name, which is separate from this ID (it's the
bucketName
property). -
props: A bundle of values that define properties of the bucket. Here we've defined only one property:
versioned
, which enables versioning for the files in the bucket.
All constructs take these same three arguments, so it's easy to stay oriented as you learn about new ones. And as you might expect, you can subclass any construct to extend it to suit your needs, or just to change its defaults.
If all a construct's props are optional, you can omit the third parameter entirely.
It's interesting to take note of how props are represented in the different supported languages.
-
In TypeScript and JavaScript,
props
is a single argument and you pass in an object containing the desired properties. -
In Python, props are represented as keyword arguments.
-
In Java, a Builder is provided to pass the props. (Two, actually; one for
BucketProps
, and a second forBucket
to let you build the construct and its props object in one step. This code uses the latter.) -
In C#, you instantiate a
BucketProps
object using an object initializer and pass it as the third parameter.
Synthesize an AWS CloudFormation template
Synthesize an AWS CloudFormation template for the app, as follows.
cdk synth
If your app contained more than one stack, you'd need to specify which stack(s) to synthesize. But since it only contains one, the Toolkit knows you must mean that one.
If you received an error like --app is required...
, it's probably because
you are running the command from a subdirectory. Navigate to the main app directory
and try
again.
The cdk synth
command executes your app, which causes the resources defined
in it to be translated to an AWS CloudFormation template. The displayed output of
cdk synth
is
a YAML-format template; our app's output is shown below. The template is also saved
in the
cdk.out
directory in JSON format.
Resources: MyFirstBucketB8884501: Type: AWS::S3::Bucket Properties: VersioningConfiguration: Status: Enabled UpdateReplacePolicy: Retain DeletionPolicy: Retain Metadata: aws:cdk:path: HelloCdkStack/MyFirstBucket/Resource CDKMetadata: Type: AWS::CDK::Metadata Properties: Modules: aws-cdk=1.XX.X,@aws-cdk/aws-events=1.XX.X,@aws-cdk/aws-iam=1.XX.X,@aws-cdk/aws-kms=1.XX.X,@aws-cdk/aws-s3=1.XX.X,@aws-cdk/cdk-assets-schema=1.XX.X,@aws-cdk/cloud-assembly-schema=1.XX.X,@aws-cdk/core=1.XX.X,@aws-cdk/cx-api=1.XX.X,@aws-cdk/region-info=1.XX.X,jsii-runtime=node.js/vXX.XX.X
Even if you aren't very familiar with AWS CloudFormation, you should be able to find
the definition for
an AWS::S3::Bucket
and see how the versioning configuration was translated.
Every generated template contains a AWS::CDK::Metadata
resource by default.
The AWS CDK team uses this metadata to gain insight into how the AWS CDK is used,
so we can
continue to improve it. For details, including how to opt out of version reporting,
see
Version reporting.
The cdk synth
generates a perfectly valid AWS CloudFormation template. You could take it
and deploy it using the AWS CloudFormation console. But the AWS CDK Toolkit also has
that feature
built-in.
Deploying the stack
To deploy the stack using AWS CloudFormation, issue:
cdk deploy
As with
cdk synth
, you don't need to specify the name of the stack since there's only
one in the app.
It is optional (though good practice) to synthesize before deploying. The AWS CDK synthesizes your stack before each deployment.
If your code changes have security implications, you'll see a summary of these, and be asked to confirm them before deployment proceeds.
cdk deploy
displays progress information as your stack is deployed. When it's
done, the command prompt reappears. You can go to the AWS CloudFormation consoleHelloCdkStack
. You'll also find MyFirstBucket
in
the Amazon S3 console.
You've deployed your first stack using the AWS CDK—congratulations! But that's not all there is to the AWS CDK.
Modifying the app
The AWS CDK can update your deployed resources after you modify your app. Let's make
a
couple of changes to our bucket. First, we'll enable public read access, so people
out in the
world can access the files we store in the bucket. We also want to be able to delete
the
bucket automatically when we delete the stack, so we'll change its RemovalPolicy
.
Now we'll use the cdk diff
command to see the differences between what's
already been deployed, and the app as it stands right now.
cdk diff
The AWS CDK
Toolkit queries your AWS account for the current AWS CloudFormation template for the
hello-cdk
stack, and compares it with the template it just synthesized
from your app. The Resources section of the output should look like the following.
Stack HelloCdkStack
IAM Statement Changes
┌───┬────────────────────────┬────────┬──────────────┬───────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼────────────────────────┼────────┼──────────────┼───────────┼───────────┤
│ + │ ${MyFirstBucket.Arn}/* │ Allow │ s3:GetObject │ * │ │
└───┴────────────────────────┴────────┴──────────────┴───────────┴───────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Resources
[+] AWS::S3::BucketPolicy MyFirstBucket/Policy MyFirstBucketPolicy3243DEFD
[~] AWS::S3::Bucket MyFirstBucket MyFirstBucketB8884501
├─ [~] DeletionPolicy
│ ├─ [-] Retain
│ └─ [+] Delete
└─ [~] UpdateReplacePolicy
├─ [-] Retain
└─ [+] Delete
The diff indicates two things. First, that the stack has a new IAM policy statement
that
grants everyone (principal *
) read access (s3:GetObject
action) to
our bucket. Note that we didn't need to create this statement; the AWS CDK did it
for us. All we
needed to do was set the publicReadAccess
property when instantiating the
bucket.
It's informative to look at the output of cdk synth here and see the twenty additional lines of AWS CloudFormation template that the AWS CDK generated for us when we changed one property of our bucket.
Besides the new policy, we can also see the DeletionPolicy
property is set to
Delete
, enabling the bucket to be deleted when its stack is deleted. The
UpdateReplacePolicy
is also changed to cause the bucket to be deleted if it
were to be replaced with a new one.
Don't be confused by the difference between RemovalPolicy
in your AWS CDK app
and DeletionPolicy
in the resulting AWS CloudFormation template. The AWS CDK calls it
RemovalPolicy
because its semantics are slightly different from AWS CloudFormation's
DeletionPolicy
: the AWS CDK default is to retain the bucket when the stack is
deleted, while AWS CloudFormation's default is to delete it. See Removal policies for
further details.
You can also see that the bucket isn't going to be replaced, but will be updated with the new properties.
Now let's deploy.
cdk deploy
The AWS CDK warns you about the security policy change we previously saw in the diff. Enter y to approve the changes and deploy the updated stack. The Toolkit updates the bucket configuration as you requested.
HelloCdkStack: deploying... HelloCdkStack: creating CloudFormation changeset... 1/1 | 8:39:43 AM | UPDATE_COMPLETE | AWS::S3::Bucket | MyFirstBucket (MyFirstBucketB8884501) 1/1 | 8:39:44 AM | UPDATE_COMPLETE_CLEA | AWS::CloudFormation::Stack | HelloCdkStack 2/1 | 8:39:45 AM | UPDATE_COMPLETE | AWS::CloudFormation::Stack | HelloCdkStack ✅ HelloCdkStack Stack ARN: arn:aws:cloudformation:REGION:ACCOUNT:stack/HelloCdkStack/ID
Destroying the app's resources
Now that you're done with the quick tour, destroy your app's resources to avoid incurring any costs from the bucket you created, as follows.
cdk destroy
Enter y to approve the changes and delete any stack resources.
This wouldn't have worked if we hadn't changed the bucket's RemovalPolicy
!
Instead, the stack deletion would complete successfully, and the bucket would become
orphaned (no longer associated with the stack).
If the bucket still exists after you delete the stack, it probably means you put something in it. AWS CloudFormation won't delete buckets with files in them. Delete the files and try again.
Next steps
Where do you go now that you've dipped your toes in the AWS CDK?
-
Try the CDK Workshop
for a more in-depth tour involving a more complex project. -
See the API reference to begin exploring the CDK constructs available for your favorite AWS services.
-
Dig deeper into concepts like Environments, Assets, Permissions, Runtime context, Parameters, and Escape hatches.
-
Explore Examples
of using the AWS CDK.
The AWS CDK is an open-source project. Want to contribute