Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SAM local invocation with CDK generated template with typescript not able to find module index (index.mjs) #7048

Closed
Schwar999 opened this issue May 10, 2024 · 5 comments
Labels
area/cdk blocked/close-if-inactive Blocked for >14 days with no response, will be closed if still inactive after 7 days blocked/more-info-needed More info is needed from the requester. If no response in 14 days, it will become stale. stage/bug-repro The issue/bug needs to be reproduced stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at.

Comments

@Schwar999
Copy link

Schwar999 commented May 10, 2024

Issue

I'm trying to test a typescript lambda test made with CDK using SAM local invocation.

I did sam local "invoke -t stack.template.json" to test lambda, but I got the following error: "Error: Cannot find module 'index'“, ‘Require stack:’,”- /var/runtime/index.mjs Error."
The configuration in tsconfig.ts uses a CommonJS module with a ES2020 target.

I am trying to figure out why this error occurred, and I am thinking that SAM probably tried to invoke ES2020 modules instead of CommonJS.
I want to change the SAM local invocation so it can resolve to CommonJS.

I confirmed the result in a console, and it said that "index.js" was made using "cdk deploy", not "index.mjs".

Error code

user@e5a3a4120a93:~/app/cdk$ sam local invoke func -t ./cdk.out/stack.template.json  --container-host host.docker.internal
Invoking index.handler (nodejs18.x)
arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:78 is already cached. Skipping download
Local image is up-to-date
Using local image: samcli/lambda-nodejs:18-x86_64-2fad385d3004a32911b20c629.

2024-05-09T11:58:15.991Z        undefined       ERROR   Uncaught Exception      {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'index'\nRequire stack:\n- /var/runtime/index.mjs","stack":["Runtime.ImportModuleError: Error: Cannot find module 'index'","Require stack:","- /var/runtime/index.mjs","    at _loadUserApp (file:///var/runtime/index.mjs:1087:17)","    at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)","    at async start (file:///var/runtime/index.mjs:1282:23)","    at async file:///var/runtime/index.mjs:1288:1"]}   
09 May 2024 11:58:16,018 [ERROR] (rapid) Init failed error=Runtime exited with error: exit status 129 InvokeID=
09 May 2024 11:58:16,521 [ERROR] (rapid) Invoke failed error=ErrAgentNameCollision InvokeID=5cf7740b-0b0c-4b8d-9733-514b9147aa3e

{"errorType": "Runtime.ImportModuleError", "errorMessage": "Error: Cannot find module 'index'\nRequire stack:\n- /var/runtime/index.mjs", "trace": ["Runtime.ImportModuleError: Error: Cannot find module 'index'", "Require stack:", "- /var/runtime/index.mjs", "    at _loadUserApp (file:///var/runtime/index.mjs:1087:17)", "    at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)", "    at async start (file:///var/runtime/index.mjs:1282:23)", "    at async file:///var/runtime/index.mjs:1288:1"]}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["es2020"],
    "declaration": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": false,
    "inlineSourceMap": true,
    "inlineSources": true,
    "experimentalDecorators": true,
    "strictPropertyInitialization": false,
    "noEmit": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "typeRoots": ["./node_modules/@types"]
  },
  "exclude": ["node_modules", "cdk.out"]
}

ENV
Docker

  • SAM CLI, version 1.116.0
  • CDK 2.141.0 (build 3d1c06e)
  • aws-cli/2.15.41 Python/3.11.8 Linux/5.15.133.1-microsoft-standard-WSL2 exe/x86_64.debian.12 prompt/off
  • node v18.19.0
  • npm version 9.2.0
@Schwar999 Schwar999 added the stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at. label May 10, 2024
@Schwar999 Schwar999 changed the title SAM local invocation with CDK generated template with typescript not to be able to find module index() SAM local invocation with CDK generated template with typescript not to be able to find module index (index.mjs) May 10, 2024
@Schwar999 Schwar999 changed the title SAM local invocation with CDK generated template with typescript not to be able to find module index (index.mjs) SAM local invocation with CDK generated template with typescript not able to find module index (index.mjs) May 10, 2024
@hawflau
Copy link
Contributor

hawflau commented May 10, 2024

Hey @Schwar999, thanks for raising the issue.

To help us reproduce the issue, can you please share your Lambda Function Construct in CDK and corresponding Lambda Function Resource in synth-ed template?

@hawflau hawflau added blocked/more-info-needed More info is needed from the requester. If no response in 14 days, it will become stale. stage/bug-repro The issue/bug needs to be reproduced area/cdk blocked/close-if-inactive Blocked for >14 days with no response, will be closed if still inactive after 7 days and removed stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at. labels May 10, 2024
@Schwar999
Copy link
Author

Schwar999 commented May 10, 2024

@hawflau
Thank you for your reply.

Here are some of my codes.
Would you be able to analyze them?

Synth-ed template

