Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to consume properties from configmaps in Java Spring boot application deployed through Helm

I have simple Spring boot application which I need to deploy on development and prod different namespaces on a Kubernetes cluster using Helm.

I was thinking about keeping multiple application.properties (application-dev.properties, application-prod.properties) files for each environment and then create configmaps from them through values.yaml files which also will be different for each environment and specified when I execute Helm upgrade.

Now the question is how do I consume values from config.maps as I understand I can either mount the properties file inside container for example /deployment/application.properties

Or expose each property as an environment variable inside container.

But how do I consume them from Java application?

Also at the moment when I create container image it has current application .properties inside /resources/ files embedded and this is what application is using from default so I need to overwrite this behaviour when application is running inside container as opposite to then when its just build and run manually on developer desktop.

like image 488
Rafal Avatar asked May 11 '18 17:05

Rafal


People also ask

How does spring boot Pick application properties?

So in a spring boot application, application. properties file is used to write the application-related property into that file. This file contains the different configuration which is required to run the application in a different environment, and each environment will have a different property defined by it.

How does Spring Boot read external application properties?

Spring Boot allows you to externalize your configuration so you can work with the same application code in different environments. You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration.

Where does spring boot store application properties?

You will need to add the application. properties file in your classpath. If you are using Maven or Gradle, you can just put the file under src/main/resources . If you are not using Maven or any other build tools, put that under your src folder and you should be fine.


2 Answers

Springboot can automatically infer variables from environment variables. In your application.properties or application.yaml, just use ${MY_ENVIRONMENT_VARIABLE:my-defaultvalue}.
Use helm to populate your configmap. Use configmap as environment variables into your deployment manifest.

This way you do not need to have multiple application.properties for dev, int ,prod inside your image. Keeping it intact across deployment.

And then in your helm chart, you can have multiple values.yaml example values-dev.yaml or values-int.yaml. you can also dynamically set helm values from command line, overriding the yaml file.

I have a demo app in github https://github.com/balchua/demo, which uses this pattern.

like image 152
Bal Chua Avatar answered Nov 09 '22 01:11

Bal Chua


You could certainly use environment variables as Bal Chua suggests. If you do that you can override particular values at install time using --set or if you've a lot of config you can use the '-- values' flag and pass in a custom values.yaml file.

Another approach is to load a whole file using .Files.Glob (example in github) and load the file as part of the chart. You can then mount the file to /config to consume it in your spring boot application. Then your config file would be in the same form as a Spring boot config file, rather than a helm values.yaml. Though in many cases there needn't be much difference.

There's a discussion of how you could do similar for secrets (presumably you'll want to put your passwords in secrets) and use it for CI/CD in https://dzone.com/articles/hunting-treasure-with-kubernetes-configmaps-and-se (which is the article accompanying the github example). Basically you would use .Files.Glob with .AsSecrets instead of .AsConfig so as to encode the content. Many helm charts have the option to generate a random password if not specified but I'd guess you probably don't need that.

like image 2
Ryan Dawson Avatar answered Nov 09 '22 01:11

Ryan Dawson