Library versions

Spring Boot 2.7.12 Spring Cloud 2021.0.6 Spring Cloud AWS 2.4.1


I have a Spring Cloud Config setup with a Git backend. Generally, property files fetching function well. My aim is store secrets in AWS and reference them from property files, so I added additional spring.config.import: "aws-secretsmanager:/test/springconfig" directive within the properties file for the Spring Cloud Config Server.

This option only works when I add such a configuration to an application property itself as follows:

spring:
  application:
    name: my-java-client
  config:
    import: 
    - "configserver:"
    - "aws-secretsmanager:/test/springconfig"

My intention is to house both configurations and sensitive data (in the form of AWS references like "aws-secretsmanager:/test/springconfig") in the Git backend. So, the properties file in Git backend would look like

server.datasource.url: jdbc:postgresql://dev:5432/example
spring.config.import: "aws-secretsmanager:/test/springconfig"
some.dummy: value

This is what I get now:

{
"name": "configserver:git@github.com:xxx/spring-configs.git/configs-location/java-client/java-client-dev.yaml",
"properties": {
"server.datasource.url": {
"value": "jdbc:postgresql://dev:5432/example",
"origin": "Config Server git@github.com:xxx/spring-configs.git/configs-location/java-client/java-client-dev.yaml:1:24"
},
"some.dummy": {
"value": "value",
"origin": "Config Server git@github.com:xxx/spring-configs.git/configs-location/java-client/java-client-dev.yaml:2:13"
},
"aws.secretsmanager.region": {
"value": "us-east-1",
"origin": "Config Server git@github.com:xxx/spring-configs.git/configs-location/java-client/java-client-dev.yaml:5:13"
},
"management.endpoints.web.exposure.include": {
"value": "env",
"origin": "Config Server git@github.com:xxx/spring-configs.git/configs-location/java-client/java-client-dev.yaml:7:44"
},
"management.endpoint.env.enabled": {
"value": true,
"origin": "Config Server git@github.com:xxx/spring-configs.git/configs-location/java-client/java-client-dev.yaml:8:34"
},
"spring.config.import": {
"value": "aws-secretsmanager:/test/springconfig",
"origin": "Config Server git@github.com:xxx/spring-configs.git/configs-location/java-client/java-client-dev.yaml:10:23"
}
}
},

The problem is that I don't get retrieved values from aws secret while storing spring.config.import: "aws-secretsmanager:/test/springconfig" in Git backend for Cloud Config server. I would appreciate any guidance on potential options to achieve this result. I have read that this can be done using Spring Cloud Vault, but it seems excessive for our needs as we would like to use AWS facilities for this purpose.

Thanks, Oleksandr

Comment From: ryanjbaxter

Yes you cannot put spring.config.import in configuration files coming from external sources. It needs to be placed in the application yaml locally of the client.

The config server itself does support AWS Secrets Manager as a backend though https://docs.spring.io/spring-cloud-config/docs/4.0.2/reference/html/#_aws_secrets_manager

Comment From: okulbida

Thanks @ryanjbaxter I'd like to manage both configurations and references to AWS Secrets Manager secrets within property files. For example:

management.endpoints.web.exposure.include: env
management.endpoint.env.enabled: true
aws-secretsmanager:/test/springconfig

I am seeking a way to store all application configuration references, including secrets, in one location. I am interested in the most straightforward and efficient method to achieve this. Could you please suggest an appropriate solution that minimizes complexity?

Comment From: ryanjbaxter

What version of Spring Cloud are you using?

Comment From: okulbida

Currently I have this

<spring-cloud.version>2021.0.6</spring-cloud.version>
<spring-cloud-aws.version>2.4.4</spring-cloud-aws.version>

Comment From: ryanjbaxter

Can you try your original project with Spring Cloud 2022.0.3?

Comment From: okulbida

@ryanjbaxter
Is it possible to have multiple backends for config server ? Option to have both git and something like this would help a lot to manage secrets in proper way https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#_aws_secrets_manager_backend

Comment From: ryanjbaxter

Yes you can use a composite https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#composite-environment-repositories

Comment From: okulbida

Thanks @ryanjbaxter I tested with Spring Cloud 2022.0.3 and it didn't help. For some reason I also cannot run awsparamstore or aws-secretsmanager composite type (multiple git, native types work).

Here is my current config

application.yaml:

server.port: 8888

management.endpoints.web.exposure.include: env
management.endpoint.env.enabled: true

aws.secretsmanager.region: us-east-1
aws.paramstore.region: us-east-1

credentials:
  profile:
    name: default

