IM's ENV Variables Handling

Request

We want to get rid of sensitive data (such as credentials) from application property files. It is a security risk because everything stored in a Git repository can be viewed by anybody in Pricefx company via gitgrep.

Solution

Store such data in secured environment (Hades) and pass them to IM as environment variables during the deploy time.

Implementation

On Hades server there is a binary application “imdeployer” and “database” (/root/bin/integration_managers.csv) of all IMs. It contains four columns.

ID

TARGET

DEPLOY_FUNCTION

ENV_VARS

ID

TARGET

DEPLOY_FUNCTION

ENV_VARS

arm_dev

node1.arm-qa.pricefx.net

deploy_im_standard_im_1_2_and_newer

 

watsco_qa

node1.watsco-qa.pricefx.net

deploy_im_standard_openjdk11andnewer

 

dn_dev

node1.dn-qa.pricefx.net

deploy_im_standard_im_1_2_and_newer

integration.pfx.url=https://dn-qa.pricefx.com/pricefx,integration.pfx.username=integration,integration.pfx.partition=dn-dev,integration.pfx.password=SecretPass

tfg_prod

node1.tfg.pricefx.net

deploy_im_standard

 

Notes:

  • ID – Has to be unique. In this case it is tfg_prod.

     

  • TARGET – It is Salt’s minion ID. Usually it is real server hostname.

  • DEPLOY_FUNCTION – Deploy function defines the .conf file on the server and its content.
    For example, deploy_im_standard function will create the following .conf file:

    salt $TARGET cmd.run "/bin/echo -e 'JAVA_OPTS=\"-Xmx${MAX_HEAP_SIZE} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/pricefx/runtime/${2} -Xloggc:gc.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=5M -Dfile.encoding=UTF-8 -Dspring.cloud.config.enabled=false -Dspring.profiles.active=${3}\"\nidentity=${2}\nLOG_FOLDER=/dev\nLOG_FILENAME=null' > /var/pricefx/runtime/${2}/${2}.conf"


    deploy_im_standard_im_1_2_and_newer creates a different .conf file:

    salt $TARGET cmd.run "/bin/echo -e 'JAVA_OPTS=\"-Xmx${MAX_HEAP_SIZE} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/pricefx/runtime/${2} -Xloggc:gc.log -XX:+PrintGCDetails -Dfile.encoding=UTF-8 -Dspring.cloud.config.enabled=true -Dlogging.file.name=main.log -Dspring.profiles.active=${3}\"\nidentity=${2}\nLOG_FOLDER=/dev\nLOG_FILENAME=null\nJAVA_HOME=/usr/lib/jvm/java-openjdk' > /var/pricefx/runtime/${2}/${2}.conf"

    As you can see, both .conf file vary. We cannot use some Java properties in open-jdk11 as in oracle-java 7 etc.

  • ENV_VARS – Here is the place for your custom environment variables. It is just a string delimited by comma “,”.

Do not use delimiter [, or ; ] in the data.

 

Now, take a look at arm_dev and dn_dev. One has something in env_variables and the other does not.

Final .conf file for arm_dev:

root@node1.arm-qa.pricefx.net /var/pricefx/runtime/im-arm-dev # cat im-arm-dev.conf JAVA_OPTS="-Xmx4G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/pricefx/runtime/im-arm-dev -Xloggc:gc.log -XX:+PrintGCDetails -Dfile.encoding=UTF-8 -Dspring.cloud.config.enabled=true -Dlogging.file.name=main.log -Dspring.profiles.active=arm_dev" identity=im-arm-dev LOG_FOLDER=/dev LOG_FILENAME=null JAVA_HOME=/usr/lib/jvm/java-openjdk root@node1.arm-qa.pricefx.net /var/pricefx/runtime/im-arm-dev #

Final .conf file for dn_dev:

Based on this you can see that we can now remove properties from the application property file and it will still work.

No more credentials in Git.

Benefits

  • All IM data in one secured place.

  • No more 1200 lines and more of IF statements in the deploy_jenkins_job script.

  • Possibility to define fine grained environment variables.

  • Possibility to mass edit IM properties (such as password change on Pricefx side – now you will change it in “database” and restart IM. Integration Engineers do not need to even know about it and there is no need to change it in the application properties and do the commit.)

  • Easier transfer to AWS (Kubernetes could take a look at that database as well and provide those ENV variables directly to the container in the same way as it salt does it now).

Integration Engineer Instructions

Data which you consider to be sensitive should be moved to ENV variables and removed from application properties.

Create a helpdesk ticket where you will define that you want, for example, to specify a new ENV variable for Salesforce password.

Then you can remove that line from your property file or remap it if needed:

Once Ops/Support add it to the database, you will end up with .conf file like this:

Ops/Support Instructions

Lets assume you have received the above request.

  1. Open the “database” file on Hades (currently it is /root/bin/integration_managers.csv).

  2. Navigate to the line which starts with “arm_dev”.

  3. It will look like this (example):

    There are no ENV variables yet.

  4. Let’s add the requested one:

  5. Save it and you’re done.

 

If you receive another request asking you to specify a new environment variable such as “test=test”, then you will do:

Just use “,” as the ENV variables delimiter.

 

Do not create new records for IMs in those IF conditions anymore. Add a line to the database file instead. You can use “imdeployer” CLI.

IM Deployer CLI

There is a binary application called “imdeployer” which is located next to the database file (/root/bin/imdeployer). It serves as a layer between deploy_jenkins_job and CSV DB file. Its purpose is to handle data validation, errors, commented (disabled) records and to resolve proper records. You can see examples in its Git repository (https://gitlab.pricefx.eu/integration/imdeployer).

Conclusion

This solution brings a lot of improvements in security and code organization as well as in design and future usage.

It is backward compatible and if it will not find anything in the DB file, it will continue to search for it in IF statements.

There is no need to change anything on IM side.

IntegrationManager version 5.8.0