"func0915CAEC": {
   "Type": "AWS::Lambda::Function",
   "Properties": {
    "Architectures": [
     "x86_64"
    ],
    "Code": {
     "S3Bucket": "cdk-xxxx",
     "S3Key": "xxxx.zip"
    },
    "Environment": {
     "Variables": {
      "ENV_NAME": "dev",
      "LOG_LEVEL": "debug",
      "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1"
     }
    },
    "Handler": "index.handler",
    "Layers": [
     "arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:78"
    ],
    "MemorySize": 256,
    "Role": {
     "Fn::GetAtt": [
      "funcServiceRoleDA6E3B24",
      "Arn"
     ]
    },
    "Runtime": "nodejs18.x",
    "VpcConfig": {
     "SecurityGroupIds": [
      {
       "Fn::GetAtt": [
        "funcSecurityGroup8BD4105F",
        "GroupId"
       ]
      }
     ],
     "SubnetIds": [
      "subnet-000",
      "subnet-001"
     ]
    }
   },
   "DependsOn": [
    "funcServiceRoleDefaultPolicy2124A06A",
    "funcServiceRoleDA6E3B24"
   ],
   "Metadata": {
    "aws:cdk:path": "test-stack/func/Resource",
    "aws:asset:path": "asset.71bec7b1e16c2b00a998c4abec8abb8ebcf9242a7b",
    "aws:asset:is-bundled": true,
    "aws:asset:property": "Code"
   }
  }

stack.ts

import { Duration, Stack, StackProps } from "aws-cdk-lib";
import { Construct } from "constructs";
import { Topic } from "aws-cdk-lib/aws-sns";
import { SqsSubscription } from "aws-cdk-lib/aws-sns-subscriptions";
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
import { Architecture, LambdaInsightsVersion, Runtime, Tracing } from "aws-cdk-lib/aws-lambda";
import { Config } from "./config";
import { SubnetType, Vpc } from "aws-cdk-lib/aws-ec2";
import { Queue, QueuePolicy } from "aws-cdk-lib/aws-sqs";
import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
import { RetentionDays } from "aws-cdk-lib/aws-logs";
import { Effect, PolicyStatement, ServicePrincipal } from "aws-cdk-lib/aws-iam";
import { QueueProps } from "aws-cdk-lib/aws-sqs/lib/queue";

export class TestStack extends Stack {
  constructor(scope: Construct, id: string, props: TestStackProps, config: Config) {
    super(scope, id, props);

    const vpc = Vpc.fromLookup(this, "test-vpc", { vpcId: config.testVpcId });

    const funcLambda = new NodejsFunction(this, `func`, {
      memorySize: 256,
      vpc: vpc,
      vpcSubnets: vpc.selectSubnets({ subnetType: config.testVpcSubnetType as SubnetType }),
      allowPublicSubnet: config.testVpcSubnetType === "Public",
      runtime: Runtime.NODEJS_18_X,
      timeout: Duration.seconds(config.pushNotifier.func.lambdaAndQueueVisibilityTimeoutSeconds),
      environment: {
        ENV_NAME: config.env,
        LOG_LEVEL: config.logLevel,
      },
      architecture: Architecture.X86_64,
      insightsVersion: LambdaInsightsVersion.fromInsightVersionArn(config.lambdaInsightsArn),
      logRetention: RetentionDays.ONE_YEAR,
      tracing: Tracing.ACTIVE,
    });

lambda.ts

import { Context, SQSEvent, SQSRecord } from "aws-lambda";
import got from "got";
import { defaultLogger, getLogger } from "./logger";
import { captureLambdaHandler, Tracer } from "@aws-lambda-powertools/tracer";
import middy from "@middy/core";

let logger = defaultLogger;

export const handler = middy(async (event: SQSEvent, context: Context) => {
  logger = getLogger(context);
  const sqsRecord: SQSRecord = event.Records[0];
  const sqsBody: TestMessage = JSON.parse(sqsRecord.body);
  return notifySingle(sqsRecord.messageId, sqsBody.endpoint, sqsBody.payload);
}).use(captureLambdaHandler(tracer));

@mndeveci
Copy link
Contributor

I've tried to reproduce this issue however I was able to invoke the function locally.

Here is the folder structure;

.
├── README.md
├── bin
│   └── cdk-local.ts
├── cdk.json
├── jest.config.js
├── lib
│   ├── cdk-local-stack.func.ts
│   └── cdk-local-stack.ts
├── package-lock.json
├── package.json
└── tsconfig.json

Here are the contents of the files;
bin/cdk-local.ts

#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { CdkLocalStack } from '../lib/cdk-local-stack';

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

lib/cdk-local-stack.ts

export interface Response {
    result: number;
}

export const handler = async (event: {}): Promise<Response> => {
    const result = {
        result: 10,
    };

    return result;
};

lib/cdk-local-stack.func.ts

import * as cdk from 'aws-cdk-lib';
import { Architecture, Runtime, Tracing } from 'aws-cdk-lib/aws-lambda';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';
import { Construct } from 'constructs';

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

    // The code that defines your stack goes here

    const funcLambda = new NodejsFunction(this, `func`, {
      memorySize: 256,
      runtime: Runtime.NODEJS_18_X,
      architecture: Architecture.X86_64,
      logRetention: RetentionDays.ONE_YEAR,
      tracing: Tracing.ACTIVE,
    });
  }
}

I've used your tsconfig.json file. I am running cdk synth and then sam local invoke --template cdk.out/CdkLocalStack.template.json func and I can invoke function locally.

Can you provide a reproducible example?

@lucashuy
Copy link
Contributor

Closing the issue, please reopen or create a new issue if you encounter any other problems.

@lucashuy lucashuy closed this as not planned Won't fix, can't repro, duplicate, stale May 24, 2024
@lucashuy lucashuy added the stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at. label May 24, 2024
Copy link
Contributor

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/cdk blocked/close-if-inactive Blocked for >14 days with no response, will be closed if still inactive after 7 days blocked/more-info-needed More info is needed from the requester. If no response in 14 days, it will become stale. stage/bug-repro The issue/bug needs to be reproduced stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at.
Projects
None yet
Development

No branches or pull requests

4 participants