In a spring boot application, I would like to pass some environment variables from env files (available for different environments) to the application.yml. We decided not to use spring profiles for different environments as using .env files make the later migrations to cloud easier for us. Defining these variables as following in the application.yml:
datasource:
driverClassName: org.mariadb.jdbc.Driver
username: "${SPRING_DATASOURCE_USERNAME}"
password: "${SPRING_DATASOURCE_PASSWORD}"
Furthermore, I have exported all the environment variables in the .env file which also includes ${SPRING_DATASOURCE_USERNAME} and ${SPRING_DATASOURCE_PASSWORD} using the following command:
export $(grep -v '^#' .env | xargs -d '\n')
When running
./gradlew test
I get the following error:
Missing property (SPRING_DATASOURCE_USERNAME) for Groovy template expansion.
The problem is that gradle wrapper does not get the system environment variables or exported environment variables. Is there a way to solve this using .env files? Any hints are appreciated!
Since you've exported them as environment variables, you could remove spring.datasource.username and spring.datasource.password from your application.yml. Spring will search them automatically from the environment variables. You don't need to specify them like templates. An extreme usage is exporting all the properties via environment variables and leaving application.yml empty.
References
Priority: https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config
Rules: https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding.environment-variables
Related
First of all I am new to Lambda function in AWS and all. I need to access the lambda environment variables into my spring-boot's application.properties file to put RDS username, pass etc. Can someone please give me any hint ?
datasource:
url: ${DBURL}
username: ${UNAME}
password: ${PASS}
Your example should work as it is in your question, are you getting any errors?
Alternatively, you could rename your environment variables to:
SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME, and SPRING_DATASOURCE_PASSWORD and Spring Boot will automatically pick up those values and use them, without needing anything in application.properties.
I was looking to externalize application configuration for containerized applications on Google Cloud Run. I know there are environment variables available for cloud run application and I want to have something as Config Server for Cloud Run.
Is there any out of the box support available on GCP?
When setting up your Cloud Run deployment, you can simply inject environment variables into your service:
Because Spring Boot comes with application.properties mechanism, you can easily override those values exactly from the environment variables. Do keep in mind, that the syntax is slightly different:
application.properties
spring.profiles.active=dev
environment variables
SPRING_PROFILES_ACTIVE=dev
Injected env variables will take precedence over the ones defined in your application.properties file.
There are two solutions to it :
If your docker file is "ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/****.jar"]" then use "-Dspring.profiles.active=dev" in the container arguments on the cloud run.
In case your docker file has "CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/***.jar"]" You can do it by setting Environment Variable as SPRING_PROFILES_ACTIVE and value as dev in "Variables & Secrets" tab on cloud run Container Configuration
In light-4j, is there a way to use environment variables in configuration files (like cors.yml, consul.yml, client.yml) similar to docker-compose files?
Yes. Take a look at this document
https://doc.networknt.com/concern/config/#environment-external-config-injection
You can use placeholders in the config files and use environment variables or values.yml to overwrite the variables in any config file.
From the spring documentation http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-yaml i see that an external YAML file is possible.
I was able to use a PropertyPlaceholderConfig FileSystem resourse to load in yaml, but it did not honor the active profile.
I saw for application.properties you can use #PropertySource, but that does not work for YAML according to the docs.
So bottom line question: How do a specify an application.yml in a profile aware fashion in Spring4/spring boot.
Note: It works in src/main/resources/application.yml
In order to specify an external profile aware .yml file the SPRING_CONFIG_LOCATION and SPRING_PROFILES_ACTIVE system variables can be used.
JAVA_OPTS example
-Dspring.profiles.active=dev -Dspring.config.location=file:C:/application.yml
This will allow you to have provide multiple profiles inside of a YML file and let spring do the heavy lifting of evaluating the correct properties:
spring:
profiles: dev
someprop: devprop
---
spring:
profiles: test
someprop: testprop
I'm using Spring 3.1.3 and the new profile feature. When I set the environment in my IDE for spring_profiles_active=NONPROD, it works fine. However, when I deploy to our aPaaS environment which is also using Tomcat, it isn't getting picked up.
Shouldn't I just be able to do the following:
env:
CATALINA_OPTS: -Dspring_profiles_active=NONPROD
If I ssh to the machine, I see this is getting set. Any ideas why Spring isn't picking this up?
Put the following lines to your manifest.yml file to get the Spring profile activated in Stackato:
env:
spring_profiles_active:
default: NONPROD
This will put spring_profiles_active into environment variable and Spring happily reads it from there. Note that you have to use underscores in the variable name, because Stackato doesn't like dots in those. The reason is that Linux environment variable names shouldn't contain dots for shell programs to work correctly with them.