DEV Community

kkkensuke
kkkensuke

Posted on • Updated on

Starting AWS CDK with TypeScript. AWS Lambda + API Gateway

Environment

  • AWS Cloud9

  • CDK Version : 2.63.2

Image Diagram

I would like to create a demo of a Lambda service that can be called via Amazon API Gateway using AWS CDK. The demo image is below.

Image description
So let's get your hands dirty!

Creating a new CDK Project

We will be using AWS Cloud9 as our working environment. As the title says, we will create a project using TypeScript.
First, create a directory for the project we will use this time.

mkdir cdk-workshop && cd cdk-workshop
Enter fullscreen mode Exit fullscreen mode

Create a TypeScript CDK project. (This will take a bit of time.)

cdk init sample-app --language typescript
Enter fullscreen mode Exit fullscreen mode

You will see useful cdk commands like this. We will use these later.

## Useful commands

* `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
Enter fullscreen mode Exit fullscreen mode

You will see the project directory created as shown in the figure below.

Image description

  • lib/cdk-workshop-stack.ts:This file defines the main stack of the CDK application. This file is the main file to edit.

  • bin/cdk-workshop.ts:This will be the entry point for the CDK application, loading the stack defined in lib/cdk-workshop-stack.ts.

  • cdk.json:It defines how to RUN the app for the toolkit. In this case, it is written as npx ts-node bin/cdk-workshop.ts.

Creating Lambda Function, API Gateway

Clean up unnecessary code and deploy first time

The first step is to clean up some existing code that is not needed.
Open lib/cdk-workshop-stack.ts and clean up as follows, since SQS Queue and SNS topic are not needed for this demo.

import * as cdk from 'aws-cdk-lib';

export class CdkWorkshopStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // nothing here!
  }
}
Enter fullscreen mode Exit fullscreen mode

The contents of the CDK are empty, but the AWS CloudFormation template is created (synthesize) from the contents described in the CDK, and when deploying to an AWS environment, even if the CDK is used, the CloudFormation template is deployed in the form of a CloudFormation template.

cdk synth
Enter fullscreen mode Exit fullscreen mode

The CloudFormation template has been created in the checkout folder.

Next, you can install a stack called "bootstrap" only for the first deployment. This stack contains resources used by the CDK Toolkit, such as the S3 bucket that holds the CloudFormation templates.

cdk bootstrap
Enter fullscreen mode Exit fullscreen mode

Now, let's deploy it!

cdk deploy
Enter fullscreen mode Exit fullscreen mode

If you look at the CloudFormation console after a successful deployment, you see that the stack you created exists! (It means that the template created with cdk synth has been applied)

Image description

Creating Hello Lambda function

Let's write the code for the Lambda function. We will do the following

  1. Create a lambda directory in the same hierarchy as the bin and lib directories.

  2. If a .gitignore file exists, add !lambda/*.js in the file.

  3. Create the file lambda/hello.js and write the following code

exports.handler = async function(event) {
  console.log("request:", JSON.stringify(event, undefined, 2));
  return {
    statusCode: 200,
    headers: { "Content-Type": "text/plain" },
    body: `Hello, CDK! You've hit ${event.path}\n`
  };
};
Enter fullscreen mode Exit fullscreen mode

Add the created Lambda function to the stack

Add the lambda function you just created to the stack. import the CDK Library for Lambda, which is also needed to add the Lambda stack.

import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class CdkWorkshopStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // defines an AWS Lambda resource
    const hello = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_16_X,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'hello.handler'
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

A few additional details about the above code

  • The NodeJS (version 16) runtime is used.

  • The handler of the Lambda function is written to be read from the lambda directory.

  • The name of the handler is also the same as the handler in the created function.

Before deploying, take a look at the differences in the code. You can see the differences.

cdk diff
Enter fullscreen mode Exit fullscreen mode

Deploy

cdk deploy
Enter fullscreen mode Exit fullscreen mode

