aws-cdk: SyntaxError: Unexpected token '?' on Amazon Linux 2 CodeBuild images (Node 14 required starting at 2.28.0)

Describe the bug

Running command cdk synth with latest aws-cdk from npm produces an error.

Expected Behavior

I made no changes to source. The install step installs the most recent aws-cdk and it seems this error came with the newest version.

Current Behavior

[Container] 2022/06/14 18:50:24 Running command cdk synth
--
663 | /usr/local/lib/node_modules/aws-cdk/lib/index.js:12322
664 | return process.env.CDK_HOME ? path.resolve(process.env.CDK_HOME) : path.join((os.userInfo().homedir ?? os.homedir()).trim() \|\| "/", ".cdk");

SyntaxError: Unexpected token '?'
--
668 | at wrapSafe (internal/modules/cjs/loader.js:915:16)
669 | at Module._compile (internal/modules/cjs/loader.js:963:27)
670 | at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
671 | at Module.load (internal/modules/cjs/loader.js:863:32)
672 | at Function.Module._load (internal/modules/cjs/loader.js:708:14)
673 | at Module.require (internal/modules/cjs/loader.js:887:19)
674 | at require (internal/modules/cjs/helpers.js:74:18)
675 | at Object.<anonymous> (/usr/local/lib/node_modules/aws-cdk/bin/cdk.js:3:15)
676 | at Module._compile (internal/modules/cjs/loader.js:999:30)
677 | at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)

Reproduction Steps

npm install -g aws-cdk
cdk synth

Possible Solution

No response

Additional Information/Context

I was able to explicitly install version 2.27.0 to confirm this is an issue with 2.28.0 (but I still have this problem later in the self mutate phase where I can’t control the version). This was all done on a .NET CDK app. My apologies for the lack of info I know you need more I am just trying to get some attention on this as soon as I can.

CDK CLI Version

aws-cdk@2.28.0

Framework Version

No response

Node.js Version

12.22.12

OS

Linux

Language

.NET

Language Version

No response

Other information

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 14
  • Comments: 49 (12 by maintainers)

Commits related to this issue

Most upvoted comments

I think this is because of the NodeJS version 12, as I can reproduce it with Node 12 but not with Node 16.

When using the CDK with Node 12, I get the warning:

npm WARN notsup Unsupported engine for aws-cdk@2.28.0: wanted: {"node":">= 14.15.0"} (current: {"node":"12.22.2","npm":"6.14.13"})
npm WARN notsup Not compatible with your version of node/npm: aws-cdk@2.28.0

The problem is that when deploying to production, the standard CDK Pipeline image (for ARM anyway) is outdated! The latest version of Node in the AmazonLinux2 package repo for ARM is still 12!

Plus, even if you try to pin the version of the CDK in your build, the built-in SelfMutate / UpdatePipeline step still tries to run

npm install -g aws-cdk@2

which then prints the above warning, and proceeds to fail with the error cited in the original post for this issue.

[Container] 2022/06/14 20:05:12  BUILD: 1 commands
[Container] 2022/06/14 20:05:12 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
[Container] 2022/06/14 20:05:12 Phase context status code:  Message: 
[Container] 2022/06/14 20:05:12 Entering phase INSTALL
[Container] 2022/06/14 20:05:12 Running command npm install -g aws-cdk@2
/usr/local/bin/cdk -> /usr/local/lib/node_modules/aws-cdk/bin/cdk
npm WARN notsup Unsupported engine for aws-cdk@2.28.0: wanted: 
{
    "node": ">= 14.15.0"
}
 (current: 
{
    "node": "12.22.2",
    "npm": "6.14.13"
}
)    
npm WARN notsup Not compatible with your version of node/npm: aws-cdk@2.28.0
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.2 (node_modules/aws-cdk/node_modules    /fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted 
{
    "os": "darwin",
    "arch": "any"
}
 (current: 
{
    "os": "linux",
    "arch": "arm64"
}
)

+ aws-cdk@2.28.0
added 1 package from 1 contributor in 2.327s

[Container] 2022/06/14 20:05:22 Phase complete: INSTALL State: SUCCEEDED
[Container] 2022/06/14 20:05:22 Phase context status code:  Message: 
[Container] 2022/06/14 20:05:22 Entering phase PRE_BUILD
[Container] 2022/06/14 20:05:22 Phase complete: PRE_BUILD State: SUCCEEDED
[Container] 2022/06/14 20:05:22 Phase context status code:  Message: 
[Container] 2022/06/14 20:05:23 Entering phase BUILD
[Container] 2022/06/14 20:05:23 Running command cdk -a . deploy Pipeline --require-approval=never --verbose
/usr/local/lib/node_modules/aws-cdk/lib/index.js:12322
  return process.env.CDK_HOME ? path.resolve(process.env.CDK_HOME) : path.join((os.userInfo().homedir ??         os.homedir()).trim() || "/", ".cdk");
                                                                                                   ^

SyntaxError: Unexpected token '?'
    at wrapSafe (internal/modules/cjs/loader.js:915:16)
    at Module._compile (internal/modules/cjs/loader.js:963:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/usr/local/lib/node_modules/aws-cdk/bin/cdk.js:3:15)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)

[Container] 2022/06/14 20:05:23 Command did not exit successfully cdk -a . deploy Pipeline --require-    approval=never --verbose exit status 1
[Container] 2022/06/14 20:05:23 Phase complete: BUILD State: FAILED

Please update the aws_cdk.aws_codebuild.LinuxBuildImage.AMAZON_LINUX_2_ARM_2 image ASAP! Production pipelines for ARM are broken!

