AWS Elastic Beanstalk environment variables overriding at the EB application level - node.js

I am currently running the same NodeJS Sails app on two different "environments" within the same Elastic Beanstalk "application" (AWS-specific terms in quotes). My intention was for these "environments" to serve as staging and production. Sails provides a built-in method for swapping configs based on the environment variable NODE_ENV. However, when I set the environment variable in one "environment," it overrides the value for the other.
I have tried using the AWS CLI command eb setenv NODE_ENV="environment_name" as well as using the web interface. (The setting in question is at Application > Environment > Configuration > Software Configuration under the "Environment Properties" header.)
I have been trying to search for this issue, but I have been having a hard time finding anything that addresses it specifically. Answers like the selected one here imply that it is possible to do what I am looking for.
Is there something wrong with the way I am setting this variable? Am I misunderstanding how Elastic Beanstalk handles these settings? I understand that I can also set environment variables by changing the .ebextensions file for different deploys, but I would prefer a cleaner fix.
As requested, here is the output from eb status and eb list (actual application name replaced):
$ eb status
Environment details for: app-staging
Application name: app
Region: us-east-1
Deployed Version: 1.1.0
Environment ID: e-fxxxxxxxxx
Platform: 64bit Amazon Linux 2015.03 v2.0.1 running Node.js
Tier: WebServer-Standard
CNAME: app-staging.elasticbeanstalk.com
Updated: 2015-12-08 03:54:37.894000+00:00
Status: Ready
Health: Green
$ eb list
app-production
* app-staging

It turns out this issue was happening because the AWS web interface was not keeping up with the changes I was making. The environment variables were not being overridden. Logging out and back in fixed this for me.
I have noticed that, in general, many perceived issues on AWS may be fixed in this way.

Related

Deploy Node.js application to AWS Elastic Beanstalk from Bitbucket using AWS CodePipeline

I'm writing this post after exhausting all the options I could try.
Scenario:
I want to deploy a lightweight backend logic written in Node.js (using JavaScript, Express.js, MongoDB).
Platforms considered:
AWS (preferred)
Heroku
Bitbucket Pipelines (least preferred)
Currently it's deployed on Heroku (and running as expected), but I want to deploy it on our preferred platform, i.e., AWS. Also, I want the whole deployment process to be automated (using Continuous Delivery/Deployment).
To achieve that, I created:
A fresh Node.js environment (v16.0, platform v5.6.0) on Elastic Beanstalk
A new CodePipeline:
Source: Bitbucket
Repository (cloned from here)
Change detection options: Start the pipeline on source code change
Output artifact format: CodePipeline default
Build stage: skipped
Deploy provider: AWS Elastic Beanstalk (with correct region, app and env name)
Outcome on every try:
On the first try when the environment gets created, we get greeted with the default screen:
After subsequent commits, things like this start to show up:
Error pages with error codes in the series of 400s and 500s:
To overcome those problems, I scratched all the blog posts and support articles available regarding those issues and followed the steps thoroughly gaining no success in the end.
Some of the (many) solutions I tried:
Create a Procfile with the the params
Write app.js/index.js outside the src/ (dumb thing, I know)
Switch to immutable deployments (as mentioned here)
I seriously need help resolving this issue. Any help or guidance towards some solution would be greatly appreciated.

How do I design my NodeJS app to have one config (per env) that can work for both K8S and locally in debugger?

