parameter-store.adoc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. = Parameter Store Integration
  2. Spring Cloud AWS adds support for loading configuration properties from Parameter Store through Spring Boot https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-files-importing[config import feature].
  3. Maven coordinates, using <<index.adoc#bill-of-materials, Spring Cloud AWS BOM>>:
  4. [source,xml]
  5. ----
  6. <dependency>
  7. <groupId>io.awspring.cloud</groupId>
  8. <artifactId>spring-cloud-aws-starter-parameter-store</artifactId>
  9. </dependency>
  10. ----
  11. == Loading External Configuration
  12. To fetch parameters from Parameter Store and add them to Spring's environment properties, add `spring.config.import` property to `application.properties`:
  13. For example, assuming that the parameters in Parameter Store are stored under path `/config/spring`:
  14. |===
  15. | Parameter Name | Parameter Value
  16. | `/config/spring/message` | `Welcome`
  17. | `/config/spring/httpUrl` | `https://external-service:3030/`
  18. |===
  19. Once `spring.config.import` statement is added:
  20. [source,properties]
  21. ----
  22. spring.config.import=aws-parameterstore:/config/spring
  23. ----
  24. Two parameters are added to environment: `message` and `httpUrl`.
  25. If a given path in Parameter Store does not exist, application will fail to start. If parameters retrieved from Parameter Store are not required for the application, and it should continue to startup even when the path is missing, add `optional` before prefix:
  26. [source,properties]
  27. ----
  28. spring.config.import=optional:aws-parameterstore:/config/spring
  29. ----
  30. To load parameters from multiple paths, separate their names with `;`:
  31. [source,properties]
  32. ----
  33. spring.config.import=aws-parameterstore:/config/spring;/config/app
  34. ----
  35. If some parameters are required, and other ones are optional, list them as separate entries in `spring.config.import` property:
  36. [source,properties]
  37. ----
  38. spring.config.import[0]=optional:aws-parameterstore=/config/spring
  39. spring.config.import[1]=aws-parameterstore=/config/optional-params/
  40. ----
  41. If you add indexed parameter names such as `/config/application/cloud.aws.stack_0_.name`, `/config/application/cloud.aws.stack_1_.name`, ... to Parameter Store,
  42. these will become accessible as array properties `cloud.aws.stack[0].name`, `cloud.aws.stack[1].name`, ... in Spring.
  43. === Adding prefix to property keys
  44. To avoid property key collisions it is possible to configure a property key prefix that gets added to each resolved parameter.
  45. As an example, assuming the following parameters are stored under path `/config/my-datasource`:
  46. |===
  47. | Parameter Name | Parameter Value
  48. | `/config/my-datasource/url` | `jdbc:mysql://localhost:3306`
  49. | `/config/my-datasource/username` | `db-user`
  50. |===
  51. By default, `url` and `username` properties will be added to the Spring environment. To add a prefix to property keys configure `spring.config.import` property with `?prefix=` added to the parameter path:
  52. [source,properties]
  53. ----
  54. spring.config.import=aws-parameterstore:/config/my-datasource/?prefix=spring.datasource.
  55. ----
  56. With such config, properties `spring.datasource.url` and `spring.datasource.username` are added to the Spring environment.
  57. NOTE: Prefixes are added as-is to all property names returned by Parameter Store. If you want key names to be separated with a dot between the prefix and key name, make sure to add a trailing dot to the prefix.
  58. == Using SsmClient
  59. The starter automatically configures and registers a `SsmClient` bean in the Spring application context. The `SsmClient` bean can be used to create or retrieve parameters from Parameter Store.
  60. [source,java]
  61. ----
  62. import org.springframework.stereotype.Component;
  63. import software.amazon.awssdk.services.ssm.SsmClient;
  64. ...
  65. @Autowired
  66. private SsmClient ssmClient;
  67. ...
  68. ssmClient.getParametersByPath(request -> request.path("/config/spring/")).parameters();
  69. ----
  70. == Customizing SsmClient
  71. To use custom `SsmClient` in `spring.config.import`, provide an implementation of `BootstrapRegistryInitializer`. For example:
  72. [source,java]
  73. ----
  74. package com.app;
  75. import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
  76. import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
  77. import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
  78. import software.amazon.awssdk.regions.Region;
  79. import software.amazon.awssdk.services.ssm.SsmClient;
  80. import org.springframework.boot.BootstrapRegistry;
  81. import org.springframework.boot.BootstrapRegistryInitializer;
  82. class ParameterStoreBootstrapConfiguration implements BootstrapRegistryInitializer {
  83. @Override
  84. public void initialize(BootstrapRegistry registry) {
  85. registry.register(SsmClient.class, context -> {
  86. AwsCredentialsProvider awsCredentialsProvider = StaticCredentialsProvider.create(AwsBasicCredentials.create("yourAccessKey", "yourSecretKey"));
  87. return SsmClient.builder().credentialsProvider(awsCredentialsProvider).region(Region.EU_WEST_2).build();
  88. });
  89. }
  90. }
  91. ----
  92. Note that this class must be listed under `org.springframework.boot.BootstrapRegistryInitializer` key in `META-INF/spring.factories`:
  93. [source, properties]
  94. ----
  95. org.springframework.boot.BootstrapRegistryInitializer=com.app.ParameterStoreBootstrapConfiguration
  96. ----
  97. If you want to use autoconfigured `SsmClient` but change underlying SDKClient or ClientOverrideConfiguration you will need to register bean of type `AwsClientConfigurerParameterStore`:
  98. Autoconfiguration will configure `SsmClient` Bean with provided values after that, for example:
  99. [source,java]
  100. ----
  101. package com.app;
  102. import io.awspring.cloud.autoconfigure.config.parameterstore.AwsParameterStoreClientCustomizer;
  103. import java.time.Duration;
  104. import org.springframework.boot.BootstrapRegistry;
  105. import org.springframework.boot.BootstrapRegistryInitializer;
  106. import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
  107. import software.amazon.awssdk.http.SdkHttpClient;
  108. import software.amazon.awssdk.http.apache.ApacheHttpClient;
  109. import software.amazon.awssdk.services.ssm.SsmClientBuilder;
  110. class ParameterStoreBootstrapConfiguration implements BootstrapRegistryInitializer {
  111. @Override
  112. public void initialize(BootstrapRegistry registry) {
  113. registry.register(AwsParameterStoreClientCustomizer.class,
  114. context -> new AwsParameterStoreClientCustomizer() {
  115. @Override
  116. public ClientOverrideConfiguration overrideConfiguration() {
  117. return ClientOverrideConfiguration.builder().apiCallTimeout(Duration.ofMillis(500))
  118. .build();
  119. }
  120. @Override
  121. public SdkHttpClient httpClient() {
  122. return ApacheHttpClient.builder().connectionTimeout(Duration.ofMillis(1000)).build();
  123. }
  124. });
  125. }
  126. }
  127. ----
  128. == `PropertySource` Reload
  129. Some applications may need to detect changes on external property sources and update their internal status to reflect the new configuration.
  130. The reload feature of Spring Cloud AWS Parameter Store integration is able to trigger an application reload when a related parameter value changes.
  131. By default, this feature is disabled. You can enable it by using the `spring.cloud.aws.parameterstore.reload.strategy` configuration property (for example, in the `application.properties` file).
  132. The following levels of reload are supported (by setting the `spring.cloud.aws.parameterstore.reload.strategy` property):
  133. * `refresh` (default): Only configuration beans annotated with `@ConfigurationProperties` or `@RefreshScope` are reloaded.
  134. This reload level leverages the refresh feature of Spring Cloud Context.
  135. * `restart_context`: the whole Spring `ApplicationContext` is gracefully restarted. Beans are recreated with the new configuration.
  136. In order for the restart context functionality to work properly you must enable and expose the restart actuator endpoint
  137. [source,yaml]
  138. ====
  139. ----
  140. management:
  141. endpoint:
  142. restart:
  143. enabled: true
  144. endpoints:
  145. web:
  146. exposure:
  147. include: restart
  148. ----
  149. ====
  150. Assuming that the reload feature is enabled with default settings (`refresh` mode), the following bean is refreshed when the secret changes:
  151. ====
  152. [java, source]
  153. ----
  154. @Configuration
  155. @ConfigurationProperties(prefix = "bean")
  156. public class MyConfig {
  157. private String message = "a message that can be changed live";
  158. // getter and setters
  159. }
  160. ----
  161. ====
  162. To see that changes effectively happen, you can create another bean that prints the message periodically, as follows
  163. ====
  164. [source,java]
  165. ----
  166. @Component
  167. public class MyBean {
  168. @Autowired
  169. private MyConfig config;
  170. @Scheduled(fixedDelay = 5000)
  171. public void hello() {
  172. System.out.println("The message is: " + config.getMessage());
  173. }
  174. }
  175. ----
  176. ====
  177. The reload feature periodically re-creates the configuration from config maps and secrets to see if it has changed.
  178. You can configure the polling period by using the `spring.cloud.aws.parameter.reload.period` (default value is 1 minute).
  179. == Configuration
  180. The Spring Boot Starter for Parameter Store provides the following configuration options:
  181. [cols="4,3,1,1"]
  182. |===
  183. | Name | Description | Required | Default value
  184. | `spring.cloud.aws.parameterstore.endpoint` | Configures endpoint used by `SsmClient`. | No | `null`
  185. | `spring.cloud.aws.parameterstore.region` | Configures region used by `SsmClient`. | No | `null`
  186. | `spring.cloud.aws.parameterstore.reload.strategy` | `Enum` | `refresh` | The strategy to use when firing a reload (`refresh`, `restart_context`)
  187. | `spring.cloud.aws.parameterstore.reload.period` | `Duration`| `15s` | The period for verifying changes
  188. | `spring.cloud.aws.parameterstore.reload.max-wait-time-for-restart` | `Duration`| `2s` | The maximum time between the detection of changes in property source and the application context restart when `restart_context` strategy is used.
  189. |===
  190. == IAM Permissions
  191. Following IAM permissions are required by Spring Cloud AWS:
  192. [cols="2"]
  193. |===
  194. | Get parameter from specific path
  195. | `ssm:GetParametersByPath`
  196. |===
  197. Sample IAM policy granting access to Parameter Store:
  198. [source,json,indent=0]
  199. ----
  200. {
  201. "Version": "2012-10-17",
  202. "Statement": [
  203. {
  204. "Effect": "Allow",
  205. "Action": "ssm:GetParametersByPath",
  206. "Resource": "yourArn"
  207. }
  208. ]
  209. }
  210. ----