ExpressJS : Proper way to access or declare an environment variable in client/index.html? - node.js

I'm currently learning and toying with Node.js and Express.js and I was wondering what is the proper or most accurate way to use/access a variable depending on environment ( production|development|test ) in client/index.html ?
Typically I would like to use a different Google Analytics code in production and in development environment.
Currently I'm going to investigate/test two solutions :
using grunt to inject relevant code in client/index.html
using a variable set in /server/config/environment/[production|development|test].js
Is there another options and which one is most appropriate way to do this ?

Both are equal, but the second is a bit easier to maintain. You can also pass this value as a URL param in DEV mode (e.g. ?code=123) and skip in production for using a hardcoded constant.

Related

How to reference hiera variable elsewhere in hiera?

We are using the roles pattern in puppet with hiera, meaning we have these lines in hiera.yaml:
- name: "Roles data"
path: "roles/%{::server_role}.yaml"
We have a custom fact that produces the role name when facter runs, but we would like to move this into hiera. Instead of the server_role variable being produced by facter, we want to specify the server_role inside of hiera, and let that variable be referenced elsewhere in hiera. Something like this:
hiera.yaml:
- name: "Per-node data"
path: "nodes/%{trusted.certname}.yaml"
- name: "Roles data"
path: "roles/%{lookup(server_role)}.yaml"
nodes/hostname.yaml:
server_role: foo_bar
I have seen this question, which says to use hiera() or lookup() but when I try to use those, I get this error message:
Interpolation using method syntax is not allowed in this context
So how can I use a hiera variable that's defined elsewhere in hiera?
Edit:
The prototypical code examples for defining roles could use any fact that's known to facter, often giving examples that are based on hostname. When you can't embed server config into hostname, a common(ish) workaround is to write a file such as /etc/server_role, but it seems to defeat the purpose of config management, when you need to ssh into a machine and edit a file. As the other comments & answer here so far mentioned, you could use an ENC, but again, the goal here is not to have config stored outside of version control. In fact, we have foreman as an ENC and we make a practice to never use it that way because then upgrades and other maintenance become unsustainable.
We could write a class which will pick up data from hiera, write it to /etc/server_role, and on the next puppet run, facter will pick that up and send it back to hiera, so then we'll have the server_role fact available to use in hiera.yaml. As gross as this sounds, so far, it's the best known solution. Still looking for better answers to this question.
Thanks.
As #MattSchuchard explained in comments, you cannot interpolate Hiera data into your Hiera config, because the config has to be known before the data can be looked up.
If you need a per-role level in your data hierarchy then an alternative would be to assign roles to machines via an external node classifier. You don't need it to assign any classes, just the server_role top-scope variable and probably also environment.
On the other hand, maybe you don't need a per-role level of your general hierarchy in the first place. Lots of people do roles & profiles without per-role data, but even if you don't want to do altogether without then it may be that module-specific data inside the module providing your role classes could be made to suffice.

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.

Terraform conditional source in MODULE

I am trying to set a module's source (this IS NOT a resource) based on a conditional trigger but it looks like the module is getting fired before the logic is applied:
module "my_module" {
source = "${var.my_field == "" ? var.standard_repo : var.custom_repo}"
stuff...
more stuff...
}
I have created the standard_repo and custom_repo vars as well and defined with URLs for respective repos (using git:: -- this all works w/o conditional)
All this being said, anyone know of a way to implement this conditional aspect? (again, this is a module and not a resource)
I tried using duplicate modules and calling based off the var value but this, too, does not work (condition is never met, even when it is):
repo = ["${var.my_field == "na" ? module.my_module_old : module.my_module_new}"]
One way to achieve this is described in this post
Basically, a common pattern is to have several folders for different environments such as dev/tst/prd. These environments often reuse large parts of the codebase. Some may be abstracted as modules, but there is still often a large common file which is either copy-pasted or symlinked.
The post offers a way that doesn't conditionally disable based on variables but it probably solves your issue of enabling a module based on different enviornments. It makes use of the override feature of terraform and adds a infra_override.tf file. Here, it defines a different source for the module which points to an empty directory. Voila, a disabled module.
Variables are not allowed to be used in the module source parameter. There also does not seem to be a plan for this to change. https://github.com/hashicorp/terraform/issues/1439 . Creating a wrapper script , or using something like mustache http://mustache.github.io/ seems to be the best way to solve the problem.

Jenkins Extended Choice Parameter Plugin Groovy Script

So in the website for the plugin, the change-log for Version 0.61 (Mar 30, 2016) mentions that they have exposed Jenkins and project bindings for use in a groovy script. I'm currently trying to set a parameter (multi select) and i want it to have different options based on the value of another parameter which is set before this one in the Jenkins job. However i'm not able to get the value of that other parameter in the script.
My problem is very similar to the one explained here
I've tried using ${param}, $(param), $param, bindings.variables.get('param') in the script, and none of it works
I've also tried to set that parameter in the Variable bindings section of the script but still no success.
Any ideas about the correct way to obtain the value?
I set the variable binding as param on the other field that you want to dynamically populate and used param (please note that i didnt use $ ${} or binding.get etc). It worked for me.
As a side note, Will active choice reactive parameter work in your case?

Resources