=== Integrating your Spring Cloud application with the AWS Parameter Store

Spring Cloud provides support for centralized configuration, which can be read and made available as a regular Spring
`PropertySource` when the application is started. The Parameter Store Configuration module allows you to use this mechanism
with https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html[AWS Parameter Store].

Simply add a dependency on the `spring-cloud-starter-aws-parameter-store-config` starter module to activate the support.
The support is similar to the support provided for the Spring Cloud Config Server or Consul's key-value store:
configuration parameters can be defined to be shared across all services or for a specific service and can be
profile-specific. Encrypted values will be decrypted when retrieved.

All configuration parameters are retrieved from a common path prefix, which defaults to `/config`. From there shared
parameters are retrieved from a path that defaults to `application` and service-specific parameters use a path that
defaults to the configured `spring.application.name`. You can use both dots and forward slashes to specify the names
of configuration keys. Names of activated profiles will be appended to the path using a separator that defaults to an
underscore.

That means that for a service called `my-service` the module by default would find and use the following parameters:
[cols="3*", options="header"]
|===
|Parameter key
|Spring property
|Description

|`/config/application/cloud.aws.stack.name`
|`cloud.aws.stack.name`
|Shared by all services that have the Configuration support enabled. Can be overridden with a service- or profile-specific property.

|`/config/application_production/cloud.aws.stack.name`
|`cloud.aws.stack.name`
|Shared by all services that have the Configuration support enabled and have a `production` Spring profile activated.
Can be overridden with a service-specific property.

|`/config/my-service/cloud/aws/stack/auto`
|`cloud.aws.stack.auto`
|Specific to the `my-service` service. Note that slashes in the key path are replaced with dots.

|`/config/my-service_production/cloud/aws/stack/auto`
|`cloud.aws.stack.auto`
|Specific to the `my-service` service when a `production` Spring profile is activated.
|===

Note that this module does not support full configuration files to be used as parameter values like e.g. Spring Cloud
Consul. AWS Parameter Store's Standard Parameter values are limited to 4096 characters, so we only support individual
Spring properties being configured.

You can configure the following settings in a Spring Cloud `bootstrap.properties` or `bootstrap.yml` file
(note that relaxed property binding is applied, so you don't have to use this exact syntax):
[cols="3*", options="header"]
|===
|Property
|Default
|Explanation

|`aws.paramstore.prefix`
|`/config`
|Prefix indicating first level for every property loaded from the Parameter Store.
Value must start with a forward slash followed by one or more valid path segments or be empty.

|`aws.paramstore.defaultContext`
|`application`
|Name of the context that defines properties shared across all services

|`aws.paramstore.profileSeparator`
|`_`
|String that separates an appended profile from the context name. Can only contain
dots, dashes, forward slashes, backward slashes and underscores next to alphanumeric characters.

|`aws.paramstore.failFast`
|`true`
|Indicates if an error while retrieving the parameters should fail starting the application.

|`aws.paramstore.name`
|the configured value for `spring.application.name`
|Name to use when constructing the path for the properties to look up for this specific service.

|`aws.paramstore.enabled`
|`true`
|Can be used to disable the Parameter Store Configuration support even though the auto-configuration is on the classpath.

|`aws.paramstore.region`
|`eu-central-1`
|Can be used to configure region AWSSimpleSystemsManagementClients.
|===

[TIP]
====
In order to find out which properties are retrieved from AWS Parameter Store on application startup,
turn on `DEBUG` logging on `io.awspring.cloud.paramstore.AwsParamStorePropertySource` class.

[source,indent=0]
----
logging.level.io.awspring.cloud.paramstore.AwsParamStorePropertySource=debug
----
====

In `spring-cloud` `2020.0.0` (aka Ilford), the bootstrap phase is no longer enabled by default. In order
enable it you need an additional dependency:

[source,xml,indent=0]
----
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-bootstrap</artifactId>
  <version>{spring-cloud-version}</version>
</dependency>
----

==== Spring Boot Configuration Import Support
From Spring Cloud AWS 2.3.0 onwards, the Parameter Store Configuration module additionally supports using
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-files-importing[Spring Boot's (2.4.0+) application config import feature]
 to load Parameter Store values into a Spring application's Environment.

[NOTE]
====
This is the recommended approach for importing Parameter Store values from Spring Cloud AWS 2.3.0 onwards.
Using the module's Spring Cloud bootstrap PropertySource is now considered a legacy approach, and support for it will
be withdrawn in Spring Cloud AWS 3.0.
====

Importing Parameter Store values using this mechanism is enabled by using Boot's `spring.config.import` application
config property with a prefix of `aws-parameterstore:`, and optionally specifying a list of the names of parameters to
import. The table below provides examples of supported property values and describes their behaviour.

[cols="2*", options="header"]
|===
|Property
|Description

|`spring.config.import=aws-parameterstore:`
|Importing parameters based on spring.application.name property value for each active profile

|`spring.config.import=aws-parameterstore:config-key;other-config-key`
|Importing parameters by individual keys

|`spring.config.import=optional:aws-parameterstore:config-key;other-config-key`
|When `optional` is used the application will start even if the specified parameter is not found.

|`spring.config.import=optional:aws-parameterstore:other-config-key,aws-parameterstore:required-config-key`
|Optional and required values can be separated by comma. List can be used as well.
|===

Spring Boot 2.4 changed the ways files are loaded which means profile loading has changed for spring-cloud-aws as well.
Link to Spring Boot reference docs about file specific loading: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-files-profile-specific[Reference Docs]
Read more on the official: https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4[Spring Blog].

==== IAM Permissions
Following IAM permissions are required by Spring Cloud AWS:

[cols="2"]
|===
| Get parameter from specific path
| `ssm:GetParametersByPath`

|===

Sample IAM policy granting access to Parameter Store:

[source,json,indent=0]
----
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ssm:GetParametersByPath",
            "Resource": "yourArn"
        }
    ]
}
----