I've been using K8S for a year or so and continue to revisit a problem.
My app is running in K8S and I now need to debug it. I have a NodeJS App that I'm asking about. But similar questions could be asked about Java SpringBoot apps (but this question is just for NodeJS).
I want to use my favorite IDE (IntelliJ or VSCode) to run the app but the app is currently getting it's configuration (inside K8S) using ConfigMaps and Secrets.
(Q) Is there a "best practice" or "pattern" that can be followed that supports the DRY principle and has configuration in one place that can be used for both K8S and when running locally.
Background
I have a NodeJS app that I decided to use ENVIRONMENT variables to hold configuration information because that worked well in IntelliJ IDE, in Docker and in K8S.
I used npm dotenv and created .env.local, .env.stage, .env.prod files to support running in different environments. This worked well enough until it was running in K8S and someone wanted to tweak the configuration and didn't believe that rebuilding the image was the best way to support this. Instead the K8S experts told me I should use ConfigMaps and Secrets, so I converted from the dotenv approach to use the K8S ConfigMaps and Secrets.
I kept the old .env files around just in case and I can use them but the source code no longer call uses dotenv package.
require('dotenv').config()
process.env.myConfigVariable
So I need to either add that code back to support debugging, or manually set the environment variables. I'm wondering if there is a better approach.
I have yaml files templates to make it easy to recreate the deployment from scratch if/when needed.
.env.local
deploy/
helm/
create-configmap.yaml
create-secret.yaml
src/
common/*
appMain.js
Some of the approaches I've considered:
(a) Accept it and have two configs (one for local and one for K8S). Leave the code for dotenv but don't deploy a .env file when deploying to K8S.
(b) Run local k8s (like minikube or k3s) and use my ConfigMap and Secrets as I would with K8S. I then need to figure out how to connect from my IDE to the local K3S environment and open ports in the k3s environment to support this. Some solutions include: Bridge to Kubernetes, YouTube Video Remote Debugging in Kubernetes with Cloud Code,
Debug Java Microservices in Kubernetes with IntelliJ, and I'm sure several others.
(c) Use a JSON config file instead of dotenv. For example, use a JSON config file for everything and map that to /app/config.json and that same config file can be used in both environments. I could have config-local.json, config-stage.json, and config-prod.json to support the different environments.
(d) You tell me. What's another way?
Thanks!

How environment variables are used when deployed on aws

I am building a web application that utilises environment variables locally, and I want to put this on production (online). I am trying to find out how to set environment variables on AWS.
This is a node.js application and I am using elastic beanstalk on AWS for deployment. I have looked through https://docs.aws.amazon.com/cloud9/latest/user-guide/env-vars.html#env-vars-env-list , but I'm unsure of which option applies to me.
The .env file I have locally contains lines like
PASSWORD=MYPASSWORD
and I am using the dotenv package, with require('dotenv').config(); in the appropriate files. I am accessing environment variables in my code through things like process.env.PASSWORD (using the aforementioned example of a line in the .env file).
I've tried searching several places and am presented with various options, but I'm not sure which one applies to my environment variables.
The link you are following may help you in ec2 machine that is mangages by you, but if you are working Elasticbeanstalk I will recommend using Environment variable configuration provided by elasticbeanstalk.
I am not in favour of .env in case of Elasticbeanstalk, ECS and many other services where AWS provide easy and out of the box feature to set environment variable in the configuration and .env write environment to file which is less secure then system environment variable.
The interesting part of Elasticbeanstalk ENV is, the system environment variable has higher periphery then .env environment variable but better to not place dotenv on elasticbeanstalk.
Environment Properties and Other Software Settings
You can use environment properties to pass secrets, endpoints, debug
settings, and other information to your application. Environment
properties help you run your application in multiple environments for
different purposes, such as development, testing, staging, and
production.
elasticbeanstalk-deploy_nodejs
Example .ebextensions/options.config
option_settings:
aws:elasticbeanstalk:application:environment:
API_ENDPOINT: www.example.com/api
Now all you need
var endpoint = process.env.API_ENDPOINT
Environment Properties
The Environment Properties section lets you specify environment
configuration settings on the Amazon EC2 instances that are running
your application. These settings are passed in as key-value pairs to
the application.
Inside the Node.js environment running in AWS Elastic Beanstalk, you
can access the environment variables using process.env.ENV_VARIABLE
similar to the following example.
var endpoint = process.env.API_ENDPOINT

How to manage .env configuration in continous integration

I develop an application with nodejs and react. I use dotenv for configuration in my different environment.
I use TFS 2017 for build and release my application.
What is the best practise for add my .env file of production environment?
Production configs can be difficult to maintain. You can use any module or even write your own custom module to load environment variable in to your application.
However, maintaining production .env files locally for each product (i.e. committing them or putting them inside your docker image is a bad idea. If you ever happen to change some of those configs, you will have to manually change in the code for each application, build docker image (if required) and redeploy. If there are just a couple of applications, it might be easy. But if the number of related applications grow in size (as usually happens in case of microservice based architecture) - all of them sharing credentials, ips for database connections etc. it becomes a hectic task to manually change code and redeploy all the applications.
Usually, developers tend to keep a central repository of all credentials and environment variables. For examples, AWS offers parameter store and MS Azure offers Azure Key vault. In such a case, all the parameters are fetched during start time, and all we have to do is restart the application.
So usually people set only one global varibale NODE_ENV (as prod or dev), dynamically fetch all environment variables based on NODE_ENV running something like env $(node read-env-variables.js) node app.js.

Configure application on Google Cloud Platform with environment variables

I'm a newbie with Google Cloud App Engine and I want to deploy my simple Node.js application. I need to configure it for "production" environment. For example, I want to provide some credentials for email box, which my application is going to query for new emails.
I like to use nconf npm package, it gives me powerful and flexible configuration via command-line arguments or environment variables. I don't need to hard-code possibly secure values in source code.
Is there a way to configure environment variables or command-line arguments for an application in Google Developer Console?
P. S.
I found from documentation, that one can inline environment variables in app.yml config file:
env_variables:
FOO: 'myapp.bar'
But this is still not suitable for me, since app.yml is staged in git.

Resources