ansible variable scope not broad enough - scope

I have a role called get_install_command that runs a local python script which returns a command that needs to be run on a remote server. The role get_install_command sets a variable called "install_command" which the role "install" attempts to use. Here is my code:
- hosts: localhost
roles:
- get_install_command
- hosts: remote_host
roles:
- install
however I get this error:
"installation_command.stdout_lines": "VARIABLE IS NOT DEFINED!"
What should I do to fix this? It seems to me that I need to put this variable in a higher scope

Variables defined in a play using register or set_fact are scoped to the host on which the task is running. So since you run get_install_command on localhost, the install_command variable is available on localhost.
The documentation covers how to access variables defined on another host. You want something like this:
hostvars.localhost.install_command.stdout

Related

How to update PATH environment variable while deploying in Cloud Foundry

I want to deploy my Node.js application in Pivotal Cloud Foundry using manifest.yml. I need to update the PATH variable of the container before the application starts, to include the path of a directory in my application's src directory. Can this be achieved?
manifest.yml:
---
applications:
- name: node-apollo-graphql-server
command: npm start
instances: 1
memory: 512M
buildpack: dicf_nodejs_buildpack_rc
stack: cflinuxfs3
You cannot do this by setting env variables with cf push -e or the env: block in manifest.yml. If you set path using one of these methods, you'll override path when what you likely want to do is append to it.
To append to $PATH, add a file .profile to the root of your project (directory from which you're running cf push). In that file, put one line export PATH=$PATH:<new loc> where <new loc> is the path you want to append to the $PATH env variable.
The .profile file is sourced before your application starts so you can use this to dynamically set environment variables or apply configuration before your application starts up.
The only caveat is that this happens before your application starts so it blocks the starting of your application. As such, you should avoid running expensive/time-consuming processes here. Otherwise, you will delay the start of your application, or possibly even cause app failures if you exceed the startup timeout (cf push -t).

How can I make node application see system variables on Google Cloud?

I have variable set in my .bash_rc file:
whoami#cloudshell:~/source/NodePrototype (x-alcove-9999999)$ echo $APP_ENVIRONMENT
LIVE
Yet node.js application out of:
const app_environment_config=require('./APP_ENVIRONMENT/' + process.env.APP_ENVIRONMENT)
produce
2019-02-21 14:18:16 default[20190221t141628] Error: Cannot find module './APP_ENVIRONMENT/undefined'
Eventhough when I enter node shell:
whoami#cloudshell:~/source/NodePrototype (x-alcove-9999999)$ node
> process.env.APP_ENVIRONMENT
'LIVE'
The same part works locally.
It depends on how your Node app is being launched, because looks like is not running in an environment where that variable exists, to make sure print all your current env vars to make this sure: console.log(process.env).
Also, a good practice, when you need something like that, is to use .env files with this module: https://www.npmjs.com/package/dotenv is a good practice to pass configuration to your Node apps.

Variable substitutions in docker-compose in Azure Docker Web app

I have a docker-compose file that contains a secret for my database.
port: 4466
managementApiSecret: ${DB_SECRET}
So I would like to use Docker-Compose's Variable Substitution (https://docs.docker.com/compose/compose-file/#variable-substitution) to be able to provide my secrets through an environment variable instead of my yaml file.
Is this at all possible using the "Application Settings" variables on my Azure Linux Docker Instance?
It doesn't seem to work for me, I've tried both ${VAR} and $VAR syntax and neither worked. I also tried with secrets that only contain alphanumerics and numbers.
Thanks in advance.
Frank
Environment variables that you need to start the container (for example: you want to include build number in container name) can be added to .env file in same directory as the docker-compose.yml file.
sample .env file:
DB_SECRET=foo
run: docker-compose config and verify that the variable has been substituted with the value you have in .env file
Also, I recommend using managementApiSecret:"${DB_SECRET}" (note the quotes around the variable) in your docker-compose.yml file
There might be azure specific way to share secrets but I didn't try that yet.
If you want to pass in environment variables that the container needs, then https://docs.docker.com/compose/compose-file/#env_file is what you want. Those environment vars will become part of environment inside docker container.

Gitlab-CI Kubernetes integration: variables not set

I have an issue with kubernetes variables not set in Gitlab-CI.
There's another issue, but it talks about the "old" integration, not the latest that works differently.
So here's the thing. I have a free account, and a kubernetes cluster configured. Everything works fine, the cluster is correctly configured, Helm Tiller, Prometheus and Gitlab-CI-Runner have been installed, and the runner is used to execute the jobs.
Since it's a free account, I can add only one cluster with a * scope, and the documentation says that the following variables should be available through any job:
KUBE_URL
KUBE_TOKEN
KUBE_NAMESPACE
KUBE_CA_PEM_FILE
KUBE_CA_PEM
KUBECONFIG
But none of them are set, the following job echoes nothing, except the CI_PROJECT_ID:
build_backend:
stage: build
except: [ tags ]
script:
- echo CI_PROJECT_ID=$CI_PROJECT_ID
- echo KUBE_URL=$KUBE_URL
- echo KUBE_CA_PEM_FILE=$KUBE_CA_PEM_FILE
- echo KUBE_TOKEN=$KUBE_TOKEN
- echo KUBE_NAMESPACE=$KUBE_NAMESPACE
- echo KUBE_CA_PEM=$KUBE_CA_PEM
- echo KUBECONFIG=$KUBECONFIG
I was not able to find any lead (except the obsolete issue referenced above), but as it's quite recente, I could not make the difference between it has not been tested yet or I'm the only one having the issue
Thanks for any help!
Ok, I can confirm this is a duplicate of this and that the provided solution does indeed work.
Add this to your job:
environment: 'production'
production being the name of an environment (you can create it before in the dedicated screen, but it's not necessary).

process.env.PATH undefined in Passenger node app (production mode)

I recently deployed a node application with Phusion Passenger for nginx, and encountered a pretty quirky error in the process:
My code threw an error from trying to spawn a child_process. I did a bit of debugging and eventually concluded that the problem arose from the $PATH environment variable being undefined in node, and I could solve the problem with a passenger_env_var directive like this (showing an extract of my nginx config):
server {
listen 80;
server_name blargh.com;
root /home/user/blargh.com/build;
passenger_enabled on;
# For some reason $PATH isn't loaded into node, and we can't spawn child processes without it
passenger_env_var PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games;
}
I still haven't figured out what caused this problem though - setting passenger_load_shell_envvars on; didn't help, and the www-data user did have a $PATH envvar defined in the shell. Moreover, other environment variables (like $SHELL) seems to have been loaded by node, adding to the mystery of why $PATH was excluded.
Does anybody know what could cause this problem?
tl;dr
Specify global envvars that you expect to be defined at system boot (like PATH) in /etc/default/nginx. Use something like dotenv properly and write environment specific config for your app in a text file that's not checked in. Environment variables are pretty evil in general.
I felt this one deserved a fairly lengthy answer, since environment variables has caused recurring problems for me during the last couple of months.
Storing your config as environment variables is one of the rules that 12 factor app lays out for writing scalable web applications. They're good because they let you separate your config from your code in a flexible manner. However, a problem with them is that the way we encounter them normally, when we export MYVAR=myvalue or set them in our ~/.pam_environment or ~/.bashrc, the scope of them is our current terminal session.
This causes issues as we start to use solutions like Phusion Passenger to start our apps at system boot - their startup scripts don't care about user shell environments. They also don't care about the global /etc/environment apparently, which is what caused my problems with PATH being undefined.
Phusion Passenger actually has some documentation on making global environment variables persist:
If you installed Nginx through the Debian or Ubuntu packages, then you can define environment variables in /etc/default/nginx. This is a shell script so you must use the export FOO=bar syntax.
So by setting the PATH envvar in /etc/default/nginx, I could solve that issue. But I was still having trouble with the other environment variables - I had to set them in my nginx config to have them passed on to my node app. It was clear to me that this wasn't the right way to do it.
At this point I was already using dotenv, but I had misunderstood its purpose slightly. I had checked in the .env file and thought of it as a way to provide default values for envvars that would be overridden by the environment as needed. This isn't how the authors themselves envisioned this module to be used:
We strongly recommend against committing your .env file to version control. It should only include environment-specific values such as database passwords or API keys.
It started becoming clear to me that people often don't define the envvars for their apps in the actual environment. I found an article by Peter Lyons that suggests storing config in a text file instead of in envvars, and that's when it clicked for me.
My final solution was to uncommit my .env file, and write a specific one for each environment. I left a .env.template in my repo as a reference to what configuration my app expected to be defined at run-time.

Resources