spring:
  profiles:
    include: composite
  # config:
  #   import:
  #   - 'aws-secretsmanager:/test/springconfig'
  #   - 'aws-parameterstore:/spring-cloud/server/privatekey'
  cloud:
    config:
      server:
        composite:
        - type: awsparamstore
          region: us-east-1
          prefix: /dev 
          profile-separator: '/'    
        - type: git
          uri: git@github.com:repo/configs.git
          basedir: configs-location
          clone-on-start: true
          default-label: main
          timeout: 5
          refresh-rate: 1
          ignoreLocalSshSettings: true
          search-paths:
            - "configs-location/shared"
            - "configs-location/{application}"

pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.0</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>io.example</groupId>
  <artifactId>configserver</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>spring-cloud-config-server</name>
  <description>Spring Config server providing config information</description>
  <properties>
    <java.version>17</java.version>
    <spring-cloud.version>2022.0.3</spring-cloud.version>
    <spring-cloud-aws.version>2.4.4</spring-cloud-aws.version>
    <amazon-awssdk-ssm.version>2.20.69</amazon-awssdk-ssm.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
        <dependency>
            <groupId>io.awspring.cloud</groupId>
            <artifactId>spring-cloud-starter-aws-secrets-manager-config</artifactId>
            <version>${spring-cloud-aws.version}</version>
        </dependency>
        <dependency>
            <groupId>io.awspring.cloud</groupId>
            <artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
            <version>${spring-cloud-aws.version}</version>
        </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-aws-parameter-store-config</artifactId>
        <version>2.2.6.RELEASE</version>
    </dependency>
        <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>ssm</artifactId>
      <version>${amazon-awssdk-ssm.version}</version>
    </dependency>

  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

ERROR:

config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616244539+03:00 2023-06-02T16:44:58.609Z ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616293659+03:00
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616304029+03:00 java.lang.IllegalStateException: Error processing condition on org.springframework.cloud.config.server.config.CompositeRepositoryConfiguration.searchPathCompositeEnvironmentRepository
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616310859+03:00   at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-3.1.0.jar!/:3.1.0]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616317126+03:00   at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616323933+03:00   at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:183) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616329747+03:00   at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616335625+03:00   at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616342099+03:00   at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:427) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616348214+03:00   at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:287) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616354789+03:00   at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:344) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616360413+03:00   at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:115) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616366608+03:00   at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:771) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616372949+03:00   at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:589) ~[spring-context-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616379074+03:00   at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.0.jar!/:3.1.0]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616401782+03:00   at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:733) ~[spring-boot-3.1.0.jar!/:3.1.0]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616408682+03:00   at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:435) ~[spring-boot-3.1.0.jar!/:3.1.0]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616414915+03:00   at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-3.1.0.jar!/:3.1.0]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616420954+03:00   at org.springframework.boot.SpringApplication.run(SpringApplication.java:1305) ~[spring-boot-3.1.0.jar!/:3.1.0]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616426666+03:00   at org.springframework.boot.SpringApplication.run(SpringApplication.java:1294) ~[spring-boot-3.1.0.jar!/:3.1.0]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616432147+03:00   at io.example.configserver.ConfigServerApplication.main(ConfigServerApplication.java:13) ~[classes!/:0.0.1-SNAPSHOT]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616438333+03:00   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616443910+03:00   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616449824+03:00   at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616455529+03:00   at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616461058+03:00   at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[app.jar:0.0.1-SNAPSHOT]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616467082+03:00   at org.springframework.boot.loader.Launcher.launch(Launcher.java:95) ~[app.jar:0.0.1-SNAPSHOT]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616472374+03:00   at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[app.jar:0.0.1-SNAPSHOT]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616478058+03:00   at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) ~[app.jar:0.0.1-SNAPSHOT]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616483715+03:00 Caused by: java.lang.NullPointerException: Cannot invoke "Object.hashCode()" because "key" is null
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616508433+03:00   at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) ~[na:na]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616515734+03:00   at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:888) ~[spring-beans-6.0.9.jar!/:6.0.9]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616521508+03:00   at org.springframework.cloud.config.server.composite.CompositeUtils.getEnvironmentRepositoryFactoryTypeParams(CompositeUtils.java:77) ~[spring-cloud-config-server-4.0.3.jar!/:4.0.3]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616530630+03:00   at org.springframework.cloud.config.server.composite.OnSearchPathLocatorPresent.getMatchOutcome(OnSearchPathLocatorPresent.java:46) ~[spring-cloud-config-server-4.0.3.jar!/:4.0.3]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616536604+03:00   at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-3.1.0.jar!/:3.1.0]
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616542537+03:00   ... 25 common frames omitted
config-server-deployment-54d557ff99-blrn8 config-server 2023-06-02T19:44:58.616547774+03:00

Comment From: ryanjbaxter

Can you change type: awsparamstore to type: awsParameterStore and try again?

Comment From: okulbida

thanks for your reply, this was solved in different way