
application.yml에는 흔히 민감한 정보(DB 관련 정보 등)가 저장되기 때문에 .gitignore에 application.yml을 작성해 github에 올라가는 것을 막으라고 한다. 협업 과정에서 application.yml을 github에 올리지 않고 별도로 공유하는 것은 솔직히 번거롭다. 수정 사항이 생겼는데도 깜빡해서 공유하지 않아 로컬마다 application.yml이 다르게 설정되어 있는 경우가 발생하기도 한다.
그렇다면, 민감한 정보 값은 AWS System Manager의 Parameter Store에 저장하고 application.yml는 Parameter Store의 키만 작성해 값을 가져오는 방식으로 한다면 어떨까? 이 경우 application.yml에는 민감한 값이 공개되지 않고 Parameter Store에서 사용한 키 값 이름만이 저장되어 github에 올릴 수 있다. 이는 매우 편리하고 변경에도 용이하면서, 보안상으로도 적절한 방법이다.
비밀번호, 데이터베이스 문자열 및 라이선스 코드와 같은 비밀번호 및 구성 데이터를 중앙 집중식으로 저장 및 관리합니다. 값을 암호화하거나 일반 텍스트로 저장하고 모둔 수준에서의 액세스를 보장합니다.
AWS에서는 위와 같이 설명이 적혀있다. 쉽게 말하자면, 키-값 형태로 값을 저장할 수 있는 저장소이다.
키는 슬래시를 사용해 계층 구조로 구성 가능하다. 예를 들면, parameter/rds/a와 parameter/rds/b는 parameter/rds라는 같은 계층에 존재한다.
이를 사용해 dev 계층과 prod 계층을 만들어 개발 환경에 사용하는 파라미터, 프로덕션 환경에 사용하는 파라미터를 별도의 계층으로 분리할 수 있다.
파라미터는 표준, 고급 파라미터로 나뉘는데, 표준의 경우 무료이다. 고급의 경우 유료인 대신, 다른 계정과 파라미터를 공유하는 등의 추가적인 기능을 가진다.
파라미터 유형으로는 문자열, 문자열 목록, 보안 문자열이 존재한다. 보안 문자열의 경우 KMS 키를 사용해 데이터를 암호화해 민감한 값을 저장하는데 적절하다.
Parameter Store는 Secret Manager와 자주 비교된다. 두 서비스 모두 키-값 저장소이고, 비밀 값을 저장하는데 사용할 수 있기 때문이다. 그러나 두 서비스는 용도가 다르다. Parameter Store는 환경 변수, 구성 데이터의 저장에 더 초점을 두는 서비스이고, Secret Manager는 민감한 값, 보안 값의 저장에 초점을 두는 서비스이다.
두 서비스 간 가장 중요한 차이점은 Secret Manager가 유료 서비스라는 것이다. 유료 서비스인 만큼 암호 관리에 유용한 자동 회전 등의 여러 기능을 제공한다.
Parameter Store에서 표준 파라미터, 보안 문자열을 사용해 암호를 저장한다면 무료로 민감한 값을 저장할 수 있다. 비용 절감이 중요하다면 Parameter Store를 사용하자.
뭐든지 이름을 지을 수 있다면 컨벤션이 존재하기 마련이다.
컨벤션은 자신의 프로젝트 팀 규칙에 맞춰 적절하게 설정하면 된다. 이전에 프로젝트를 진행할 때에는 이 벨로그 글을 참고해 / Repo 이름 / AWS 서비스 이름 / stage / 변수명 으로 계층 구조를 생성해 작성했다.
파라미터 스토어에 MySQL 연결 관련 값(URL, Password, Username)를 저장해보자!
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PW}
application.yml에서 DB_URL , DB_USERNAME , DB_PW 세 가지 값을 파라미터 스토어에 표준, 보안 문자열 유형의 파라미터로 저장하고, 스프링 부트 서버 실행 시 파라미터를 가져오도록 설정할 예정이다.
AWS 콘솔에 접속해 System Manager 서비스로 이동한다.
이동 후 왼쪽 메뉴에서 애플리케이션 도구 목록 중 "파라미터 스토어"를 클릭한다.

