1

Although I am not familiar with DevOps best practices, I am trying to come up with a reliable and efficient method for managing multiple variables in production. The following represents my current approach:

/
|ENV_VAR.sh
|--/api1
|--/staging.api1
|--/api2
|--/staging.api2

Where:

ENV_VAR.sh

### API 1 variables ###
export API1_VAR_1=foo
export API1_VAR_2=foo2
export API1_STAG_VAR_1=foo_stag
export API1_VAR_2=foo2_stag2

### API 2 variables ###
export API2_VAR_1=foo
export API2_VAR_2=foo2
export API2_STAG_VAR_1=foo_stag
export API2_VAR_2=foo2_stag2

The API 1 and 2 are two nodejs-based apps running in the same server using a reverse-proxy configuration. If nothing goes bad with the server (e.g. unexpected shutdown), I just have to (re)set the variables once in a while via SOURCE ENV_VAR.SH in order to make sure that new variables are defined.

Before proceeding with this approach, I would like to know whether it is correct at all, or if it has a big flaw. If this approach is alright, how to automatically (re)source the environment variables from the package.json whenever a new version of any App is deployed? (just to guarantee that the variables are still defined)

Thanks in advance.

O. Jones
  • 103,626
  • 17
  • 118
  • 172
vtolentino
  • 754
  • 5
  • 14
  • Afternoon. This is a bit of a broad question, how are you currently deploying to your production and staging environments? – razki Apr 10 '20 at 12:27
  • I am currently using a `yml` file configured for each environment, which is then processed via GitLab. Once the corresponding branch is updated, a new pipeline is created and the the app it copied to the server. I then access the server and start / manage the apps vias `pm2` package. – vtolentino Apr 10 '20 at 12:37

1 Answers1

0

I like using Loren West's config package for these configuration parameters. I happen to like to extend it with the properties package: that way I don't have to put parameters in valid, comment-free, JSON format. JSON5 also helps solve the readability problem, but I haven't tried it.

Why do I like this?

  1. It gives a structured way of dealing with development / test / staging / production environments. It keys off the ENV environment variable, which of course has values like development and production.

  2. All properties files go into a single directory, typically ./config. Your production krewe can tell what they're looking at. default.properties, development.properties and production.properties are the names of typical files.

  3. Most configuration parameters don't have to be secret, and therefore they can be committed to your repository.

  4. Secrets (passwords, connection strings, API keys, etc) can be stored in local.properties files placed into ./config by your deployment system. (Mention local.properties in your .gitignore file.)

  5. Secrets can also be loaded from environment variables, named in a file called ./config/custom_environment_variables.json.

  6. It works nicely with pm2.

This is really easy to configure.

Your files:

 default.properties   (used when not overridden by another file)
 [API1]
 VAR_1 = foo
 VAR_2 = foo2
 [API2]
 VAR_1 = foo
 VAR_2 = foo_for_api2

 staging.properties
 [API1]
 VAR_1 = foo_stag
 VAR_2 = foo2_stag2
 [API2]
 VAR_1=foo_stag
 VAR_2=foo2_stag2

 custom_environment_variables.json
 {
   "API1" : {
     "password": "API1_PASS"
   },
   "API2" : {
     "password": "API2_PASS"
   }
}

Your nodejs program:

const config = require( 'config' )
require( 'properties' )
const appConfig = config.get( 'API1' )

const var1 = appConfig.VAR_1
const password = appConfig.password

Then you run your program with API1_PASS=yaddablah nodejs program.js and you get all your configs.

O. Jones
  • 103,626
  • 17
  • 118
  • 172
  • Thanks for the quick reply. I guess I misundertood something. Since the `custom_environment_variables.json`, `staging.properties` and `default.properties` are used for both apis, where would they be located? P.S.: Each api has their own nodejs instance running in parallel and managed via `pm2`. – vtolentino Apr 10 '20 at 15:20
  • You have a couple of choices about the two-api situation. One is to maintain a separate config directory for each one. It's still an improvement because most of your configs aren't secret. The second choice is to keep a separate git repo for your config directory, and load it as a git submodule into the repos for your two projects. https://git-scm.com/book/en/v2/Git-Tools-Submodules I bet your devops krewe will like the second choice. – O. Jones Apr 10 '20 at 15:53