4

I currently have a regular SpringBoot App that I'm splitting into 2 applications in order to gain some of the benefits from Spring Cloud Dataflow and Spring Batch:

  1. A SpringBoot app responsible for detecting specific events and launching new Batch tasks throught Spring Cloud Dataflow REST API
  2. A SpringBoot + Spring Batch task which will be registered to SCDF from it's jar on our Nexus and called upon new events are polled.

I already got both apps working and I'm beginning to move things around. Now my concern is, this batch application has an application.yml file containing datasources and other important properties that can (shouldn't, but can) updated very often.

On my current approach, my application is packaged inside a Docker container and I start my app saying where the definitive application.yml file. This allows me to have one specific .yml file per environment, since I'm not allowed here to use Spring Profiles to organize variables per env. Devs shouldn't be able to know Prod vars.

Here's the entry point of my Dockerfile:

ENTRYPOINT ["java","-Dspring.profiles.active=docker","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar", "--spring.config.location=classpath:/application.yml,file:/tmp/config/application.yml"]

What would be the best way to keep my properties file externalized using this new approach of a SCDF task? Should I go for Spring Cloud Config? Does passing the --spring.config.location as an job argument actually work?

Keeping in mind my restricting mentioned above, can Spring Cloud still be addressed as a possible solution?

Thanks in advance for any help!

Best regards,

Enrico

Enrico Bergamo
  • 163
  • 1
  • 14

2 Answers2

0

Definitely Spring Cloud Config Server will be a good option specially considering you mentioned data sources that contains passwords and potentially other keys/secrets that you should protect. With config server you can not only externalize configurations but also store them securely since it allows you to encrypt properties using both symmetric and asymmetric algorithms, see here:

spring cloud config encryption and decryption

On the other hand, having those properties in you application.yml means those passwords/key/secrets will end-up in you control version system (hopefully not accessible from outside your organization's network).

Another option is keeping your config in your configuration files and externalize only the sensitive information. In my organization we use HashiCorp Vault combined with Spring Cloud Config.

Vault

If there is not existing Vault deployed in your organization and you find the effort of maintaining an additional service is too high for you or your team, Spring Cloud Config server should be good enough.

About: I'm not allowed here to use Spring Profiles to organize variables per env. Devs shouldn't be able to know Prod vars. I think this is direct consequence of having properties inside the code, usually there are some, if not most, of the configuration that is shared across different applications leading eventually to config hell specially if you have to rotate passwords or keys. Externalizing will allow Devs to access non-prod environment configuration and Ops deal with prod environment configuration so everyone is happy. Even with Vault Devs can "know" prod env Vault paths while not being able to access it.

Israel Fernández
  • 395
  • 1
  • 3
  • 8
0

You can use kubernetes configmap for you spring cloud tasks and spring batches. If you are deploying the spring cloud data flow on Kubernetes. You can add the below dependency into your cloud tasks and spring batches.

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>

Now you need to add the following bootstrap yaml properties into your application.

spring:
  cloud:
    kubernetes:
      enabled: true
      config:
        enabled: true
        namespace: <namespace>
        name: <config map 1>
        namespace: <kubernetes namespace>
        sources:
        - name: <config map 1>
        - name: <config map 2>
      reload:
        enabled: true
        strategy: refresh

You need to mention namespace value. If you are segregating properties-based on environment, please mention the namespace you are using. you can also specify the config map names.

Read more about it here. https://docs.spring.io/spring-cloud-kubernetes/docs/current/reference/html/index.html#kubernetes-propertysource-implementations

swyrik
  • 144
  • 2
  • 7