override application.yaml properties of spring boot app using k8s deployment/configmap - spring-boot

I have a spring boot app that has an application YAML file (src/main/resources/).
app:
props:
-
key1: value
key2: value
-
key3: value
key4: value
-
key5: value
key6: value
I want to override the entire list of props in the deployment's env section (k8s). is there any way to do it in Kubernetes?

Spring will automatically allow you to override properties via environment variables.
So if you want to change key3, then all you need to do is to create an environment variable called: APP_PROPS_1_KEY3 and you can override this value. This can be done via K8.
More here: https://stackoverflow.com/a/58186093/5563263

As per this SO, Assuming the App is deployed on Kubernetes with a Pod you can inject environment variables inside the container by either directly assigning them to the Deployment itself, or with a ConfigMap, Here in this Tutorial you have detailed info and steps about this process.
Adding the support links:
Here is the doc for :
Expose Pod Information to Containers Through Environment Variables.
Configure a Pod to Use a ConfigMap.
Spring Boot features external configuration.

Related

Kubernetes autogenerated environment variables set wrong?

During pod startup Kubernetes is creating some environment variables based on services i created (via downward API?). Problem is that one of them, MY_APPLICATION_PORT, seems to be initialized incorrectly, it looks like:
MY_APPLICATION_PORT=tcp://192.168.0.5:7777
whereas i expect it to hold only 7777 value. The problem is that i have a Spring Boot application that has this property in application.properties:
my.application.port=7777
So when spring resolves it's properties, it prefers value from environment variable over one from .properties file, thus overwriting it with incorrect value.
My question is - do you guys know how to control creation of kubernetes env variables? I can overwrite it in my deployment.yaml, but I wonder if there's another way.
EDIT:
I've found this as a closest description of my issue I've seen online:
https://github.com/kubernetes/kubernetes/issues/65130
This environment variable comes from compatibility with a very old Docker feature. You can disable it in Kubernetes by setting enableServiceLinks: false on a Container object in a Pod spec, anywhere that may appear. For example:
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: ...
enableServiceLinks: false
env: [...]
In particular the syntax is intended to be compatible with the environment variables generated by container links in first-generation Docker networking. Since then Docker has also introduced a DNS system into its core, and in pure Docker using links at all is now considered obsolete. It should be safe to always set this Kubernetes property, especially if it causes conflicts like what you describe here.

How do I load AWS region specific properties from Spring Boot application properties?

My java microservice (developed in Spring boot) loads S3 bucket from an application properties file. S3 bucket names for 4 different AWS regions are different (bucker-east-1, bucker-west-2 etc) hence how do I load AWS region-specific properties from application properties? For example, for us-west-2 region, bucker-us-west-2 property should be loaded, etc. is there any existing support for this type of feature in SPring boot?
There's at least a couple of ways you could handle this.
Use environment variables: Using env variable in Spring Boot's application.properties
Feasibly you could structure the names to be something like bucket.name=<bucket-prefix>-${AWS_REGION}
Use Spring profiles. You can create separate properties files for each region.
For example, you'd have application-us_east_1.properties, application-us_east_2.properties. You then can add the appropriate spring profile upon deployment by passing in the JVM parameter, -Dspring.profiles.active=us_east_1 to activate us_east_1. Alternatively, you can use the SPRING_PROFILES_ACTIVE environment variable similarly.

How to create kubernetes configmap from properties file during maven build?

We have an old java application which has few properties files. We are doing a POC to deploy it in Kubernetes cluster using Helm chart. As of now, we manually creating configmap by copying the content from properties file. If any updates in properties file, as a result the same update should be done in configmap manually. So, Is there any solution available to create a configmap from the properties file during maven build?
Thanks in advance.
If you were using Spring Cloud Config in the past to fetch your properties and reload application during change of properties, there is an alternative provided by Spring for Kubernetes which allows fetching and reading the properties from your ConfigMap(s) directly and allows reload when the ConfigMap changes
Reference - https://cloud.spring.io/spring-cloud-static/spring-cloud-kubernetes/1.1.0.M3/reference/html/#kubernetes-propertysource-implementations
But looks like there is no solution available yet to generate ConfigMap(s) from property file(s) directly during a maven build.
It can be done by help of volume and volumeMounts.
You can get info from this

How can we set different environment profile in spring boot?

I am working on microservices using spring boot. i have around 5 microservices. so I configured spring cloud config server to centralized configuration. its perfectly working fine.
config server configuretion
spring.profiles.active=native
spring.cloud.config.server.native.search-locations=classpath:/common-config
server.port=8888
now the problem is I have two environment dev and test and i created application-test.properties and application-dev.properties as per the spring documented i need to set profile like
Spring profile
spring.profiles.active=test
but its already set as a native then how can i load multiple profile.
please help me ..
You can pass in the active profile name as an environment variable at run time of each of the apps. This will take priority over the active profile listed in your properties file. You can do this with any property actually. If you're using docker to launch your apps, you can pass it in from your Dockerfile or from your docker-compose.yml
You can set spring.profiles.active=$ACTIVE_SPRING_PROFILE and set OS environment ACTIVE_SPRING_PROFILE = test
You can use multiple profiles in Spring. Try:
spring.profiles.active=dev,native
See more: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html#boot-features-profiles

How does Spring map Docker environment variables?

So I found this sample project. In docker-compose.yml I notice that he is supplying a environment variable called REGISTRY_HOST, and that this is then used in various application.yml files in the project, here for instance.
What I am wondering is, how does this mapping work and is it Docker or Spring that performs the magic? For instance, he is binding registry.host and registry.port, but how exactly is this mapped? How come it is registry that is the prefix, and where does registry.host come from when it isn't in the compose file?
Basically what docker does is it just assigns the environment variable, nothing more. But on Spring side, it reads this variables and tries to assign to an application property. Which is explained in Externalized Configuration Please see the 24.7.2 Relaxed Binding part of the documentation.

Resources