Skip to content

Profile-based Parameter Store Retrieval is Missing in 3.x #1344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
evangaito opened this issue Feb 12, 2025 · 4 comments
Open

Profile-based Parameter Store Retrieval is Missing in 3.x #1344

evangaito opened this issue Feb 12, 2025 · 4 comments
Labels
status: team-discussion Team has to figure out how to proceed type: documentation Documentation or Samples related issue

Comments

@evangaito
Copy link

Creating an issue from this as version 2.x of spring-cloud-aws had great support for Spring profile-based parameter retrieval, including using multiple profiles. In 3.x the support for spring profiles has been completely removed. A seemingly popular workaround has been posted to StackOverflow that leverages the spring.profiles.active property. That solution looks like this:

spring:
  config:
    import:
      - aws-parameterstore:/config/app_${spring.profiles.active}/

The problem with this approach is that parameters can only be retrieved for a single profile and only if there is one active profile. Even if you only want to load parameters based on one of multiple active profiles, the presence of additional profiles breaks the import string.

Would really like to see more complete profile support reintroduced into newer versions of this library.


Discussed in #1340

Originally posted by jaroslaw-blazkow February 5, 2025
Hi, I'm trying to migrate to the newest awspring libraries, but I cannot find solution for the new approach with specifying paramstore variables.
I've tried to use
spring.config.import: "aws-parameterstore:" in bootstrap.yml but it seems its not longer supported with default resolvers with aws.parameterstore.separator, etc. and left unbound, so I found out this solution:

spring:
  config:
    import:
      - aws-parameterstore:/config/app_${spring.profiles.active}

but the problem is, that I've got couple profiles active. How to solve it?

@MatejNedic
Copy link
Member

Hey @evangaito , yes this is I am afraid drawback of spring.config.import implementation. Please check my PR.

You could do something like.

application.properties with default loadings.

application-dev.properties with

spring:
  config:
    import:
      - aws-parameterstore:/config/app_dev

application-staging.properties with

spring:
  config:
    import:
      - aws-parameterstore:/config/app_staging

Since we are leveraging on Spring internal configuration mechanism it is not possible to change this.

Please check spring-projects/spring-boot#43514

@evangaito
Copy link
Author

Thanks for the quick reply @MatejNedic! Sounds like there is no plan to reintroduce any sort of "automatic" contexts to the ParameterStoreConfigDataLocationResolver. Adding the import to the various profile config files makes sense, but most of our environments have no additional config, all environment-specific properties are pulled from AWS. So that solution would require us to introduce config files for profiles that don't currently exist. Correct me if I'm wrong but another solution that might work better for us is to simply pass the import string as a start-up flag like we already do with the profile as -Dspring.config.import=aws-parameterstore:/config/app_<profile>. Since that is already the time we decide which profile to use, we know the specific profile we'd want to include in the import property value.

@evangaito
Copy link
Author

@maciejwalkowiak replied on the linked discussion and got me thinking about how I might be able to implement a custom solution that recognizes profiles. I ended up creating my own version of ParameterStoreConfigDataLocationResolver that basically has one minor change: it will replace a placeholder with each active profile.

Instead of this in the original:

contexts.forEach(propertySourceContext -> locations
					.add(new ParameterStoreConfigDataResource(propertySourceContext, location.isOptional(), sources)));

I replaced it with this:

contexts.forEach(propertySourceContext -> {
        if (propertySourceContext.contains(PROFILE_PLACEHOLDER)) {
          profiles.getActive().forEach(profile ->
              locations.add(new ParameterStoreConfigDataResource(propertySourceContext.replace(PROFILE_PLACEHOLDER, profile), location.isOptional(), sources)));
        } else {
          locations
              .add(new ParameterStoreConfigDataResource(propertySourceContext, location.isOptional(), sources));
        }
      });

The new resolver uses its own prefix (which I just replaced with a dummy one here) plus defines the profile placeholder:

  public static final String PREFIX = "custom-paramstore:";
  public static final String PROFILE_PLACEHOLDER = "<profile>";

This change allows me to add an import like so:

spring:
  config:
    import: "optional:custom-paramstore:/config/app-<profile>/"

and it will resolve that single context into one location per active profile. The final thing you have to do to register this location resolver is create or modify a META-INF/spring.factories file and add

org.springframework.boot.context.config.ConfigDataLocationResolver=\
  my.custom.package.CustomParameterStoreDataLocationResolver

I figured I would just share this as another potential workaround for this issue.

@maciejwalkowiak
Copy link
Contributor

Fantastic @evangaito! Thanks for sharing your solution.

@MatejNedic MatejNedic added type: documentation Documentation or Samples related issue status: team-discussion Team has to figure out how to proceed labels Mar 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: team-discussion Team has to figure out how to proceed type: documentation Documentation or Samples related issue
Projects
None yet
Development

No branches or pull requests

3 participants