Skip to content

Commit

Permalink
deploy api as AWS Lambda using AWS CDK
Browse files Browse the repository at this point in the history
  • Loading branch information
apalchys committed Jul 19, 2024
1 parent a621a23 commit 4e0eb52
Show file tree
Hide file tree
Showing 10 changed files with 1,026 additions and 5 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ lerna-debug.log*
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml

# AWS CDK
cdk.context.json
cdk.out
46 changes: 44 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[travis-url]: https://travis-ci.org/nestjs/nest
[linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux
[linux-url]: https://travis-ci.org/nestjs/nest

<p align="center">A progressive <a href="http://nodejs.org" target="blank">Node.js</a> framework for building efficient and scalable server-side applications, heavily inspired by <a href="https://angular.io" target="blank">Angular</a>.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
Expand Down Expand Up @@ -60,6 +60,48 @@ $ npm run test:e2e
$ npm run test:cov
```

## Deploy

Deployment is done using AWS CDK. You can find deployment configuration in `./deploy` folder.

To run deployment, you need to have AWS credentials set up on your machine.

Run deployment if you have AWS credentials in your environment variables:

```bash
$ npm run build
$ npm run deploy
```

If you set up AWS Profile in your `~/.aws/credentials` file, you can run deployment with the following command:

```bash
$ npm run build
$ npm run deploy -- --profile <profile-name>
```

When deployment is done, you can find the url of deployed API in the output of the command.

```
Outputs:
nodejs-aws-cart-api.Url = <url>
```

#### How it works

When you run `npm run deploy`, cdk bundles all your code into a single js file using `esbuild`, uploads it to S3, generates CloudFormation template representing the change and deploying it to the AWS account.

### Notes

Due to how NestJS is written, some modules are marked as "external" and are not included in the final bundle:

- @nestjs/microservices
- @nestjs/websockets
- class-transformer
- class-validator

If you want to use any of this modules, you need to add them to package.json, install and remove from `deploy/Stack.ts`.

## Support

Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
Expand All @@ -72,4 +114,4 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors

## License

Nest is [MIT licensed](LICENSE).
Nest is [MIT licensed](LICENSE).
10 changes: 10 additions & 0 deletions cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"app": "npx ts-node deploy/App.ts",
"context": {
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
"@aws-cdk/core:stackRelativeExports": true,
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
"@aws-cdk/core:target-partitions": ["aws", "aws-cn"]
}
}
11 changes: 11 additions & 0 deletions deploy/App.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as cdk from 'aws-cdk-lib';

import { Stack } from './Stack';

const app = new cdk.App({});

new Stack(app, 'nodejs-aws-cart-api', {
env: {
region: 'eu-central-1',
},
});
37 changes: 37 additions & 0 deletions deploy/Stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as nodejs from 'aws-cdk-lib/aws-lambda-nodejs';
import { Construct } from 'constructs';

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

const server = new nodejs.NodejsFunction(this, 'server', {
functionName: 'nodejs-aws-cart-api',
entry: 'dist/main.lambda.js',
timeout: cdk.Duration.seconds(30),
memorySize: 1024,
runtime: lambda.Runtime.NODEJS_20_X,
environment: {
RDS_CONNECTION_URL: '<UPDATED_ME>',
},
bundling: {
externalModules: [
'@nestjs/microservices',
'@nestjs/websockets',
'class-transformer',
'class-validator',
],
},
});

// exposes the lambda function via HTTP URL
const { url } = server.addFunctionUrl({
authType: lambda.FunctionUrlAuthType.NONE,
cors: { allowedOrigins: ['*'] },
});

new cdk.CfnOutput(this, 'Url', { value: url });
}
}
Loading

0 comments on commit 4e0eb52

Please sign in to comment.