If you are looking for a centralized configuration solution for your distributed system, then look no further! Amazon System Manager’s Parameter Store is here to save the day.
For this solution to work, you will need to take advantage of Spring Profiles. Take a look at this link for more information: https://www.baeldung.com/spring-profiles
package com.creditshop.infrastructure.config;
/**
* Created by cory on 10/19/18.
*/
import com.creditshop.infrastructure.service.AWSCredentialsProviderImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement;
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder;
import com.amazonaws.services.simplesystemsmanagement.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Configuration("awsSsmConfig")
public class AwsSsmConfig
{
private static final Logger logger = LoggerFactory.getLogger(AwsSsmConfig.class);
@Value("${spring.profiles.active:dev}")
private String activeProfile;
@Autowired
private ConfigurableEnvironment environment;
@Bean
public AWSCredentialsProviderImpl awsCredentialsProviderServiceImpl()
{
return new AWSCredentialsProviderImpl();
}
@Bean
public AWSSimpleSystemsManagement awsClient(AWSCredentialsProviderImpl awsCredentialsProviderService)
{
AWSSimpleSystemsManagement client = AWSSimpleSystemsManagementClientBuilder.standard()
.withCredentials(awsCredentialsProviderService.getMainCredentials()).withRegion(awsCredentialsProviderService.getCurrentRegion()).build();
logger.info("Created client");
return client;
}
private List<Parameter> getPropertyValues(AWSSimpleSystemsManagement awsClient, String prefix)
{
GetParametersByPathRequest parameterRequest = new GetParametersByPathRequest();
parameterRequest.setPath("/" + prefix + "/");
parameterRequest.setRecursive(true);
parameterRequest.setWithDecryption(true);
GetParametersByPathResult parameterResult = awsClient.getParametersByPath(parameterRequest);
List<Parameter> parametersList = parameterResult.getParameters();
String nextToken = parameterResult.getNextToken();
while (parameterResult.getNextToken() != null)
{
parameterRequest.setNextToken(nextToken);
parameterResult = awsClient.getParametersByPath(parameterRequest);
parametersList.addAll(parameterResult.getParameters());
nextToken = parameterResult.getNextToken();
}
return parametersList;
}
@Bean(name="ssmPropertySource")
public MapPropertySource ssmMapPropertySource(AWSSimpleSystemsManagement awsClient)
{
logger.info("Retrieving config from AWS parameter store");
Map<String, Object> config = new HashMap<>();
List<Parameter> params = getPropertyValues(awsClient, activeProfile);
params.forEach(parameter ->
{
String name = parameter.getName().replaceFirst("/" + activeProfile + "/", "");
logger.info("Found " + parameter.getName() + " " + parameter.getType());
config.put(name, parameter.getValue());
});
MutablePropertySources sources = environment.getPropertySources();
MapPropertySource ssmPropertySource = new MapPropertySource("aws-ssm", config);
sources.addFirst(ssmPropertySource);
return ssmPropertySource;
}
}
The above solution will inject all properties in your parameter store into the Spring Environment. Once this happnes your code can easily access with environment.getProperty(“property”)