Append a directory to Amazon Lambda Environment Variables $NODE_PATH - node.js

Default Env Variable as per the docs:
NODE_PATH:/opt/nodejs/node8/node_modules/:/opt/nodejs/node_modules:$LAMBDA_RUNTIME_DIR/node_modules
I want to append my custom directory to it (NOT to override all)
NODE_PATH:$NODE_PATH:/opt/nodejs/mycustom-directory
I tried the above from lambda console it overrides all. $NODE_PATH is added as a string. It is not parsing $NODE_PATH
Output I got when printing env:
NODE_PATH=$NODE_PATH:/opt/nodejs/mycustom-directory
Similar Question but no Solution still: AWS lambda add PATH variable?

I needed this too, as I am using AWS Lambda Layers, which are placed on the default NODE_PATH, and wanted to also be able to use local roots to avoid long relative paths (such as import bar from foo/bar instead of import bar from ../../../../foo/bar, but I didn't find any way to append to NODE_PATH without losing the default ones - as soon as it's set, the paths to node_modules - including the aws-sdk module, are lost.
The only solutions I can think of are:
Explicitly set NODE_PATH to the default value plus your custom one (which adds an ugly dependency to lambda internal environment configuration which you shouldn't have to care about)
Put your custom library in a layer. Many times this is a good solution if you can extract sub-modules as separate layers (but it doesn't help for situations like elimination of long relative paths within the application itself like I described above).
Append programatically, by having the very first lines of your application do
process.env.NODE_PATH = process.env.NODE_PATH + ":my-custom-path";
require("module").Module._initPaths(); // This re-initalizes the module loader to use the new NODE_PATH.
require('some-custom-module-in-my-custom-path'); // should work
require('aws-sdk') // should also work
This may not be the prettiest hack, but it should do the trick (disclaimer: haven't actually tried this in a AWS Lambda environment but it works locally using Node 12 at least).

I came up with the same problem.
I wrote a code to check if the lambda function applies the shell variable expansions, and to figure out they don't.
I set environment variable FOO as $NODE_PATH,
Then, run the check code (in lambda function):
const { FOO } = process.env;
exports.lambdaHandler = async (event, context, callback) => {
console.log(FOO);
};
The output is:
2019-02-22T08:29:05.714Z cde21239-628f-4a79-b046-6a14f177f59e $NODE_PATH
I just rewrite the whole NODE_PATH to be (my custom library path):/opt/nodejs/lib:/opt/nodejs/node8/node_modules/:/opt/nodejs/node_modules:/var/runtime/node_modules
the default value of NODE_PATH is explained there:
https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html

Related

Can we use an env variable named _MY_SECRET?

I'm trying to use an environment variable in my serverMiddleware in Nuxt.js. It works fine when it starts with a letter (MY_SECRET) but since it's a private server variable I'd like it to start with an underscore (_MY_SECRET). However for some reason the latter is undefined.
This is my basic setup:
// .env
MY_SECRET = hello
_MY_SECRET = world
// serverMiddleware/index.js
console.log(process.env.MY_SECRET, process.env._MY_SECRET) // output: hello undefined
Why does this happen and what other options do I have to prefix my private variables?
Nvm, you cannot use runtimeConfig in a serverMiddleware (probably because it is out of the Nuxt context) as shown here: https://github.com/nuxt/nuxt.js/issues/2033#issuecomment-773181809
I tried it myself with an underscore and it's working great with a publicRuntimeConfig.
After some research aka this answer and reading the official spec, on top of some Wikipedia, it looks like _ is a valid character for an env. Meanwhile, it is also used as a separator.
I've tried several things, found out that if you prefix it with a _, you won't even have it in process.env, this is not a dotenv issue neither (checked this one too), so I just guess that this is not possible.
Solution
Use PRIVATE_MY_SECRET and you should be good!

Can the config crate merge environment variables into a subsection of a hierarchical config file?

I am using the Config crate in Rust, and would like to use environment variables to set keys inside a section of the config. The end goal is to override application settings from a docker compose file, or docker command line, using the environment.
If my config was the following, could I use a specifically crafted environment variable to set database.echo ?
(code blurb below is taken from this example)
debug = true
[database]
echo = true
The example code to configure this using the environment variables illustrates only to set keys at the top level. Wondering how to extend this. The .set() takes a hierarchical key, so I'm hopeful that there's a way to encode the path in the env variable name.
Answering my own question.
I just noticed that the Environment code accepts a custom separator which will get replaced with . (dot).
So one can set the separator to something like _XX_ and that would get mapped to a ".". Setting DATABASE_XX_ECHO=true, for instance would then change the database.echo key.

Bypass NODE_ENV with node-config

I am trying to test my config files by validating them, nothing fancy, a schema, a list of envs, iterate over it, load the config and validate the variable against the schema.
Problem is, to do that, I currently have to set process.env.NODE_ENV. Since the tests have their own reserved config file, this mean if the tests were run in parrallel, it may happen that the test change the NODE_ENV variable when the other tests are loading the config, which while it doesn't seems likely to happens, still bother me.
A simple solution would be to be able to tell node-config to ignore the environment variable, and use a given value as if it was, something like require('config')('myNodeEnv'), but I couldn't find anything similar in the wiki nor the documentation. The closest is custom env variable, but this would just move the problem to another variable.
Instead of tests having their own config files, tests should load a same "base" test-config.
When a specific test needs to override a specific value it should override that specific value and not the entire config (needless to say, we need to make sure to fix the overridden value when the test finishes).
When we work as described above, it reduces the chances of any collision because the chances that different tests will override the exact same value at the exact same moment is very low.
Another option is to run tests separately, for example:
npm run test:suite1
npm run test:suite2
where test:suite1 could be declared in package.json under scripts section, for example:
"test:suite1": "NODE_ENV=test-conf-1 tests/suite1.js",
...

Is there a way to use a global variable for the whole npm project?

I need to use a variable between node modules folder and src folder.Is there a way to use a variable to be used within the whole project?
Thanks.
Typically this is done with process environment variables. Any project can look for a common environment variable and handle that case accordingly, as well as the node modules of said project. As long as they agree on the name, they all share the same environment. Have a good default, don't force people to set this environment variable.
The environment can be set using an environment file (do not check this into source control!), on your container or cloud configuration, or even right on the command line itself.
TLOG=info npm test
That is an example that I use frequently. My project runs logging for the test cases only at alert level - there are a lot of tests so it makes the output less verbose. However, sometimes while developing I want to see all the logs, so my project is looking for an environment variable TLOG (short for "test logging") and I can set it just for that run! Also no code change is needed, which is nicer than JavaScript variables that need to be set back to original values, forget to be turned off, etc.

Best practice when using an API key in Node.js

I have an API key I'm using in my Node.js application. Currently, I keep it stored in a text file and put it in a global variable when my application starts up.
So basically it's just:
var key = getKey();
useKeyGetData(key);
I don't like having this global variable, and it's a pain to pass between files. Is there a better way to get my key where/when I need it? Is there some standard for doing so?
The conventional alternative to what you're doing, especially when pertaining to API keys, is to use environment variables. This is an operating system-level configuration facility. Each process has its own set of environment variables, usually inherited from its parent process. By convention, environment variables have uppercase names.
In node.js, you can access environment variables through process.env. For example, if you run an application like this:
$ MY_VARIABLE=test node app.js
You can access the value of the MY_VARIABLE environment variable via:
process.env.MY_VARIABLE
It can be tedious, however, to have to keep passing the environment variable(s) on each invocation of your program. That's why there are packages such as dotenv which allow you to store your environment variables in a text file.
More specifically, you will have a file called .env and in it you might have:
MY_VARIABLE=test
OTHER_VARIABLE=foo
At the beginning of your app.js, you then do:
require('dotenv').config();
This reads the environment variable values from the .env file. You can then access them as you would access any other environment variables:
console.log("MY_VARIABLE: " + process.env.MY_VARIABLE);
console.log("OTHER_VARIABLE: " + process.env.OTHER_VARIABLE);
Now you don't have to explicitly pass the environment variables to your application upon invocation, i.e. you can just run it as usual:
$ node app.js
If you do pass one explicitly, it will override whatever value you gave in your .env file:
$ MY_VARIABLE=bar node app.js
Now the MY_VARIABLE environment variable will have a value of "bar" instead of "testing". Since OTHER_VARIABLE isn't passed explicitly, it retains its value of "foo" specified in the .env file.

Resources