How can I set NODE_ENV permanently with ansible? - node.js

I have 2 machines for my two environments.
The first one hosts a staging environment. It needs to have NODE_ENV set to dev.
The second one hosts a production environment. It needs to have NODE_ENV set to prod.
I provision my servers with Ansible.
How can I do this ?

Another option is set NODE_ENV at /etc/environment file.
In ansible tasks:
- lineinfile: dest=/etc/environment line="NODE_ENV=dev"

I solved the problem like so.
In roles/node-env/tasks/main.yml :
---
- name: Configure NODE_ENV
lineinfile: dest=/etc/environment regexp="^NODE_ENV=" line="NODE_ENV={{ node_env }}"
when: node_env is defined
In hosts/staging:
[webserver]
staging-server-hostname
[webserver:vars]
node_env=dev
In hosts/production:
[webserver]
production-server-hostname
[webserver:vars]
node_env=prod
In playbook.yml:
---
- name: Provision web server
hosts: webserver
sudo: true
roles:
- { role: Stouts.nodejs, tags: nodejs }
- ...
- { role: node-env, tags: nodejs }
Then I provision my staging environment with:
ansible-playbook -i hosts/staging playbook.yml
And my production environment with:
ansible-playbook -i hosts/production playbook.yml
Note that I stored my environment variable in /etc/environment because I wanted this variable set one for all and for every users.
This can also be stored in ~/.profile or in /etc/profile.d according to your needs. See this answer for more information.
It might be overkill, but it's flexible. If anyone has a simplier suggestion don't hesitate to share!

Related

How Nodejs process.env works

I have a ENVIRONMENT Variable , which resolves the current stage inside the container in kubernetes.
when i refer the variable inside code it always prints "dev" even when the actual value refers to "stage". inside container .
my helm variables :
profiles:
- node
owner:
group: gcp-admin # change to your own group
notify:
slack:
channelName: XXXXXXXX-ingestion # change to your own slack channel
build:
docker:
app:
runtime: node
buildArgs:
nodeVersion: 14.17.1
buildDir: '.'
deploy:
helm:
values:
env:
ENVIRONMENT: stage
my java script code goes like this..
env: process.env.ENVIRONMENT
when i write console.log(env) it always prints dev.
the below image is what i get when i run describe pod
Seems your configuration looks old (verify the version). You can refer to the below doc.
env:
- name: ENVIRONMENT
value: "stage"
Read more here:
https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/
https://phoenixnap.com/kb/helm-environment-variables
I did something similar but env name was “APP_ENV” instead and it works
helm:
values:
env:
APP_ENV: "staging" // or "development" or "production"
and in code
if (process.env.APP_ENV == "staging") {

NodeJS: How to include environment variable from CircleCI into the application

In my front end application, I'm storing sensitive information in the environment and using them as following:
const client_secret = process.env.CLIENT_SECRET;
On local development, I use dotenv package to pass in the values in .env file
CLIENT_SECRET=XXXXX
The .env file is not committed.
I use CircleCI for my deployment process, and saved the CLIENT_SECRET value in CircleCI environment variables, but how can I pass into the application?
This is my CircleCI config.yml:
- deploy:
name: Deploy
command: |
ENVIRONMENT=${ENVIRONMENT:=test}
VERSION=`date "+%Y-%m-%dt%H%M"`
if [ "${ENVIRONMENT}" = "production" ]; then
APP_FILE=app-prod.yaml
else
APP_FILE=app.yaml
fi
gcloud app deploy ${APP_FILE} --quiet --version ${VERSION}
I can do this in app.yaml:
env_variables:
NODE_ENV: 'production'
CLIENT_SECRET: XXXXX
But I don't want to include the sensitive information into the .yaml file and commit them. Does anyone know any way I can pass environment values into the application?
I'm using Google Cloud Platform, and gcloud app deploy command doesn't seem to have a flag to include the environment variables.
Using bash script to create a .env file with environment variables manually
app.yaml.sh
#!/bin/bash
echo """
env: flex
runtime: nodejs
resources:
memory_gb: 4.0
disk_size_gb: 10
manual_scaling:
instances: 1
env_variables:
NODE_ENV: 'test'
CLIENT_SECRET: \"$CLIENT_SECRET\"
"""
config.yml
steps:
- checkout
- run:
name: chmod permissions
command: chmod -R 755 ./
- run:
name: Copy across app.yaml config
command: ./app.yaml.sh > ./app.yaml
- deploy:
name: Deploy
command: |
VERSION=`date "+%Y-%m-%dt%H%M"`
gcloud app deploy app.yaml --quiet --version ${VERSION}
Reading about it, it's indeed, as you mentioned, that the only "official" way to set environment variables, it's by setting them in the app.yaml - this article provides more information on it. Considering that, I went to search further and I have found this good question from the Community - accessible here - where some workarounds are provided.
For example, the one that you mentioned, about creating a second file with the values and call it in the app.yaml is a good one. You can them use the .gitignore for the file not exist in the repository - in case you are using one. Another option would be to use Cloud Datastore to store the information and use it in your application. This way, Datastore would keep this information secured and accessible for your application, without becoming public within your App Engine configuration.
I just thought a good idea of adding this information here, with the article and question included, in case you want more information! :)
Let me know if the information helped you!

How to run a playbook task based on OS type in ansible?

