Preface
We can hard-code those env values into serverless.yml
, but of course it is not ideal.
If we have already separated variables into default-one and stage-specific ones, we definitely want to reuse them.
Requirements
-
A plugin
serverless-dotenv-plugin
is required to load multiple env files and; -
We need to write custom
parser
when our env file is ajson
file (more readable than an ordinary.env
file, especially when there is a long array).
Deployment Configuration
The serverless.yml
serverless.yml
Here the order of variables in path
does matter, varibles in .env.dev.json
can override those in .env.json
:
plugins: - serverless-dotenv-plugin ...... custom: dotenv: path: - .env.json - .env.dev.json dotenvParser: "./jsonParser.js"
The parameter dotenvParser
is optional, as long as our .env
files are simply key=value
's, otherwise we need a parser to process non-ordinary values (like an array).
jsonParser.js
jsonParser.js
1const fs = require("fs"); 2 3module.exports = function ({ paths }) { 4 const envVarsArray = paths.map((path) => { 5 try { 6 const fileContent = fs.readFileSync(path, "utf8"); 7 const jsonData = JSON.parse(fileContent); 8 9 const stringifiedData = {}; 10 for (const key in jsonData) { 11 const value = jsonData[key]; 12 const ordinaryENVType = ["string", "boolean", "number"]; 13 14 if (ordinaryENVType.includes(typeof value)) { 15 stringifiedData[key] = jsonData[key]; 16 } else if (Array.isArray(jsonData[key])) { 17 stringifiedData[key] = jsonData[key].map((v) => String(v)).join(","); 18 } else { 19 //ignore 20 } 21 } 22 23 return stringifiedData; 24 } catch (error) { 25 console.error(`Error reading/parsing ${path}:`, error.message); 26 return {}; 27 } 28 }); 29 30 return envVarsArray.reduce((acc, curr) => ({ ...acc, ...curr }), {}); 31};
Special treatments have been made from line 14-18, any list is transformed into ,
-concated string (remember to split by ,
in the program).