aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.68k stars 3.93k forks source link

cli-lib-alpha: unable to bundle NodejsFunction #26376

Open dreamorosi opened 1 year ago

dreamorosi commented 1 year ago

Describe the bug

When using the AwsCdkCli from the @aws-cdk/cli-lib-alpha package I'm unable to synthesise stacks containing a NodejsFunction construct.

Expected Behavior

The stack should synth & deploy normally, provided that all other parameters are valid.

Current Behavior

When attempting to synth the stack, an error is thrown:

Error: Failed to bundle asset cdk-poc-nodejs18x-6e3e8-makeFnIdempotent/my-function/Code/Stage, bundle output is located at /private/var/folders/s7/xzcjrts93cn5_mq16vkcqt794zqxk7/T/cdk.outoC4Vgb/bundling-temp-eb7f12479b9ffbb7cb20787b7437388f75f41b3c18ec89fbfaa0e64470237272-error: TypeError [ERR_INVALID_ARG_VALUE]: The argument 'stdio' is invalid. Received WritableWorkerStdio {
  _writableState: WritableState {
    objectMode: false,
    highWaterMark: 16384,
    finalCalled: false,...
 ❯ AssetStaging.bundle node_modules/aws-cdk-lib/core/lib/asset-staging.js:2:603
 ❯ AssetStaging.stageByBundling node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:4544
 ❯ stageThisAsset node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:2005
 ❯ Cache.obtain node_modules/aws-cdk-lib/core/lib/private/cache.js:1:242
 ❯ new AssetStaging node_modules/aws-cdk-lib/core/lib/asset-staging.js:1:2400
 ❯ new Asset node_modules/aws-cdk-lib/aws-s3-assets/lib/asset.js:1:736
 ❯ AssetCode.bind node_modules/aws-cdk-lib/aws-lambda/lib/code.js:1:4628
 ❯ new Function node_modules/aws-cdk-lib/aws-lambda/lib/function.js:1:7479
 ❯ new NodejsFunction node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/function.js:1:1121

Reproduction Steps

  1. Create a class that implements ICloudAssemblyDirectoryProducer, along the lines of what described in the construct docs:
class MyProducer implements ICloudAssemblyDirectoryProducer {
  public app: App;
  public stack: Stack;
  #stackName: string;

  public constructor(stackName: string, context?: Record<string, any>) {
    this.#stackName = stackName;
    this.app = new App();
    this.stack = new Stack(this.app, this.#stackName);
  }

  async produce() {
    return this.app.synth().directory;
  }
}
  1. Init the provider and cli
const producer = new MyProducer("cdk-poc-nodejs18x-6e3e8-makeFnIdempotent");
const cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(producer);
  1. Add resources to the stack
    
    const table = new Table(producer.stack, "my-table", {
    tableName: "my-table",
    partitionKey: {
    name: "id",
    type: AttributeType.STRING,
    },
    billingMode: BillingMode.PAY_PER_REQUEST,
    removalPolicy: RemovalPolicy.DESTROY,
    });

const nodeJsFunction = new NodejsFunction(producer.stack, "my-function", { runtime: Runtime.NODEJS_18_X, functionName: "my-function-1234", entry: join(__dirname, ./src/index.ts), timeout: Duration.seconds(30), handler: "handler", environment: { IDEMPOTENCY_TABLE_NAME: table.tableName, }, logRetention: RetentionDays.ONE_DAY, }); table.grantReadWriteData(nodeJsFunction);


4. Synth the stack
```ts
await cli.synth({
  stacks: [producer.stack.stackName],
});
  1. create a function file in src/index.ts
export const handler = async () => { return { statusCode: 200 } };
  1. run & see the error

Full file below

```ts import { App, Stack, RemovalPolicy, Duration } from "aws-cdk-lib"; import { Table, AttributeType, BillingMode } from "aws-cdk-lib/aws-dynamodb"; import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs"; import { Runtime } from "aws-cdk-lib/aws-lambda"; import { RetentionDays } from "aws-cdk-lib/aws-logs"; import { join } from "node:path"; import { AwsCdkCli, ICloudAssemblyDirectoryProducer, } from "@aws-cdk/cli-lib-alpha"; const producer = new MyProducer("cdk-poc-nodejs18x-6e3e8-makeFnIdempotent"); const cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(producer); const table = new Table(producer.stack, "my-table", { tableName: "my-table", partitionKey: { name: "id", type: AttributeType.STRING, }, billingMode: BillingMode.PAY_PER_REQUEST, removalPolicy: RemovalPolicy.DESTROY, }); const nodeJsFunction = new NodejsFunction(producer.stack, "my-function", { runtime: Runtime.NODEJS_18_X, functionName: "my-function-1234", entry: join(__dirname, `./src/index.ts`), timeout: Duration.seconds(30), handler: "handler", environment: { IDEMPOTENCY_TABLE_NAME: table.tableName, }, logRetention: RetentionDays.ONE_DAY, }); table.grantReadWriteData(nodeJsFunction); await cli.synth({ stacks: [producer.stack.stackName], }); ```

Alternatively, clone this repo with the same code as above and run: https://github.com/dreamorosi/cdk-cli-poc

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.87.0

Framework Version

No response

Node.js Version

v18.12.1

OS

macOS

Language

Typescript

Language Version

5.1.6

Other information

No response

pahud commented 1 year ago

This could be related to https://github.com/aws/aws-cdk/issues/20873

I am making this a p1 but as cli-lib-alpha is an early experimental package, we probably won't be able to look into this issue immediately. But we welcome any further insights for this if any.

dreamorosi commented 1 year ago

Hi @pahud thank you replying and providing a link to another issue.

I am positive that this is indeed related to #20873. Using the workaround described in this comment makes the error go away.