I have written a playbook task in ansible. I am able to run the playbook on linux end.
- name: Set paths for go
blockinfile:
path: $HOME/.profile
backup: yes
state: present
block: |
export PATH=$PATH:/usr/local/go/bin
export GOPATH=$HOME/go
export FABRIC_CFG_PATH=$HOME/.fabdep/config
- name: Load Env variables
shell: source $HOME/.profile
args:
executable: /bin/bash
register: source_result
become: yes
As in linux we have .profile in home directory but in Mac there is no .profile and .bash_profile in macOS.
So I want to check if os is Mac then path should be $HOME/.bash_profile and if os is linux based then it should look for $HOME/.profile.
I have tried adding
when: ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'precise'
But it does not work firstly and also it is length process. I want to get path based on os in a variable and use it.
Thanks
I found a solution this way. I added gather_facts:true at top of yaml file and it started working. I started using variable as ansible_distribution.
Thanks
An option would be to include_vars from files. See example below
- name: "OS specific vars (will overwrite /vars/main.yml)"
include_vars: "{{ item }}"
with_first_found:
- files:
- "{{ ansible_distribution }}-{{ ansible_distribution_release }}.yml"
- "{{ ansible_distribution }}.yml"
- "{{ ansible_os_family }}.yml"
- "default.yml"
paths: "{{ playbook_dir }}/vars"
skip: true
- name: Set paths for go
blockinfile:
path: "$HOME/{{ my_profile_file }}"
[...]
In the playbooks' directory create directory vars and create files
# cat var/Ubuntu.yml
my_profile_file: ".profile"
# cat var/macOS.yml
my_profile_file: ".bash_profile"
If you have managed hosts with different OS, group them by OS in your inventory:
[Ubuntu]
ubu1
ubu2
[RHEL6]
RH6_1
[RHEL7]
RH7_1
RH7_2

How to set environment variables of remote hosts

I am having problems working with the environment variables of a remote host. For example, when I try {{ lookup('env', 'PATH') }} this returns the path of my guest machine not of the remote host.
How to pick up / change environment variables of the remote host?
my playbook :
---
- name : playbook
hosts : webservers
gather_facts: yes
remote_user: user1
vars:
Path: "{{lookup('ansible_env','PATH')}}"
roles :
- task1
- task2
- task3
that's return the path of my machine not the path of remote host named user1
i'm a beginner in ansible need some help .
thank you in advance.
You can set the PATH for a task or a playbook by using the environment keyword.
environment:
PATH: "{{ ansible_env.PATH }}:/thingy/bin"
SOME: value
The Ansible FAQ mentions this near the top http://docs.ansible.com/ansible/faq.html
So in your case try something like the following:
- name: Set Path for java
environment:
PATH: "$JAVA_HOME/bin:{{ ansible_env.PATH }}"
Setting the environment reference: http://docs.ansible.com/ansible/playbooks_environment.html

Amazon Elastic Beanstalk .config for node 64bit & env

Here is an excerpt of my EB configuration file .ebextensions/app.config:
option_settings:
- option_name: AWS_SECRET_KEY
value: xxxxxxxxxx
- option_name: AWS_ACCESS_KEY_ID
value: xxxxxxxxxx
- option_name: APP_ENV
value: development
- namespace: aws:elasticbeanstalk:container:nodejs
option_name: ProxyServer
value: nginx
- namespace: aws:elasticbeanstalk:container:nodejs
option_name: GzipCompression
value: true
- namespace: aws:elasticbeanstalk:container:nodejs
option_name: NodeVersion
value: 0.8.10
- namespace: aws:elasticbeanstalk:container:nodejs
option_name: NodeCommand
value: npm start
commands:
test_command:
command: echo $APPLICATION_ENV > /home/ec2-user/test.txt
cwd: /home/ec2-user
ignoreErrors: true
then I do the normal thing:
$ git commit -am "wrote config file"
$ eb init
...
$ eb start
...
would you like to use the most recent commit [y/n]
$ y
Then after deploy is complete and in green state, looking inside the eb generated .elasticbeansalk/optionsettings.myapp-env file I found:
[aws:elasticbeanstalk:application:environment]
PARAM1=
PARAM2=
PARAM3=
PARAM4=
PARAM5=
[aws:elasticbeanstalk:container:nodejs]
GzipCompression=false
NodeCommand=
NodeVersion=0.8.24
ProxyServer=nginx
My environment variable was not set, the NodeCommand directive was not set, and the NodeVersion has been ignored. What gives, EB? How can it ignore certain directives and not others? Any ideas on what I'm doing wrong?
EDIT
according to this post, the JSON holding the environment variables is held here:
/opt/elasticbeanstalk/deploy/configuration/containerconfiguration
which means I can parse this fiel for the variables, but this is frustrating since it's supposed to be taken care of with the configuration file (otherwise why have one?). There still must be an issue with my configuration file, otherwise EB seems completely broken in this respect...
I've run into this problem as well. I believe there are 2 ways to solve it.
Run "eb update" this should update your environment and hopefully grab the variables.
Create a new env and deploy your code into that environment. Once everything is good then point dns at the new env and delete the old one.
Also I read somewhere (aws forum I believe) that if you update the env in the elastic beanstalk gui interface that those values will take precedence over anything you put in the source code.

Resources