Today we are going to look into the Deployment of a Server-less Nodejs application deployed with AWS Lambda and the requests to resources are being handled by the AWS APi gateway.
So , our resources are private and are not exposed to public and we also want to offload the authentication process to a separate handler.
We will use aws cdk to deploy our resources. You can look here on how to setup CDK https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html.
Pre-requisites:
Make sure that you have aws cli credentials and are setup to your local env to be picked up by the cdk.
Lets go step by step:
Configure your CDK and init the app with cdk init app --language typescript , this will create a project folder for you and respective lib and bin directories. While the lib directory contains definition of the stacks to be deployed, the bin directory contains the apps that will finally be deployed to AWS.
Lets look at a sample code, it integrates with API gateway takes requests and also deploys a lambda that gets triggered by the event from SQS. The code below is from lib directory(MyFirstStack.ts).
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda'
import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as lambdaEventSources from 'aws-cdk-lib/aws-lambda-event-sources';
// import * as sqs from 'aws-cdk-lib/aws-sqs';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
declare const dlQueue: sqs.Queue;
export class MyFirstStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const requestHandlerLambda = new lambda.Function(this,'myFirstLambda',{
runtime:lambda.Runtime.NODEJS_20_X,
handler: 'lambda.handler',
code:lambda.Code.fromAsset('lambda-code-folder')
});
// Define the API Gateway resource
const api = new apigateway.LambdaRestApi(this, 'Content-API', {
handler: requestHandlerLambda,
});
const dlQueue = new sqs.Queue (this,'DLQ-MyQueue')
const deadLetterQueue: sqs.DeadLetterQueue = {
maxReceiveCount: 10,
queue: dlQueue,
};
const myQueueSQS = new sqs.Queue(this,'MyQueue',{
receiveMessageWaitTime:cdk.Duration.seconds(10),
visibilityTimeout:cdk.Duration.seconds(600),
deadLetterQueue:deadLetterQueue
})
const queueEventSource = new lambdaEventSources.SqsEventSource(myQueueSQS)
const anotherLambdaFunction = new lambda.Function(this,'AnotherLambdaFunction',{
runtime:lambda.Runtime.NODEJS_20_X,
handler: 'lambda.handler',
code:lambda.Code.fromAsset('local_folder_name'),
});
anotherLambdaFunction.addEventSource(queueEventSource)
}
}
Lets look at the bin directory logic
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyFirstStack } from '../lib/my-first-stack';
const app = new cdk.App();
new MyFirstStack(app, 'MyFirstStack', {
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */
/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },
/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
});
Finally you deploy your stack. To deploy , you will do
cdk synth (to synthesise and see if everything is ok)
cdk deploy ( to deploy the app)
When the deployment starts , it will create a stack and list all the associated resources in the Cloud-formation Console. This will take some time to deploy the resources and finally make it live and also it will print you the api-gateway endpoint as output.
Things to take care of:
Make sure that you also create/upload the layer if you have installed additional plugins. You can follow the installation steps here. https://docs.aws.amazon.com/lambda/latest/dg/packaging-layers.html
Attach the layer in your lambda. For any new plugins updated , make sure you update the layer and link the update the version in lambda.
There are additional steps :
lambda authorizer(to validate requests and secure endpoints).
Here is the sample code to put in lambda authorizer for validation of Bearer Token . The resource here signifies api gaeway resource ARN .
b. Masking the api gateway endpoint. You can do this via creating custom endpoint and creating a cname mapping in your DNS settings. Make sure you also create a SSL certificate in the AWS certificate manager.
Conclusion:
This way one can deploy aws api gateway,lambda,sqs stack via CDK. Let us know if you have any questions or if you need any help in your setup.