使用AWS CDK部署Nestjs项目

发布于 2025-01-28 23:14:07 字数 2779 浏览 2 评论 0原文

我有一个简单的Nestjs + Apollo Server + GraphQl项目。

您可以在这里找到该项目: https://github.com/github.com/gabeshin/gabeshin/nestjs-graphql-sample

这是问题:

  • 我想使用AWS CDK部署示例项目,但是AppSync的查询无法正常工作。
  • 我搜索了Web以寻求类似的实现,但是我很难找到一个使用AppSync使用Nestjs Framework的项目。
  • 当我从部署的AppSync API发送GraphQl查询时,我会收到错误类型unabletoAssumerolevalidationError

我认为我对AWS基础架构的缺乏知识正在引起问题,我需要一些帮助。

这是CDK代码:

        const dependenciesLayer = new LayerVersion(this, 'DependenciesLayer', {
            code: new AssetCode('modules/nestjs-graphql-template/node_modules'),
            compatibleRuntimes: [Runtime.NODEJS_14_X, Runtime.NODEJS_16_X],
        });

        const testLambda = new Function(this, 'TestHandler', {
            runtime: Runtime.NODEJS_16_X,
            code: new AssetCode('modules/nestjs-graphql-template/dist'),
            handler: 'index.handler',
            layers: [dependenciesLayer],
        });

        const api = new CfnGraphQLApi(this, 'TestApi', {
            name: 'TestApi',
            authenticationType: 'API_KEY',
        });

        const schemafile = fs.readFileSync(
            'modules/nestjs-graphql-template/schema.graphql'
        );

        const schema = new CfnGraphQLSchema(this, 'MyGraphqlSchema', {
            apiId: api.attrApiId,
            definition: schemafile.toString(),
        });

        const dataSource = new CfnDataSource(this, 'TestDataSource', {
            apiId: api.attrApiId,
            name: 'TestDataSource',
            type: 'AWS_LAMBDA',
            lambdaConfig: {
                lambdaFunctionArn: testLambda.functionArn,
            },
        });

index.ts

import { Server } from 'http';
import { Context } from 'aws-lambda';
import { createServer, proxy, Response } from 'aws-serverless-express';
import * as express from 'express';
import { createApp } from 'src/main';

let cachedServer: Server;

async function bootstrap(): Promise<Server> {
  const expressApp = express();

  const app = await createApp(expressApp);
  await app.init();

  return createServer(expressApp);
}

export async function handler(event: any, context: Context): Promise<Response> {
  if (!cachedServer) {
    const server = await bootstrap();
    cachedServer = server;
  }

  return proxy(cachedServer, event, context, 'PROMISE').promise;
}

结果

”在此处输入图像描述

I have a simple NestJS + Apollo Server + GraphQL project.

You can find the project here: https://github.com/GabeShin/nestjs-graphql-sample

Here's the issue:

  • I want to deploy my sample project using AWS CDK, but queries at AppSync is not working properly.
  • I searched web for similar implementation, but I'm having difficult time finding a project that is using NestJS framework with AppSync.
  • When I send a GraphQL query from deployed AppSync API, I'm getting Error Type UnableToAssumeRoleValidationError

I think my lack of knowledge of AWS infrastructure is causing issue and I need some help.

