Accessing user provided env variables in cloudfoundry in Spring Boot application - cloud-foundry

I have the following user provided env variable defined for my app hosted in cloudfoundry/pivotal webservices:
MY_VAR=test
I am trying to access like so:
System.getProperty("MY_VAR")
but I am getting null in return. Any ideas as to what I am doing wrong would be appreciated.

Environment variables and system properties are two different things. If you set an environment variable with cf set-env my-app MY_VAR test then you would retrieve it in Java with System.getenv("MY_VAR"), not with System.getProperty.
A better option is to take advantage of the Spring environment abstraction with features like the #Value annotation. As shown in the Spring Boot documentation, this allows you to specify values that get injected into your application as environment variables, system properties, static configuration, or external configuration without the application code explicitly retrieving the value.

Another possibility leaning on Scott Frederick's answer (sorry, I can't comment on the original post):
User provided env vars can easily be accessed in the application.yml:
my:
var: ${MY_VAR}
You can then use the #Value-Annotation like this:
#Value("${my.var}")
String myVar;

Related

When building NestJS, environment variables are not defined on a particular controller

App.module defines environment variables to be used globally.
For other controllers, environment variables are well applied when building.
Only a specific controller (user.controller) is not defined.
Instead, call user.controller via api after build, and you will see the environment variable log.
Please tell me why.
https://github.com/yj2dev/Lightning-marketplace-Clone
https://github.com/yj2dev/Lightning-marketplace-Clone
just don't use process.env directly whenever possible. Use some provider like ConfigService from #nestjs/config. Read the docs site. Otherwise you'll need to use dotenv like any other nodejs project

Why do people use .env file on server?

Why do people put a .env file to store all their secrets in a server? If someone hacks it, isn't the .env equally accessible as all the other files? Thanks!
You are correct that storing environmental secrets in a .env file poses a risk of plain text secrets being exposed to a third party if they gained access to raw code.
Just like other areas with sensitive material there are ways to get around this, generally an approach that people might take it to use a secrets management system which instead replaces any secrets values from a .env file to be accessed via a validated request.
AWS supports a couple of official services that can do this:
Secrets Manager - This service is specifically built for this purpose, you define a secret and give it either a string or JSON value that is then retrieved via a call using the SDK. All values are encrypted using a KMS key.
Systems Manager Parameter Store - Similar to secrets manager, you provide a key name and give it a value. It supports both unencrypted and encrypted values (use SecureString type).
In addition there are other services such as Hashicorp Vault that provide similar functionality.
For environmental configuration a .env file can still be appropriate i.e. enable this feature flag but if you want to try and reduce the blast radius of your application then storing secrets outside a plain text file will help to reduce this risk.
That is not the main reason for using environment variables. However, it is secure enough for saving secret values too especially when they’re combined with hashing methods.
Environment variables are most useful in the actual production level of programming. Your application must have different environments to run upon. Development: that your host is local and as a developer you need to test your code and set the debug variable to true to get stateful errors which is not something you want on the production environment. Production: that your host is your domain or server IP and you need different middleware than of the development stage. There are also staging and test environments for bigger projects. There could be a lot of things that should be handled differently on different environments: database is a great example. Besides, environment variables are useful for when there is more than one person working with the code base and people can configure the project based on their machine/OS using environment variables.

Using other environments from Postman

We have our workflow split into multiple projects, each dealing with different concerns (Central server is for anything authentication-related, API server for anything new-gen related, and each other project corresponds to a its own app).
This makes our process of hitting an app API as follows:
From Central Server local environment, post authentication
Set app
From the app environment for the end user, set to environment
Hit the API of the app of end user's choice
This makes for tests that are difficult to write, in that we'd have to do steps 1 through 3, and with two different environments.
Is there a way to access the variables from one environment (e.g. Central Server Local) from another, in the test script?
Environment variables are scoped to their own environment - up from that you could set a global variable in the test script and still access it when you change environments:
https://www.getpostman.com/docs/v6/postman/environments_and_globals/variables
Collection variables are also above environment variables but cannot be set programmatically, only through the collection settings.

Pass job name and build number to cloudbees application

I want to be able to use the job and build number within my cloudbees application (i.e access it as an environment variable).
In the application description, I can use "${JOB_NAME} #${BUILD_NUMBER}", but is this also possible somehow within the environment override fields?
I want to be able to set something like:
Name: runningversion
Value: ${JOB_NAME} #${BUILD_NUMBER}
I am assuming you are using the CloudBees Deployer plugin to deploy your application to our RUN#cloud service.
If that is the case then you can achieve exactly what you want with the Override Environment section. You just need to do something like this:
The in-line help for the Value field even indicates that it
Supports ${} style token macro expansion
As a hint to let you know that you can do what you are trying to do... so if it doesn't work then there is a bug!
Those Override Environment name-value pairs should be available, at least, as OS level environment variables and for the Java based ClickStacks (e.g. Tomcat, JBoss, Glassfish, Play, etc) they should also be available as Java System Properties but that can require that the ClickStack is written to provide that support (the well known ones produced by CloudBees should)

setting a jvm variable on CloudFoundry

I have a Java application, using a jvm variable. Normally, I set it using a command like
APP_HOME="-DAPP_HOME=$CATALINA_HOME/myapp"
in order to point to the correct folder within my application structure on Tomcat.
Now I am trying to deploy my application to the MicroCloud virtual machine. Once deployed, I use the command
vmc env-add myapp APP_HOME="-DAPP_HOME=$HOME/myapp
to set my variable. But the problem is that the variable is set as a shell variable and not JVM variable. When I use System.getenv(); I can see that my variable is set, but when I use System.getProperty("APP_HOME") the variable is null.
Anyone had experience with this and could recommend what to do set it as a JVM variable on CF?
p.s.
I read all the existing topics on the CloudFoundry Q&A and here on stackoverflow, but I do not see an answer to this problem...
Thank you in advance!
What about
vmc env-add myapp JAVA_OPTS="-DAPP_HOME=$HOME/myapp"
(i.e. pass -DAPP_HOME as a property to the JVM)
However, why are you trying to do this - and why is it such a bad idea just to grab the value using getenv instead of looking for a system Property?