Spring cloud not able to resolve vault secret into .yml - spring

I'm working with microservice architecture and have spring cloud config service and another microservice.
profiles:
active: vault
cloud:
# Configuration for a vault server running in dev mode
vault:
scheme: http
host: 127.0.0.1
port: 8200
connection-timeout: 5000
read-timeout: 15000
authentication: TOKEN
token: s.E4gdoIYAKxMvCE56MP5Etmvy
kv:
enabled: true
backend: secret
backend-version: 2
profile-separator: /
generic:
enabled: false
application-name: myapp
Config server dependency
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
this is into .yml into the config service. Then into the .yml for my microservice i have db.username property which I want to resolve from Vault but I can't. Do you have any ideas?
username: db.username
password: secret/apm-transaction-service/dev/db.user
#Value("${db.username}")
this value is resolved into the java code but not into the .yml
Now for each microservice which I have I want to resolve the secrets from the configuration service without making any changes into the microservices. Currently reading native .ymls from the config service and want to add one more source :)
ApplicationStartupRunner run method Started !!root

if you are using spring-boot, for the value in .yml file to be resolved it has to be a variable. you must use ${db.username} in the yaml file

Related

Spring cloud config and Vault Integration

I'm trying to read secret values using spring vault. All the properties for client application is stored in github and spring config server is used to access the properties. When I add the vault configuration to client application bootstrap.yml as below, the values are read properly.
bootstrap.yml
spring:
application:
name: client-app
cloud:
config:
uri: http://config-server:8080
vault:
enabled: true
authentication: APPROLE
app-role:
role-id: 12345
secret-id: 12345
role: pres-read
app-role-path: approle
connection-timeout: 5000
read-timeout: 15000
kv:
enabled: true
backend: secrets
application-name: client-app
uri: https://vault/
application.yml in config server
spring:
cloud:
config:
server:
git :
uri: https://github/repo.git
username: abc
password: pass
refreshRate: 300
Based on https://docs.spring.io/spring-cloud-vault/docs/current/reference/html/config-data.html#vault.configdata , it should be possible to load the vault config from properties yml in github. But if i move the above vault config to my client-app.yml in github, the properties are not read from the vault. How do I achieve this?

Microservices not registering on all Eureka Instances

Spring Boot version: 2.1.6.RELEASE
Spring Cloud Version: Greenwich.SR1
Objective is to set up two instances of Eureka Servers in a cluster and have all microservices registered to both, in order to achieve HA. Currently I am testing this on my local machine running Ubuntu 18.04.
So as mentioned in the official docs, I have set up the peer to peer awareness of Eureka Instances. On bringing both the Eureka Server Instances up, on the dashboard of Instance-1(Port 8080) under available replicas showing Instance-2 name and on dashboard of Instance-2(Port 8081) it is showing Instance-1 name. So far so good.
I have deployed them on external tomcat server as war and not running them as jar. War name is "eureka-naming-server". So my access URL becomes: http://localhost:8080/eureka-naming-server/eureka and http://localhost:8081/eureka-naming-server/eureka.
I have set up a load balancer using Apache 2 and mod_jk. So instead of accessing them using their individual URLs i.e. http://localhost:8080/eureka-naming-server/eureka, http://localhost:8081/eureka-naming-server/eureka, I can access them using Apache URL as http://localhost:80/eureka-naming-server/eureka and I can see load-balancing happening properly.
Now the issue is that once I give Eureka URL as http://localhost:80/eureka-naming-server/eureka in the microservice, it registers only on one instance depending on which Eureka instance the load-balancer has redirected the request. But even though peer to peer awareness is setup, microservice is not getting registered on the other eureka instance.
In Eureak servers, I'm using the below dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
Eureka-1 props:
spring:
application:
name: eureka-naming-server
jmx:
default-domain: eureka-naming-server
eureka:
client:
service-url:
defaultZone: http://eureka-server-2:8081/eureka-naming-server/eureka
#register-with-eureka: false
#fetch-registry: false
instance:
hostname: eureka-server-1
Eureka-2 props:
spring:
application:
name: eureka-naming-server
jmx:
default-domain: eureka-naming-server
eureka:
client:
service-url:
defaultZone: http://eureka-server-1:8080/eureka-naming-server/eureka
#register-with-eureka: false
#fetch-registry: false
instance:
hostname: eureka-server-2
In microservices, I'm using below dependencies:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
Microservice props:
eureka:
instance:
metadata-map:
configPath: /config
client:
service-url:
defaultZone: http://localhost/eureka-naming-server/eureka
In the machine's /etc/hosts file I have set it up as:
127.0.0.1 eureka-server-1
127.0.0.1 eureka-server-2
The eureka instance on which it is getting registered I can see the below in the logs:
WARN 13748 --- [nio-8009-exec-3] Registered instance CONFIG-SERVER/192.168.1.16:config-server:8888 with status UP (replication=false)
The other Eureka instance where it is not registered, when it receives the heart-beat because of the load-balancer, shows this in the logs:
WARN 13748 --- [nio-8009-exec-3] c.n.e.registry.AbstractInstanceRegistry : DS: Registry: lease doesn't exist, registering resource: CONFIG-SERVER - 192.168.1.16:config-server:8888
2019-12-26 19:00:34.995 WARN 13748 --- [nio-8009-exec-3] c.n.eureka.resources.InstanceResource : Not Found (Renew): CONFIG-SERVER - 192.168.1.16:config-server:8888
Eureka-1 Dashboard
Eureka-2 Dashboard
I have already tried suggestions mentioned here and here. But nothing seems to work.
So what could I be missing here?
Issue:
spring:
application:
name: eureka-naming-server
You put the same name for an application so it's displayed like this.
you need to change it to,
Eureka-1 props:
spring:
application:
name: eureka-naming-server-1
Eureka-2 props:
spring:
application:
name: eureka-naming-server-2
It may also be worth checking your security configuration for your eureka servers. If you do have spring boot security enabled, you will need to be sure that you include the corresponding username/password in the defaultZone portion of your config.
i.e. in your eureka server 1 config: eureka.client.serviceUrl.defaultZone=http://:#eureka-server-2:8761/eureka
(and visa versa for your eureka server 2 config)
I only mention this because I had left out my own username/password values in that config value and it was not registering my microservices on all my eureka instances. After make this change, it worked as I was expecting.