Here's the CDK code:

        const dependenciesLayer = new LayerVersion(this, 'DependenciesLayer', {
            code: new AssetCode('modules/nestjs-graphql-template/node_modules'),
            compatibleRuntimes: [Runtime.NODEJS_14_X, Runtime.NODEJS_16_X],
        });

        const testLambda = new Function(this, 'TestHandler', {
            runtime: Runtime.NODEJS_16_X,
            code: new AssetCode('modules/nestjs-graphql-template/dist'),
            handler: 'index.handler',
            layers: [dependenciesLayer],
        });

        const api = new CfnGraphQLApi(this, 'TestApi', {
            name: 'TestApi',
            authenticationType: 'API_KEY',
        });

        const schemafile = fs.readFileSync(
            'modules/nestjs-graphql-template/schema.graphql'
        );

        const schema = new CfnGraphQLSchema(this, 'MyGraphqlSchema', {
            apiId: api.attrApiId,
            definition: schemafile.toString(),
        });

        const dataSource = new CfnDataSource(this, 'TestDataSource', {
            apiId: api.attrApiId,
            name: 'TestDataSource',
            type: 'AWS_LAMBDA',
            lambdaConfig: {
                lambdaFunctionArn: testLambda.functionArn,
            },
        });

index.ts

import { Server } from 'http';
import { Context } from 'aws-lambda';
import { createServer, proxy, Response } from 'aws-serverless-express';
import * as express from 'express';
import { createApp } from 'src/main';

let cachedServer: Server;

async function bootstrap(): Promise<Server> {
  const expressApp = express();

  const app = await createApp(expressApp);
  await app.init();

  return createServer(expressApp);
}

export async function handler(event: any, context: Context): Promise<Response> {
  if (!cachedServer) {
    const server = await bootstrap();
    cachedServer = server;
  }

  return proxy(cachedServer, event, context, 'PROMISE').promise;
}

Result

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦里的微风 2025-02-04 23:14:07

per /a>和代码文档(node_modules/aws-cdk-lib/aws-appsync/lib/appsync.generated.d.t.ts):

/**
 * The AWS Identity and Access Management service role ARN for the data source. The system assumes this role when accessing the data source.
 *
 * Required if `Type` is specified as `AWS_LAMBDA` , `AMAZON_DYNAMODB` , `AMAZON_ELASTICSEARCH` , or `AMAZON_OPENSEARCH_SERVICE` .
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-datasource.html#cfn-appsync-datasource-servicerolearn
 */
readonly serviceRoleArn?: string;

您需要在数据源中添加ServicerOlearn。

例如:

const lambdaRole = new Role(this, 'LambdaRole', {
    assumedBy: new ServicePrincipal('appsync.amazonaws.com'),
});
lambdaRole.addManagedPolicy(
    ManagedPolicy.fromAwsManagedPolicyName('AWSLambda_FullAccess'),
);
const dataSource = new CfnDataSource(this, 'TestDataSource', {
    apiId: api.attrApiId,
    name: 'TestDataSource',
    type: 'AWS_LAMBDA',
    lambdaConfig: {
        lambdaFunctionArn: testLambda.functionArn,
    },
    serviceRoleArn: lambdaRole.roleArn
});

Per their example and the code documentation (node_modules/aws-cdk-lib/aws-appsync/lib/appsync.generated.d.ts):

/**
 * The AWS Identity and Access Management service role ARN for the data source. The system assumes this role when accessing the data source.
 *
 * Required if `Type` is specified as `AWS_LAMBDA` , `AMAZON_DYNAMODB` , `AMAZON_ELASTICSEARCH` , or `AMAZON_OPENSEARCH_SERVICE` .
 *
 * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-datasource.html#cfn-appsync-datasource-servicerolearn
 */
readonly serviceRoleArn?: string;

you need to add a serviceRoleArn to your dataSource.
For instance:

const lambdaRole = new Role(this, 'LambdaRole', {
    assumedBy: new ServicePrincipal('appsync.amazonaws.com'),
});
lambdaRole.addManagedPolicy(
    ManagedPolicy.fromAwsManagedPolicyName('AWSLambda_FullAccess'),
);
const dataSource = new CfnDataSource(this, 'TestDataSource', {
    apiId: api.attrApiId,
    name: 'TestDataSource',
    type: 'AWS_LAMBDA',
    lambdaConfig: {
        lambdaFunctionArn: testLambda.functionArn,
    },
    serviceRoleArn: lambdaRole.roleArn
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文