파라미터 생성을 클릭한다.

파라미터 이름, 계층, 유형을 설정한다. 무료로 사용하기 위해 표준 계층을 선택하고, 민감한 값을 저장할 예정이기 때문에 보안 문자열 유형을 선택한다. 적절한 파라미터 값을 작성한다.
이 과정을 통해 /rds/DB_URL , /rds/DB_USERNAME , /rds/DB_PW 라는 세 가지 파라미터를 생성했다.

// BOM
implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.2.1")
// 사용하려는 프레임워크 모듈
implementation io.awspring.cloud:spring-cloud-aws-starter-parameter-store
// AWS 자격 증명
implementation io.awspring.cloud:spring-cloud-aws-starter
Spring Boot 서버에서 파라미터를 가져오기 위해 사용하는 종속성은 위와 같다.
BOM은 여러 라이브러리를 사용하는 경우, 라이브러리 간의 호환성 문제 해결을 위해 사용한다. 즉, 특정 라이브러리의 버전 관리 및 호환성 보장을 위한 패키지이다.
BOM의 버전은 이 깃허브 주소를 참고해 작성하자.
현재 이 실습에서는 MySQL과 연결할 예정이기 때문에 MySQL 관련 종속성도 설치해야 한다.
spring:
config:
import:
- 'aws-parameterstore:[파라미터 경로1]'
- 'aws-parameterstore:[파라미터 경로2]'
현재 이 실습의 파라미터 경로는 /rds/가 된다.
여기서 존재하지 않는 파라미터 경로를 작성한다면 오류가 발생하면서 스프링부트 서버가 실행되지 않으니 유의하자.
만약 파라미터 스토어에 /myproject/rds/dev/DB_NAME , /myproject/ec2/prod/ROLE , /myproject/rds/dev/DB_PW 파라미터를 추가했다면, application.yml에는 다음과 같이 작성하면 된다.
spring:
config:
import:
- 'aws-parameterstore:/myproject/rds/dev/'
- 'aws-parameterstore:/myproject/ec2/prod/'
위 코드를 작성했다면, application.yml에 표현 언어를 통해 가져온 파라미터 값을 사용할 수 있다.
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PW}
로컬 Spring boot 서버가 Parameter Store의 파라미터 값을 가져오기 위해서는 다음과 같은 조건을 충족해야 한다.
kms:Decrypt ,ssm:GetParametersByPath ,ssm:GetParameters ,ssm:GetParameter)을 가져야 한다.Configure를 설정하는 방법은 이 포스트를 참고하면 된다.
Configure 설정 시 리전 설정을 반드시 해야 한다!!!! 해당 파라미터가 위치한 리전으로 리전 설정을 해야 Spring Boot가 제대로 실행된다. aws configure set region [리전명] 으로도 설정 가능하다.
EC2에 배포한 Spring boot 서버가 Parameter Store의 파라미터 값을 가져오기 위해서는 다음과 같은 조건을 충족해야 한다.
kms:Decrypt ,ssm:GetParametersByPath ,ssm:GetParameters ,ssm:GetParameter)을 가져야 한다.아래 JSON 코드를 IAM 정책에서 추가하고, IAM 사용자, IAM 역할에 해당 정책을 부여해 사용하자.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"ssm:GetParametersByPath",
"ssm:GetParameters",
"ssm:GetParameter"
],
"Resource": [
"arn:aws:ssm:*:767397956447:parameter/*",
"arn:aws:kms:*:767397956447:key/*"
]
}
]
}
Parameter Store를 도입한 이후부터 application.yml 뿐만 아니라 민감한 값까지 관리하기 편리해지고, 보안적으로 더 좋아졌다. 로컬에서 배포 환경으로 변화함에 따라 변경해야 하는 값도 수정하기 편리해졌다. Parameter Store를 적극적으로 활용하자..!