Spring Config uri

I have configured bootstrap.yml for spring config
spring:
application:
name: cce-auth
cloud:
config:
uri: http://temp.com:8888
It works fine but I need URI value Dynamically, for example if I will publish this .war in test environment this URL must be http://test-temp.com:8888.
So for this I have solution create config.txt file in server and using I/O Stream reed/write this string to bootstrap.yml.
But problem is loading, spring loads http://localhost:8888 before I'm writing in bootstrap.yml.
So my reason is to create dynamically URI for config server.
DO you have any idea?
Define active_profile in bootstrap.yml file
spring:
profiles:
active: ${activatedProperties}
Then create bootstrap-${activatedProperties}.yml for each environment, etc..bootstrap-dev.yml, bootstrap-pre.yml, bootstrap-prod.yml
For example:
spring:
application:
name: servicename_prod
cloud:
config:
uri: https://admin:123456#test.com:8888
server:
port: 8443
add plugin to pom.xml file :
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
When run java, define environment on it: for example, run with prod environment.
java -Dserver.port=8443 -Dspring.profiles.active=prod -jar ....

Read values from consul while bootstrap spring boot

I have question is there any way to retrieve certain values and inject them to bootstrap.yml while application is coming up.
I have configuration file like this:
spring:
application:
name: myApp
cloud:
consul:
enabled: true
host: localhost
port: 8500
config:
enabled: true
datasource:
url: jdbc:oracle:thin:#localhost:1111:XXXX
username: ${nameOfVariable1}
password: ${nameOfVariable1}
driver-class-name: oracle.jdbc.OracleDriver
For example, I need to configure embedded tomcat port, or DB credentials, I don't want to put it hardcoded in .yml properties file, instead I want to put some variable name in .yml so Spring will go and bring value from Consul. Is it possible?
You can use Spring Cloud Consul Config project that helps to load configuration into the Spring Environment during the special "bootstrap" phase.
3 steps:
add pom dependency: spring-cloud-starter-consul-config
enable consul config: spring.cloud.consul.config.enabled=true
add some config in consul kv in specific folder, such as key: config/testConsulApp/server.port, value:8081
and then start the sample web app, it will listen 8081.
more detail at spring cloud consul doc.
and demo code here

Token support in spring cloud consul

We are using spring-cloud to read the configuration for our application. We have the similar structure like below in application.yaml
spring:
cloud:
consul:
host: consul_host
port: 8500
We want to enable ACL for consul. So we need to pass consul token to read the configuration by spring.
How can I specify consul token in application.yaml
If you use at least Spring Cloud Brixton M2 (current version is RC1), there is the property spring.cloud.consul.config.acl-token where you can specify the token.
The proper answer is to have token placed in following way:
spring:
cloud:
consul:
host: consul_host
port: 8500
token: your_token
I'm using Spring Boot version: "2.0.4.RELEASE" + "spring-cloud-starter-consul-config"

Resources