This is the AWS CDK v2 Developer Guide. The older CDK v1 entered maintenance on June 1, 2022 and ended support on June 1, 2023.
Tutorial: Create your first AWS CDK app
Get started with using the AWS Cloud Development Kit (AWS CDK) by creating your first CDK app.
Prerequisites
Before starting this tutorial, complete all set up steps in Getting started with the AWS CDK.
About this tutorial
In this tutorial, you will create and deploy a simple application on AWS using the AWS CDK. The application
consists of an AWS Lambda function that returns
a Hello World!
message when invoked. The function will be invoked through a Lambda function URL that serves as a dedicated HTTP(S) endpoint for
your Lambda function.
Through this tutorial, you will perform the following:
-
Create a CDK project using the AWS CDK Command Line Interface (AWS CDK CLI)
cdk init
command. -
Use constructs from the AWS Construct Library to define your Lambda function and Lambda function URL resources.
-
Use the CDK CLI to build your app, synthesize an AWS CloudFormation template, and deploy your CDK stack.
-
Interact with your deployed application on AWS.
-
Modify your application and view changes with the CDK CLI
cdk diff
command. -
Deploy your CDK stack to implement your changes.
-
Delete your CDK stack using the CDK CLI
cdk destroy
command.
Step 1: Create your CDK project
In this step, you create a new CDK project. A CDK project should be in its own directory, with its own local module dependencies.
To create a CDK project
-
From a starting directory of your choice, create and navigate to a directory named
hello-cdk
:$
mkdir hello-cdk && cd hello-cdk
Important
Be sure to name your project directory
hello-cdk
, exactly as shown here. The CDK CLI uses this directory name to name things within your CDK code. If you use a different directory name, you will run into issues during this tutorial. -
From the
hello-cdk
directory, initialize a new CDK project using the AWS CDK CLIcdk init
command. Specify theapp
template and your preferred programming language with the--language
option:
The cdk init
command creates a structure of files and folders within the
hello-cdk
directory to help organize the source code for your CDK app. This structure of
files and folders is called your CDK project. Take a moment to explore your CDK
project.
If you have Git installed, each project you create using cdk init
is also initialized
as a Git repository.
During project initialization, the CDK CLI creates a CDK app containing a single CDK stack.
The CDK app instance is created using the App
construct. The following is a portion of this code
from your CDK application file:
The CDK stack is created using the Stack
construct. The following is a portion of this
code from your CDK stack file:
Step 2: Build your CDK app
In most programming environments, you build or compile code after making changes. This isn't necessary with the AWS CDK since the CDK CLI will automatically perform this step. However, you can still build manually when you want to catch syntax and type errors. The following is an example:
Step 3: List the CDK stacks in your app
At this point, you should have a CDK app containing a single CDK stack. To verify, use the
CDK CLI cdk list
command to display your stacks. The output should display a single stack named
HelloCdkStack
:
$
cdk list
HelloCdkStack
If you don't see this output, verify that you are in the correct working directory of your project and try again. If you still don't see your stack, repeat Step 1: Create your CDK project and try again.
Step 4: Define your Lambda function
In this step, you import the aws_lambda
module from the AWS Construct Library
and use the Function
L2 construct.
Modify your CDK stack file as follows:
Let's take a closer look at the Function
construct. Like all constructs, the Function
class takes three parameters:
-
scope – Defines your
Stack
instance as the parent of theFunction
construct. All constructs that define AWS resources are created within the scope of a stack. You can define constructs inside of constructs, creating a hierarchy (tree). Here, and in most cases, the scope isthis
(self
in Python). -
Id – The logical ID of the
Function
within your AWS CDK app. This ID, plus a hash based on the function's location within the stack, uniquely identifies the function during deployment. The AWS CDK also references this ID when you update the construct in your app and re-deploy to update the deployed resource. Here, your logical ID isHelloWorldFunction
. Functions can also have a name, specified with thefunctionName
property. This is different from the logical ID. -
props – A bundle of values that define properties of the function. Here you define the
runtime
,handler
, andcode
properties.Props are represented differently in the languages supported by the AWS CDK.
-
In TypeScript and JavaScript,
props
is a single argument and you pass in an object containing the desired properties. -
In Python, props are passed as keyword arguments.
-
In Java, a Builder is provided to pass the props. There are two: one for
FunctionProps
, and a second forFunction
to let you build the construct and its props object in one step. This code uses the latter. -
In C#, you instantiate a
FunctionProps
object using an object initializer and pass it as the third parameter.
If a construct's props are optional, you can omit the
props
parameter entirely. -
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 if you want to change its defaults.
Step 5: Define your Lambda function URL
In this step, you use the addFunctionUrl
helper method of the Function
construct to
define a Lambda function URL. To output the value of this URL at deployment, you will create an AWS CloudFormation output using the
CfnOutput
construct.
Add the following to your CDK stack file:
Warning
To keep this tutorial simple, your Lambda function URL is defined without authentication. When deployed, this creates a publicly accessible endpoint that can be used to invoke your function. When you are done with this tutorial, follow Step 11: Delete your application to delete these resources.
Step 6: Synthesize a CloudFormation template
In this step, you prepare for deployment by synthesizing a CloudFormation template with the CDK CLI cdk
synth
command. This command performs basic validation of your CDK code, runs your CDK app, and
generates a CloudFormation template from your CDK stack.
If your app contains more than one stack, you must specify which stacks to synthesize. Since your app contains a single stack, the CDK CLI automatically detects the stack to synthesize.
If you don't synthesize a template, the CDK CLI will automatically perform this step when you deploy. However, we recommend that you run this step before each deployment to check for synthesis errors.
Before synthesizing a template, you can optionally build your application to catch syntax and type errors. For instructions, see Step 2: Build your CDK app.
To synthesize a CloudFormation template, run the following from the root of your project:
$
cdk synth
Note
If you receive an error like the following, verify that you are in the hello-cdk
directory
and try again:
--app is required either in command-line, in cdk.json or in ~/.cdk.json
If successful, the CDK CLI will output a YAML–formatted CloudFormation template to
stdout
and save a JSON–formatted template in the cdk.out
directory of your project.
The following is an example output of the CloudFormation template:
Resources: HelloWorldFunctionServiceRole
unique-identifier
: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: lambda.amazonaws.com Version: "2012-10-17" ManagedPolicyArns: - Fn::Join: - "" - - "arn:" - Ref: AWS::Partition - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/ServiceRole/Resource HelloWorldFunctionunique-identifier
: Type: AWS::Lambda::Function Properties: Code: ZipFile: " \ exports.handler = async function(event) { \ return { \ statusCode: 200, \ body: JSON.stringify('Hello World!'), \ }; \ }; \ " Handler: index.handler Role: Fn::GetAtt: - HelloWorldFunctionServiceRoleunique-identifier
- Arn Runtime: nodejs20.x DependsOn: - HelloWorldFunctionServiceRoleunique-identifier
Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/Resource HelloWorldFunctionFunctionUrlunique-identifier
: Type: AWS::Lambda::Url Properties: AuthType: NONE TargetFunctionArn: Fn::GetAtt: - HelloWorldFunctionunique-identifier
- Arn Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/FunctionUrl/Resource HelloWorldFunctioninvokefunctionurlunique-identifier
: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunctionUrl FunctionName: Fn::GetAtt: - HelloWorldFunctionunique-identifier
- Arn FunctionUrlAuthType: NONE Principal: "*" Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/invoke-function-url CDKMetadata: Type: AWS::CDK::Metadata Properties: Analytics: v2:deflate64:unique-identifier
Metadata: aws:cdk:path: HelloCdkStack/CDKMetadata/Default Condition: CDKMetadataAvailable Outputs: myFunctionUrlOutput: Value: Fn::GetAtt: - HelloWorldFunctionFunctionUrlunique-identifier
- FunctionUrl Conditions: CDKMetadataAvailable: Fn::Or: - Fn::Or: - Fn::Equals: - Ref: AWS::Region - af-south-1 - Fn::Equals: - Ref: AWS::Region - ap-east-1 - Fn::Equals: - Ref: AWS::Region - ap-northeast-1 - Fn::Equals: - Ref: AWS::Region - ap-northeast-2 - Fn::Equals: - Ref: AWS::Region - ap-south-1 - Fn::Equals: - Ref: AWS::Region - ap-southeast-1 - Fn::Equals: - Ref: AWS::Region - ap-southeast-2 - Fn::Equals: - Ref: AWS::Region - ca-central-1 - Fn::Equals: - Ref: AWS::Region - cn-north-1 - Fn::Equals: - Ref: AWS::Region - cn-northwest-1 - Fn::Or: - Fn::Equals: - Ref: AWS::Region - eu-central-1 - Fn::Equals: - Ref: AWS::Region - eu-north-1 - Fn::Equals: - Ref: AWS::Region - eu-south-1 - Fn::Equals: - Ref: AWS::Region - eu-west-1 - Fn::Equals: - Ref: AWS::Region - eu-west-2 - Fn::Equals: - Ref: AWS::Region - eu-west-3 - Fn::Equals: - Ref: AWS::Region - il-central-1 - Fn::Equals: - Ref: AWS::Region - me-central-1 - Fn::Equals: - Ref: AWS::Region - me-south-1 - Fn::Equals: - Ref: AWS::Region - sa-east-1 - Fn::Or: - Fn::Equals: - Ref: AWS::Region - us-east-1 - Fn::Equals: - Ref: AWS::Region - us-east-2 - Fn::Equals: - Ref: AWS::Region - us-west-1 - Fn::Equals: - Ref: AWS::Region - us-west-2 Parameters: BootstrapVersion: Type: AWS::SSM::Parameter::Value<String> Default: /cdk-bootstrap/unique-identifier
/version Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip] Rules: CheckBootstrapVersion: Assertions: - Assert: Fn::Not: - Fn::Contains: - - "1" - "2" - "3" - "4" - "5" - Ref: BootstrapVersion AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
Note
Every generated template contains an AWS::CDK::Metadata
resource by default. The AWS CDK team uses
this metadata to gain insight into AWS CDK usage and find ways to improve it. For details, including how to opt out of
version reporting, see Version reporting.
By defining a single L2 construct, the AWS CDK creates an extensive CloudFormation template containing your Lambda resources, along with the permissions and glue logic required for your resources to interact within your application.
Step 7: (Optional) Bootstrap your environment
For this tutorial, you will be deploying into your default
environment. This environment is configured
and bootstrapped during the getting started process.
If you want to deploy this application into another environment, you must specify the environment in your CDK code and bootstrap the environment. For instructions, see the following:
Step 8: Deploy your CDK stack
In this step, you use the CDK CLI cdk deploy
command to deploy your CDK stack. This
command retrieves your generated CloudFormation template and deploys it through AWS CloudFormation, which provisions your resources as
part of a CloudFormation stack.
From the root of your project, run the following. Confirm changes if prompted:
$
cdk deploy
✨ Synthesis time: 2.69s HelloCdkStack: start: Buildingunique-identifier
:current_account-current_region HelloCdkStack: success: Builtunique-identifier
:current_account-current_region HelloCdkStack: start: Publishingunique-identifier
:current_account-current_region HelloCdkStack: success: Publishedunique-identifier
:current_account-current_region This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening). Please confirm you intend to make the following modifications: IAM Statement Changes ┌───┬───────────────────────────────────────┬────────┬──────────────────────────┬──────────────────────────────┬───────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼───────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤ │ + │ ${HelloWorldFunction.Arn} │ Allow │ lambda:InvokeFunctionUrl │ * │ │ ├───┼───────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤ │ + │ ${HelloWorldFunction/ServiceRole.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │ └───┴───────────────────────────────────────┴────────┴──────────────────────────┴──────────────────────────────┴───────────┘ IAM Policy Changes ┌───┬───────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼───────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ + │ ${HelloWorldFunction/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │ └───┴───────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Do you wish to deploy these changes (y/n)?y
Similar to cdk synth
, you don't have to specify the AWS CDK stack since the app contains a single
stack.
During deployment, the CDK CLI displays progress information as your stack is deployed. When complete, you
can go to the AWS CloudFormation consoleHelloCdkStack
stack. You can also go to the Lambda console to view your HelloWorldFunction
resource.
When deployment completes, the CDK CLI will output your endpoint URL. Copy this URL for the next step. The following is an example:
... HelloCdkStack: deploying... [1/1] HelloCdkStack: creating CloudFormation changeset... ✅ HelloCdkStack ✨ Deployment time: 41.65s Outputs: HelloCdkStack.myFunctionUrlOutput = https://
<api-id>
.lambda-url.<Region>
.on.aws/ Stack ARN: arn:aws:cloudformation:Region
:account-id
:stack/HelloCdkStack/unique-identifier
✨ Total time: 44.34s
Step 9: Interact with your application on AWS
In this step, you interact with your application on AWS by invoking your Lambda function through the function URL.
When you access the URL, your Lambda function returns the Hello World!
message.
To invoke your function, access the function URL through your browser or from the command line. The following is an example:
$
curl https://
"Hello World!"%<api-id>
.lambda-url.<Region>
.on.aws/
Step 10: Modify your application
In this step, you modify the message that the Lambda function returns when invoked. You perform a diff using the
CDK CLI cdk diff
command to preview your changes and deploy to update your application. You then
interact with your application on AWS to see your new message.
Modify the myFunction
instance in your CDK stack file as follows:
Currently, your code changes have not made any direct updates to your deployed Lambda resource. Your code defines the desired state of your resource. To modify your deployed resource, you will use the CDK CLI to synthesize the desired state into a new AWS CloudFormation template. Then, you will deploy your new CloudFormation template as a change set. Change sets make only the necessary changes to reach your new desired state.
To preview your changes, run the cdk diff
command. The following is an example:
$
cdk diff
Stack HelloCdkStack Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff) Resources [~] AWS::Lambda::Function HelloWorldFunction HelloWorldFunctionunique-identifier
└─ [~] Code └─ [~] .ZipFile: ├─ [-] exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; └─ [+] exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; ✨ Number of stacks with differences: 1
To create this diff, the CDK CLI queries your AWS account account for the latest AWS CloudFormation template for the
HelloCdkStack
stack. Then, it compares the latest template with the template it just synthesized
from your app.
To implement your changes, run the cdk deploy
command. The following is an example:
$
cdk deploy
✨ Synthesis time: 2.12s HelloCdkStack: start: Buildingunique-identifier
:current_account-current_region HelloCdkStack: success: Builtunique-identifier
:current_account-current_region HelloCdkStack: start: Publishingunique-identifier
:current_account-current_region HelloCdkStack: success: Publishedunique-identifier
:current_account-current_region HelloCdkStack: deploying... [1/1] HelloCdkStack: creating CloudFormation changeset... ✅ HelloCdkStack ✨ Deployment time: 26.96s Outputs: HelloCdkStack.myFunctionUrlOutput = https://unique-identifier
.lambda-url.<Region>
.on.aws/ Stack ARN: arn:aws:cloudformation:Region
:account-id
:stack/HelloCdkStack/unique-identifier
✨ Total time: 29.07s
To interact with your application, repeat Step 9: Interact with your application on AWS. The following is an example:
$
curl https://
"Hello CDK!"%<api-id>
.lambda-url.<Region>
.on.aws/
Step 11: Delete your application
In this step, you use the CDK CLI cdk destroy
command to delete your application. This command
deletes the CloudFormation stack associated with your CDK stack, which includes the resources you created.
To delete your application, run the cdk destroy
command and confirm your request to delete the
application. The following is an example:
$
cdk destroy
Are you sure you want to delete: HelloCdkStack (y/n)?y
HelloCdkStack: destroying... [1/1] ✅ HelloCdkStack: destroyed
Next steps
Congratulations! You've completed this tutorial and have used the AWS CDK to successfully create, modify, and delete resources in the AWS Cloud. You're now ready to begin using the AWS CDK.
To learn more about using the AWS CDK in your preferred programming language, see Work with the AWS CDK library.
For additional resources, see the following:
-
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.
-
Visit Construct Hub
to discover constructs created by AWS and others. -
Explore Examples
of using the AWS CDK.
The AWS CDK is an open-source project. To contribute, see to Contributing to the AWS Cloud Development Kit (AWS CDK)