Fix Serverless Build Errors on AWS Lambda
Adam C. |

We have a serverless application running on AWS Lambda. Recently, we saw some warnings/errors in the AWS CodeBuild log as below, although the application is successfully built:

Serverless: Deprecation warning: Starting with next major version, API Gateway naming will be changed from "{stage}{service}" to "{service}{stage}".
Set "provider.apiGateway.shouldStartNameWithService" to "true" to adapt to the new behavior now.
More Info: https://www.serverless.com/framework/docs/deprecations/#AWS_API_GATEWAY_NAME_STARTING_WITH_SERVICE

gyp ERR! configure error
gyp ERR! stack Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/serverless/node_modules/snappy/.node-gyp'

Photo by Diego Fernandez on Unsplash

apiGateway.shouldStartNameWithService

The first one is pretty straightforward. Regarding the documentation from serverless.com:

Starting with v3.0.0, API Gateway naming will be changed from ${stage}-${service} to ${service}-${stage}.

Adapt to this convention now by setting provider.apiGateway.shouldStartNameWithService to true.

To fix this, we just need to add the following in serverless.yml:

provider:
  ...
  apiGateway:
    shouldStartNameWithService: true

And we also need to add a bunch of new IAM permissions to the role, otherwise, the build will fail due to the following errors:

An error occurred: ApiGatewayRestApi - User: arn:aws:sts::514231989137:assumed-role/codebuild-NCCIH-API-service-role/AWSCodeBuild-dd964d15-ed63-4bb3-b152-48109817bbab is not authorized to perform: apigateway:PATCH on resource: arn:aws:apigateway:us-east-1::/restapis/9ohallxqbi (Service: AmazonApiGateway; Status Code: 403; Error Code: AccessDeniedException; Request ID: f81ccfd9-aa65-4aba-9016-e1c925dbae0a; Proxy: null).

Check AWS docs for IAM policy examples for managing API Gateway APIs: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-iam-policy-examples.html

gyp ERR!

We are confused with this one. It seems to be failed on our local sometimes. However, everything works fine without that. Please leave your comment if you know why.

What's gyp

node-gyp is a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js. It contains a vendored copy of the gyp-next project that was previously used by the Chromium team, extended to support the development of Node.js native addons.

We don't have node-gyp as a dependency in our package.json, so it must be used by one of our dependency, in our case it's serverless.

The error we had is so obvious that the user who runs npm does not have the right permission to ‘mkdir’. We might use ‘root’ in the local to fix this, but how about a non-root user?  When code is built & deployed in the AWS serverless, it's not using ‘root’ user and cannot ‘sudo’ as well, so we need a way to allow a non-root user to run package scripts. The good news is that npm allows us to set a flag: ‘unsafe-perm’ to true to run within the context of the running script.

So to fix this, we need to add a flag in buildspec.yml where we specify the install commands as below:

phases:
  install:
    runtime-versions:
      nodejs: 12
    commands:
      - npm install
      - npm install knex -g
      - npm install -g serverless --unsafe-perm