How to configure custom property file with encrypted properties using spring cloud? - spring

The spring cloud encryption/decryption works only with application.properties file, but I have env_*.properties for each environment, how to configure those properties to be encrypted as well?

Spring cloud config server properties file work with any file name other than application.properties file. It is important you name such environment property files with a name that follows this convention:
[spring application name]-[environment e.g dev, staging, etc].[extension] e.g. : myapp-dev.properties or myapp-dev.yml where my-app corresponds to spring.application.name property value. Also make sure these files should reside in a folder named after spring.application.name value.

Related

How to override a property defined in profile-specific application-{profile}.yml for a single application?

I have a spring-cloud-config server set up to serve YML files from a git repository. The server is using Spring Cloud 2020.0.3. There are several spring-cloud-config clients consuming config files from the server. The client applications consuming the config are using Spring Boot 2.4.6 and the new config parsing implementation.
The config repository contains an application-db.yml file and myapp.yml file. The application-db.yml file has several common properties set that all applications will use for the db profile. myapp.yml has properties for a specific application. Prior to using Spring Boot 2.4.6, I was able to override properties from application-db.yml in myapp.yml. In effect, the application-db.yml properties were the default values that individual applications could override.
For example application-db.yml might have (property key is not relevant):
spring:
datasource:
hikari:
maximum-pool-size: 5
to set the connection pool size to 5 for most applications and myapp.yml could set
spring:
datasource:
hikari:
maximum-pool-size: 10
for a one-off connection pool size of 10.
In Spring Cloud 2020.0.3 (Spring Cloud Config 3.0.4) and Spring Boot 2.4.6, the behavior is that the property in application-db.yml cannot be overridden in myapp.yml and the connection pool size property always has value 5.
I have tried setting the following properties in the application.yml and still have the same results.
spring:
cloud:
config:
allowOverride: true
overrideNone: true
overrideSystemProperties: false
According to Config file processing in Spring Boot 2.4 overriding property values is allowed in the config processing, but it is dependent on document order.
Is the overriding behavior still supported by Spring Boot using Spring Cloud Config? If so, does it depend on the order the cloud config server serves the documents? Is there a way to control the order?
edit note: I originally posted about overriding properties in the application.yml file. After more investigation, that does allowing overriding. It is in the profile specific files like application-db.yml that I cannot override values. I'm starting to think this might be a bug.
The overriding behavior you are looking for is supported in the latest release documented here and should be the default behavior without needing to add additional properties to enable override. You will need to include the application name with the spring.application.name property for the config server to recognize the overriding file.The overriding file also needs to have the same name you give in the client application (in this case,for example, my config repo has files application.properties and myapp.properties.
Client application.properties
spring.application.name=myapp
spring.config.import=optional:configserver:http://localhost:8888
...
Server application.properties
spring.application.name=configserver
spring.cloud.config.server.git.uri=https://github.com/...
server.port=8888
...
Within config repo
application.properties
spring:
datasource:
hikari:
maximum-pool-size: 5
myapp.properties
spring:
datasource:
hikari:
maximum-pool-size: 10
If the client application cannot fetch the overriding file (in this case the myapp file) from the config server application, it will fall back to its local application.properties file. However, the application will probably fail if all of the properties your application needs are not present there as well, so it's a good practice to copy all properties from your overriding file to the client application.properties file in case fetch fails.
If this didn't fix your problem I would check out this section on property overrides.

Custom file names in Spring Cloud Config Server

How to specify a spring boot application to access only a specific .properties file among other files in my Spring Cloud Config Server.
My Spring Cloud Config has the following files:
application.properties,order-dev.properties,inventory-dev.properties,
all my db and messaging properties are in order-dev and inventory-dev files.
Now I wish to move those properties to orderdb-dev, inventorydb-dev, ordermsg-dev and inventorymsg-dev files.
How do I configure my order and inventory service to pick the property from orderdb-dev, inventorydb-dev, ordermsg-dev and inventorymsg-dev files ? I have been going around to find the property for the same. Read through the official documentation and felt lost. Any help would be appreciated.
Add a bootstrap.yml file under resources folder. Then add the below properties.
spring:
application:
name: order
cloud:
config:
name: ${spring.application.name}, orderdb, ordermsg
profile: dev
This way, it will first load the properties from order-dev.properties file. Then orderdb-dev.properties and then ordermsg-dev.properties.

Spring cloud config shared property between microservices

cloud-config
src
main
java
resources
config
microservice.yml
tons of microservices here..
application.yml
File application.yml contains property
databaseIp=10.20.30.40
File microservice.yml contains property
spring.data.mongodb.host=${databaseIp}:27017
My problem is databaseIp doesn't change to 10.20.30.40
I don't want to rewrite database ip to each microservice. How can i reach my goal?

Spring Boot: Configuring subdomain, hostname and port through app properties

My Spring Boot app will have 4 different environments:
Local; running locally on my machine
Dev
UAT
Prod
When a new user registers for my app, the backend sends them an email to verify their address/account. In this email there will be a link; the user clicks the link which verifies them in the database and allows them to now login and use the app.
These links of course have to have the environment built into them:
Locally, the link might be http://localhost:9200/v1/data/accounts/verify?vt=12345
In dev the link might be: http://dev.myapp.example.com/v1/data/accounts/verify?vt=12345
In UAT the link might be: http://uat.myapp.example.com/v1/data/accounts/verify?vt=12345
In Prod the link might be: http://myapp.example.com/v1/data/accounts/verify?vt=12345
In all three environments, the hostname + port are different. Locally I specify localhost:9200 (both localhost + port). Non-locally I don't need to specify port because the app will be running on nodes behind a load balancer. In production I don't need an environment-specific subdomain like dev or uat.
In order for my emails to work correctly in all 4 environments, I need to set an environment variable that is then used by my email generator to generate links correctly.
I could use something homegrown, such as a custom property in application.properties like emailDomain, and set the property different in each environment's properties file.
But I feel like the smart folks that make up the Spring Boot community have probably already solved this problem for me...have they? Is there already a Spring Boot app property I can set that will take care of all this for me?
In the comments, I read that your main concern is being able to update the property without having to modify your .JAR/.WAR or changing some code.
This is possible since you can externalize your Spring boot configuration. If you check the Externalized Configuration docs, you can see that it looks for properties within:
OS environment variables.
...
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
Application properties outside of your packaged jar
(application.properties and YAML variants).
Application properties packaged inside your jar (application.properties and YAML variants).
So, ideally, you can put an application.properties file next to your JAR, and update the properties in that file depending on the environment you run on.

Spring Boot application profiles

I understand there's multiple ways of handling application property files and profiles in Spring Boot and I've seen multiple questions and answers on how to handle each but I'm trying to find the "best" way of handling it for a new project, if there is one.
The application is hosted in Weblogic 12c on production/pre-prod (with a jndi database connection) and ran locally in tomcat (with hardcoded database details) for development. I'd like it so that when the project is built via gradle and deployed to production it uses the jndi properties file and when ran locally it defaults to the hardcoded datasource with minimal changes required.
src/main/resources/application.properties
# DEV
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
# DEV
# PROD
# spring.datasource.jndi-name=
# spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
# PROD
From my understanding the recommended way is to externalize the property files and place the required one in a config directory alongside the WAR file for any differing config which is then automatically picked up and used?
You should consider creating multiple profiles. This means: Either multiple properties-Files, or multiple profiles in one file:
See https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html
I would recommend to use multiple application-ENV.properties, e.g.
application-prod.properties and application-preprod.properties.
There is always one active profile and settings from the application.properties (without any profile suffix) are used as default values if not overwritten in a specific profile-file.
Depdending on your environment (local, prod etc.) you should set an environment variable (start the java-process/application server with that environment variable), e.g.:
SPRING_PROFILES_ACTIVE=prod
On your local machine you would set:
SPRING_PROFILES_ACTIVE=dev
With this variable you can control, which profile is currently active.
Also consider integrating the active profile into you Continious Integration/Deployment settings.
Please note that putting plain text passwords hardcoded into committed files is not a good idea. Consider using jasypt or a spring cloud config server for your prod database configuraiton or use any mechanism that your cloud provider provides to you if you use any. Microsoft Azure for example provides a KeyVault for sensitive data.
https://cloud.spring.io/spring-cloud-config/multi/multi_spring-cloud-config.html
http://www.jasypt.org/
If you use gradle good solution is to set application.properties and test.properties files and put into them properties for prod and preprod respectively.
Then run application with different vm arguments: -Dspring.profiles.active=test for test.properties and without arguments for application.properties
Use gradle instruments and configure them once for test and prod. For example: gradle bootWar configure without vm arguments, gradle bootWarTest with vm arguments -Dspring.profiles.active=test. Save once you configs and you will create war for different environments only selecting between two buttons in gradle.

Resources