If you look at the console after deploy, you will see that the hello.js Lambda function has been created and that the asset folder has also been created in the S3 bucket.

Test

To test the created Lambda function, create and run a test using the "Amazon API Gateway AWS Proxy" template from the Lambda console.

Image description
Looks it works!

Image description

Creating a API Gateway

Next, we will create an API Gateway, a service that publishes a public endpoint on the Internet, and connect the API Gateway to Lambda so that it can receive requests from browsers and other devices.
The following is a code of the API Gateway.

import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigw from 'aws-cdk-lib/aws-apigateway';

export class CdkWorkshopStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // defines an AWS Lambda resource
    const hello = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_16_X,
      code: lambda.Code.fromAsset('lambda'),
      handler: 'hello.handler'
    });

    // defines an API Gateway REST API resource backed by "hello" function.
    new apigw.LambdaRestApi(this, 'Endpoint', {
      handler: hello
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Let's look at the differences in the stack.

cdk diff
Enter fullscreen mode Exit fullscreen mode

You can see that a lot of resources are created at once, which shows the convenience of the CDK.

Resources
[+] AWS::ApiGateway::RestApi Endpoint EndpointEEF1FD8F 
[+] AWS::ApiGateway::Deployment Endpoint/Deployment EndpointDeployment318525DA5f8cdfe532107839d82cbce31f859259 
[+] AWS::ApiGateway::Stage Endpoint/DeploymentStage.prod EndpointDeploymentStageprodB78BEEA0 
[+] AWS::ApiGateway::Resource Endpoint/Default/{proxy+} Endpointproxy39E2174E 
[+] AWS::Lambda::Permission Endpoint/Default/{proxy+}/ANY/ApiPermission.CdkWorkshopStackEndpoint018E8349.ANY..{proxy+} EndpointproxyANYApiPermissionCdkWorkshopStackEndpoint018E8349ANYproxy747DCA52 
[+] AWS::Lambda::Permission Endpoint/Default/{proxy+}/ANY/ApiPermission.Test.CdkWorkshopStackEndpoint018E8349.ANY..{proxy+} EndpointproxyANYApiPermissionTestCdkWorkshopStackEndpoint018E8349ANYproxy41939001 
[+] AWS::ApiGateway::Method Endpoint/Default/{proxy+}/ANY EndpointproxyANYC09721C5 
[+] AWS::Lambda::Permission Endpoint/Default/ANY/ApiPermission.CdkWorkshopStackEndpoint018E8349.ANY.. EndpointANYApiPermissionCdkWorkshopStackEndpoint018E8349ANYE84BEB04 
[+] AWS::Lambda::Permission Endpoint/Default/ANY/ApiPermission.Test.CdkWorkshopStackEndpoint018E8349.ANY.. EndpointANYApiPermissionTestCdkWorkshopStackEndpoint018E8349ANYB6CC1B64 
[+] AWS::ApiGateway::Method Endpoint/Default/ANY EndpointANY485C938B 
Enter fullscreen mode Exit fullscreen mode

now, deploy it.

cdk deploy
Enter fullscreen mode Exit fullscreen mode

You will see the following URL endpoints as output.

Outputs:
CdkWorkshopStack.Endpoint8024A810 = https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod/
Enter fullscreen mode Exit fullscreen mode

If you hit this endpoint with the crul command, you'll see the response come back from the Lambda function! You can also try it from your browser.

$ curl https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod/
Hello, CDK! You've hit /
Enter fullscreen mode Exit fullscreen mode

Summary

This time, we created a simple backend app using CDK with API Gateway + Lambda configuration.
Compared to the case where you have to configure it in the console or by writing CloudFormation, it seems that you can complete the creation in a much shorter time. I would like to continue publishing the CDK series in the future.

Finally, if you want to delete the app you created this time, the following command will clean it up nicely.

cdk destroy
Enter fullscreen mode Exit fullscreen mode

Reference

https://cdkworkshop.com/20-typescript.html

Thank you!

Top comments (0)