Nxで作ったNestjsのアプリをServerless FrameworkでAWS Lambdaにデプロイする

この記事は、「AWS LambdaとServerless Advent Calendar 2020」4日目です。 Nxを使うことで、NestjsやReactなどのアプリケーションをモノレポで管理することができます。また、 […]

広告ここから
広告ここまで

目次

    この記事は、「AWS LambdaとServerless Advent Calendar 2020」4日目です。

    Nxを使うことで、NestjsやReactなどのアプリケーションをモノレポで管理することができます。また、Serverless Frameworkを使うことで、NestjsやExpressなどのアプリケーションについてもより簡単にデプロイ・運用することができます。

    ただし、この2つを組み合わせて使うにはすこし工夫が必要です。ということで今回はこの組み合わせ方について紹介します。

    LambdaでNestjsを動かす準備とServerless FW系リソースを追加する

    まずは必要なライブラリを追加しましょう。

    $ yarn add serverless-lambda-nestjs
    
    // For Serverless Framework
    $ yarn add -D serverless-layers 
    
    // For TypeScript
    $ yarn add -D @types/aws-lambda

    AWS Lambdaのハンドラーを main.tsに実装する

    NxでNestjsのアプリケーションを作成した場合、エントリーポイントはsrc/main.tsで固定されます。これは設定ファイルを変更することで調整できますが、今回はそのまま使います。

    AWS Lambdaで動かす場合も、nx serveでローカル実行する場合にも同じファイルを使うことになりますので、どちらでも動くように調整します。

    import { Logger } from '@nestjs/common';
    import { NestFactory } from '@nestjs/core';
    import { ServerlessNestjsApplicationFactory } from 'serverless-lambda-nestjs';
    import { APIGatewayProxyHandler } from 'aws-lambda';
    import { AppModule } from './app/app.module';
    
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      const globalPrefix = 'api';
      app.setGlobalPrefix(globalPrefix);
      app.enableCors({
        origin: '*',
        allowedHeaders: 'Origin, X-Requested-With, Content-Type, Accept',
      });
      const port = process.env.PORT || 3333;
      await app.listen(port, () => {
        Logger.log('Listening at http://localhost:' + port + '/' + globalPrefix);
      });
    }
    
    // Run Nestjs application locally
    if (process.env.NX_CLI_SET) {
      bootstrap();
    }
    
    // Run Nestjs application in AWS Lambda
    export const handler: APIGatewayProxyHandler = async (event, context) => {
      const app = new ServerlessNestjsApplicationFactory<AppModule>(
        AppModule,
        {
            // NestFactory.create's option object
            cors: {
              origin: '*',
              allowedHeaders: 'Origin, X-Requested-With, Content-Type, Accept',
            },
        }
      );
      const result = await app.run(event, context);
      return result;
    };

    NX_CLI_SET はNx CLIを使った場合に付与される環境変数です。ということで、この環境変数が含まれる場合は一般的なNestjsアプリケーションとして起動します。また、handler関数をexportしてありますので、これを利用するAWS Lambdaの関数を用意すれば、Lambdaの中でもNestjsを動かすことができます。

    serverless.yaml をプロジェクトルートに配置する

    続いてServerless FrameworkのYAMLファイルを作成します。

    NxがビルドするNestjsのアプリは、/<PROJECT_ROOT>/dist以下に配置されます。そのため、Nestjsのアプリがあるディレクトリではなく、ルートに配置します。

    service: nx-nestjs-api
    
    custom:
      prune:
        automatic: true
        number: 3
      serverless-layers:
        dependenciesPath: ./package.json
    
    provider:
      name: aws
      runtime: nodejs12.x
      region: us-east-1
      profile: default
      stage: development
    plugins:
      - serverless-layers
    
    package:
      individually: true
      include:
        - dist/apps/api/**
      exclude:
        - '**'
    
    functions:
      index:
        handler: dist/apps/api/main.handler
        events:
        - http:
            cors: true
            path: '/'
            method: any
        - http:
            cors: true
            path: '{proxy+}'
            method: any

    Build and Deploy

    あとはデプロイするだけです。distを指定していますので、かならずデプロイ前にビルドしましょう。

    # Build Nestjs applciation
    $ yarn build
    
    # Deploy to AWS
    $ serverless deploy

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark