簡単にSpring Boot + AWS パラメータストアから取得する

## はじめに

awsのパラメータストアから簡単に値をSpringのDIコンテナに登録して`@Value`で簡単に取得できるようにする

## 環境

+ Spring Boot 3.1.3
+ Java 17
+ gradle 8.2.1


## AWS パラメータストア

次のパラメータをパラメータストアに作成

+ spring.datasource.url
+ spring.datasource.username
+ spring.datasource.password

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110010/bcdbe1f7-bfae-65ad-45f1-edcdcddf5cf1.png)



## build.gradle

次の依存を追加

```build.gradle
implementation platform('io.awspring.cloud:spring-cloud-aws-dependencies:3.0.2')
implementation 'io.awspring.cloud:spring-cloud-aws-starter-parameter-store'
```


## application.yml

aws パラメータストアから値を取得しSpring のDIコンテナに追加するために`spring.config.import`を追加する

```application.yml
spring:
  config:
    import: aws-parameterstore:/
```

例えば、次のようなパラメータが設定されている場合は、application.ymlの設定は下記の通りとなる

|パラメータ名| 値 |
|--|--|
| /config/spring/message |Welcome|
|/config/spring/httpUrl|external-service:3030/|


```application.yml
spring:
  config:
    import: aws-parameterstore:/config/spring
```


詳しくは、Springの公式[10.1. Loading External Configuration](https://docs.awspring.io/spring-cloud-aws/docs/3.0.0/reference/html/index.html#loading-external-configuration-2)を参照



## Javaコード

利用する場合は、Springの`@Value`を利用するようにすれば問題なく取得できる


```java
    import org.springframework.beans.factory.annotation.Value;

	@Value("${spring.datasource.url}")
	private String url;
	
	@Value("${spring.datasource.username}")
	private String username;

	@Value("${spring.datasource.password}")
	private String password;
```

---

## ローカル環境と結合環境でパラメータの値を変更したい場合

よくある環境変数で対応していたものをパラメータストアを利用して行いたい



### application.yml

```application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost
    username: ユーザー名
    password: パスワード
```


### application-dev.yml

結合環境(dev)のほうに、aws パラメータストアの設定を追加する
`spring.datasource.url`などは書かない


```application-dev.yml
spring:
  config:
    import: aws-parameterstore:/
```


### プロファイルを指定して起動

+ Spring Bootの起動時に`spring.profiles.active=dev`を指定すれば結合環境の場合のみawsのパラメータストアから値を取得するようになる
+ `spring.profiles.active=dev`を指定しない場合はapplication.ymlから値を取得する（application-dev.ymlは読み込みされない）


## awsの権限

aws パラメータストアから値を取得するために以下の権限を付与しておくこと


```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ssm:GetParametersByPath",
            "Resource": "*"
        }
    ]
}
```
https://docs.awspring.io/spring-cloud-aws/docs/3.0.0/reference/html/index.html#iam-permissions-7


---

## ローカル環境でawsに接続する方法

ローカル環境でaws パラメータストアに接続して動作確認する場合の接続方法はいつかあるが、環境変数`AWS_ACCESS_KEY_ID`と`AWS_SECRET_ACCESS_KEY`を設定して動作確認した

> 1. Java System Properties - aws.accessKeyId and aws.secretAccessKey
> 1. Environment Variables - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
> 1. Web Identity Token credentials from system properties or environment variables
> 1. Credential profiles file at the default location (~/.aws/credentials) shared by all AWS SDKs and the AWS CLI
> 1. Credentials delivered through the Amazon EC2 container service if `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`" environment variable is set and security manager has > permission to access the variable,
> 1. Instance profile credentials delivered through the Amazon EC2 metadata service

https://docs.awspring.io/spring-cloud-aws/docs/3.0.0/reference/html/index.html#defaultcredentialsprovider


## 余談

設定さえ出来れば、ソースコードの追加はほぼなく簡単に取得できた