Search code examples
node.jsgithub-actionsaws-cdkesbuild

Trouble Building CDK NodejsFunction in Github Actions


I am trying to build a nodejs lambda function using CDK from github actions.

Here is the function definition:

    const graphqlServerLambda = new NodejsFunction(this, "graphql-server", {
      functionName: `${props.stackName}-graphql-server-${props.stage}`,
      runtime: lambda.Runtime.NODEJS_18_X,
      architecture: lambda.Architecture.X86_64,
      projectRoot: "../server",
      depsLockFilePath: "../server/package-lock.json",
      entry: "../server/src/handler.ts",
      memorySize: 1024,
      logRetention: cdk.aws_logs.RetentionDays.ONE_WEEK,
      environment: {
        AWS_LAMBDA_EXEC_WRAPPER: "/opt/otel-handler",
        OPENTELEMETRY_COLLECTOR_CONFIG_FILE: "/var/task/collector.yml",
        OPENTELEMETRY_EXTENSION_LOG_LEVEL: "warn",

        OTEL_SERVICE_NAME: `${props.stackName}-graphql-server-${props.stage}`,
        NEW_RELIC_OTEL_ENDPOINT: "https://otlp.eu01.nr-data.net:4317",
        NEW_RELIC_LICENSE_KEY: props.new_relic_license_key,
        NODE_OPTIONS: "--require otel-config",
      },
      layers: [
        lambda.LayerVersion.fromLayerVersionArn(
          this,
          "otel-layer",
          `arn:aws:lambda:eu-central-1:901920570463:layer:aws-otel-nodejs-arm64-ver-1-17-1:1`
        ),
      ],
      tracing: lambda.Tracing.ACTIVE,
      bundling: {
        keepNames: true,
        nodeModules: [
          "graphql",
          "pino",
          "@opentelemetry/auto-instrumentations-node",
        ],
        commandHooks: {
          beforeBundling(inputDir: string, outputDir: string): string[] {
            return [
              `cp ${inputDir}/collector.yml ${outputDir}`,
              `cp ${inputDir}/otel-config.js ${outputDir}`,
            ];
          },
          afterBundling(): string[] {
            return [];
          },
          beforeInstall() {
            return [];
          },
        },
      },
    });

I added the projectRoot and depsLockFilePath values in response to this issue, however I am now getting:

cp: cannot stat ‘/asset-input/collector.yml’: No such file or directory

The collector.yml and otel-config.js files are in the cdk root directory.

As an aside, this seems like a really convulted way of deploying these functions (spinning up a docker container to do the esbuild etc), when the deployment seems to run natively on my M1, so adivce on deployment of this would also be helpful.

I should also note that I switched from ARM64 to X86_64 because I wasn't able to get this to work either, xref.


Solution

  • This problem was solved in two ways:

    1. Moving the collector.yml and otel-config.js files to the "project root" i.e. ../server
    2. Installing esbuild globally in the github action, which meant esbuild ran natively instead of with docker. This also meant I was able to switch back to ARM64 for the function.