Search code examples
node.jsenvironment-variablesserverless-framework

How to resolve local env vars in Serverless Framework V4?


I've recently started a project using Serverless V4, but I'm not able to get the variables from my .env, I'm using serverless-offline as plugin, Node.js v21.7.1.

This is my serverless.yml

# "org" ensures this Service is used with the correct Serverless Framework Access Key.
org: kennethlg
# "app" enables Serverless Framework Dashboard features and sharing them with other Services.
app: hoost
# "service" is the name of this project. This will also be added to your AWS resource names.
service: my-project

provider:
  name: aws
  runtime: nodejs20.x
functions:
  getListings:
    handler: src/controllers/getListings/index.handler
    events:
      - httpApi:
          path: /listings
          method: get
  login:
    handler: src/controllers/login/index.handler
    events:
      - httpApi:
          path: /login
          method: get
plugins:
  - serverless-offline
const responseHandler = require("../../libs/response");
const { login } = require("../../services/hostaway");

module.exports.handler = async () => {
  try {
    const data = await login();
    return responseHandler.success(data, 'Login successful');
  } catch (error) {
    return responseHandler.error('Couldn\'t login sucessfully');
  }
} 
const { instance } = require('../libs/axios');
const config = require('../config');

const login = async () => {
  try {
    console.log(config)
    const data = new URLSearchParams();
    data.append('grant_type', 'client_credentials');
    data.append('client_id', config.hostawayId);
    data.append('client_secret', config.hostawayApiKey);
    data.append('scope', 'general');

    const response = await instance.post('/accessTokens', data, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Cache-Control': 'no-cache',
      }
    });
    return response.data;
  } catch (error) {
    console.log("🚀 ~ login ~ error:", error);
    throw new Error('Error authenticating to Hostaway');
  }
}

I get a 500 error because my env vars are not set correctly:

const config = {
  port: process.env.PORT || 3000,
  hostawayApiKey: process.env.HOSTAWAY_API_KEY,
  hostawayId: parseInt(process.env.HOSTAWAY_ID)
}

module.exports = config;
Server ready: http://localhost:3000 🚀


GET /login (λ: login)
{ port: 3000, hostawayApiKey: undefined, hostawayId: NaN }

I read the documentation and it says that serverless v4 is already configured to use use local environments, but as I mentioned before, it isn't working. This is the documentation: https://www.serverless.com/framework/docs-providers-aws-guide-variables


Solution

  • In previous versions of Serverless Framework (<= V.3), the useDotEnv configuration in serverless.yml would have to be set in order to load .env and [stage].env files, and make their environment variables accessible within serverless.yml.

    In V.4, these files are read automatically, without the useDotEnv property, this mean you can access the .env variables inside the serverless.yml not in lambda environment automatically.

    Solution

    You have to configure lambda environment variables manually in serverless.yml

    1. If you want to variable configuration to a specific function by adding an environment object property in the function configuration. This object should contain a key-value pairs of string to string like below.

       functions:
         getListings:
           handler: src/controllers/getListings/index.handler
           environment:
             HOSTAWAY_API_KEY: ${env:HOSTAWAY_API_KEY}
             HOSTAWAY_ID: ${env:HOSTAWAY_ID}
           events:
             - httpApi:
                 path: /listings
                 method: get
      
    2. Or if you want to apply environment variable configuration to all functions in your service, you can add the configuration to the higher level provider object

       provider:
         name: aws
         runtime: nodejs20.x
         environment:
               HOSTAWAY_API_KEY: ${env:HOSTAWAY_API_KEY}
               HOSTAWAY_ID: ${env:HOSTAWAY_ID}