Ah ok i thought you managed to pin the version of cdk… yup looks like that works 😃

And the final for others using typescript

        const pipeline = new CodePipeline(this, 'AppPipeline', {
            pipelineName: 'AppPipeline',
            codeBuildDefaults: { 
                buildEnvironment: {
                    buildImage: LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0
                },
                partialBuildSpec: BuildSpec.fromObject({
                    phases: {
                       install: {
                        commands: [
                            "n 16.15.1"
                        ]
                       }
                    }
                })
            },

Im getting this and its super annoying, it’s because the new cdk version 2.28.0 requires nodejs v14+. Unfortunately, Im using AMAZON_LINUX_2_ARM_2 and that build image doesn’t even have the option to use a more recent version.

First attempt at workaround

Im attempting to use the ‘n’ command as below: installCommands:[n 16.15.1’] However, this still only gets you up to the update-pipeline phase and that still errors out as you can’t control the node version in that phase

Second attempt at workaround

Is to pin the cdk version to the previous version rather than use ^2.0.0… Im trying that now. Nope doesn’t work as per beton’s comment

PLEASE AWS can you upgrade all your build images to support cdk, namely nodejs 14+

For those using CdkPipeline, you can set the cdkCliVersion on the pipeline props, which also applies it to the UpdatePipeline step. If you’re using a 1.x version of the cdk with CdkPipelines api on codebuild AL2 images, you can use this to use an older version of the cdk cli that supports Node 12 (<=1.159.0 or earlier matching the framework version you’re using).

For v2 users on AL2, add a step to your buildspec to install nodejs 14 or later using nvm as detailed above for synth steps and self-mutation steps as needed.

We are currently releasing a fix to the ConfirmPermissionsBroadening step to correctly use ubuntu standard 5 so keep an eye out for that. https://github.com/aws/aws-cdk/pull/20864/commits/47b5ca06c50a566af8d1fed4202164b85f793d18

@iselcuk working on a fix now to make this action default to standard:5 image. Also still working on providing workarounds for the old CdkPipelines api. We have no official timeline on when ARM images will include NodeJS 14 by default unfortunately.

Hey all, we are working with the codebuild team to get images updated so NodeJS 14 is installed by default in latest versions of codebuild images used by cdk piplines by default. For now, @tmitchel2’s workaround seems best (TY for that).

I can work on identifying a workaround for CdkPipelines but it will likely involve escape hatches to reach into the underlying CFN and affect the buildspec in a similar manner 👈🏻 @CodeWithOz @rowilken

This works! 😃. needs a manual push…

        const pipeline = new CodePipeline(this, 'AppPipeline', {
            pipelineName: 'AppPipeline',
            selfMutationCodeBuildDefaults: {
                partialBuildSpec: BuildSpec.fromObject({
                    phases: {
                       install: {
                        commands: [
                            "n 16.15.1"
                        ]
                       }
                    }
                })
            },
            codeBuildDefaults: {
                buildEnvironment: {
                    buildImage: LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0
                }
            },

What helped me is installing hardcoded version of cdk in buildspec file: npm install -g aws-cdk@1.160.0 Of course you can use any other version (just not the latest one).

what worked for me is pinning the CDK version from the Pipeline construct. Afterwards do a manual npx cdk deploy MyPipelineStack from my machine (node 16.15.0).


const pipeline = new CodePipeline(this, 'Pipeline', {
            ...
            cliVersion: '2.27.0',
            ...

My workaround as per above works for me and is fine enough as a workaround, however, I just wanted to make it clear that the Arm images are getting left behind a bit and I guess still need to be addressed.

@ashishchandr70 all of the above posted fixes require a manual deploy as self-update can’t run synth successfully to make the changes to the code to change the cdk cli version or update the containers to standard:5.0, after that deploy it will be able to self-update as usual again.

Closing this out as codebuild has made AL2:4.0 available which has NodeJS 16 as standard, so users wanting to continue to use AL2 with the latest CDK CLI should be able to. If you get stuck with this error in self-update, update your codebuild images and run a deploy of the pipeline stack to get the updates.

@MrArnoldPalmer thanks I’m looking forward to that. Is there any ETA you can give?

@rix0rrr I’m using "@aws-cdk/pipelines": "^1.108.1" and as I mentioned earlier my build image is standard 5, but I still get the problem.

The issue is about the CodeBuild image.

Any CDK Pipeline created with a version of v1.101 or higher (or v2) will not be affected, as it will be using the CodeBuild standard:5.0 image[1] which contains Node14.

AL2-based images do not have Node14 yet, work is in progress on that.

[1] https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html

OK, got your idea:

  1. Migrate to the new API
  2. Applying the fix you proposed for CodePipeline
  3. Hoping for AWS to supply a fixed image in the near future and remove the workaround after that

I moved your partial build spec to CodeBuildDefaults. .NET:

CodeBuildDefaults = new CodeBuildOptions
{
    BuildEnvironment = new BuildEnvironment
    {
        BuildImage = LinuxBuildImage.AMAZON_LINUX_2_3,
    },
    PartialBuildSpec = BuildSpec.FromObject(new Dictionary<string, object>
    {
        {
            "version", "0.2"
        },
        {
            "phases", new Dictionary<string, object>
            {
                {
                    "build", new Dictionary<string, object>
                    {
                        {
                            "commands", new [] { "n 16.15.1" }
                        }
                    }
                }
            }
        }
    }),
},

Nice - I also see asset_publishing_code_build_defaults, so looks like we may be able to override the image for each step.

Or better yet, maybe just pin the version with the partialBuildSpec