1. 배경 및 목표
현재 저는 회사에서 개발용서버를 구축하기 위해 작업을 하고 있습니다.
먼저 개발서버는 AWS LightSail을 이용하기로 하였습니다.
운영서버는 EC2에 구축되어 있지만 LighSail을 선택한 이유는 정액제로 요금을 부과하기 때문입니다.

현재 운영서버에는 Backend 프로젝트만 올라가있지만 개발서버에는 Frontend 프로젝트와 개발용 DB 또한 Docker로 올릴 계획을 하고 있습니다. 서버 리소스 비용을 정확히 산정하기 힘든 상황에서 요금폭탄을 피하기 위해 Lighsail을 이용하기로 하였습니다.
이러한 상황에서 개발서버와 운영서버의 application.yaml의 환경변수들을 효과적으로 관리하기를 원했고 AWS에서 제공하는 암호 관리 서비스인 AWS Parameter Store를 사용하기로 하였습니다.
AWS Systems Manager Parameter Store - AWS Systems Manager
AWS Systems Manager Parameter Store AWS Systems Manager의 도구인 Parameter Store는 구성 데이터 관리 및 비밀 관리를 위한 안전한 계층적 스토리지를 제공합니다. 암호, 데이터베이스 문자열, Amazon Machine Image(AMI
docs.aws.amazon.com
Parameter Stores는 다른 AWS 서비스에서 엑세스를 할 수 있도록 합니다.

문제는 여기에 제가 이용하려는 AWS LightSail이 없다는것입니다.
그래서 저는 먼저 로컬에서 테스트를 하고 로컬과 동일한 방식으로 Lightsail 인스턴스에 이를 적용하기로 하였습니다.
제가 생각한 구현 순서는 다음과 같습니다.
- 권한 생성
- Parameter Store에 값 추가
- Spring Boot 프로젝트에 의존성 추가 및 적용
- 로컬 테스트
- LightSail 인스턴스 환경에서 테스트
제가 적용한 환경은 다음과 같습니다.
- Spring Boot 3.2.1
- Mac (로컬)
- AWS LightSail
- Docker
2. 구현
1) 권한 생성
IAM은 AWS 리소스에 대한 액세스를 안전하게 제어할 수 있는 웹 서비스입니다.
로컬과 인스턴스에서 Parameter Store에 접근하기 위한 IAM 부터 생성하였습니다.
사용자 생성에서 이름을 설정합니다.

저는 관련 권한만 주기 위해 직접 정책 연결을 체크하였습니다.


SystemsManager를 뜻하는 SSM을 검색하고 ReadOnlyAccess를 선택 후 계정을 생성하였습니다.
생성된 사용자를 선택하고 액세스키를 만듭니다.


생성된 액세스 키와 비밀 액세스 키를 잘 보관해둡니다.
2) Parameter Store에 값 저장
Parameter Store의 이름은 계층구조입니다.
/를 통해서 파라미터의 계층 구조를 나타낼 수 있습니다.

저같은 경우는
- 공통: application
- 로컬: application_local
- 개발: application_dev
- 운영: application_prod
이런식으로 나눠서 저장하였습니다. 잘 정리되있으면 찾기 편하니까 사용하시기 편하게 잘 정하시면 됩니다.
유형은 보안 문자열을 사용하였습니다.
3) SpringBoot 의존성 추가
저는 gradle을 사용하고 있으므로 build.gradle에 의존성을 추가해줍니다.
// https://mvnrepository.com/artifact/io.awspring.cloud/spring-cloud-aws-dependencies
implementation(platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.4.0"))
implementation("io.awspring.cloud:spring-cloud-aws-starter-parameter-store")
여기서 spring-cloud-aws-dependencies는 BOM(Bill of Materials) 역할을 하는 dependency 입니다.
AWS 관련 다양한 starter(S3, Parameter Store, SQS 등)의 호환 버전을 자동으로 관리하게 해줍니다.
platform()은 의존성 버전을 고정하거나 통일시키는 BOM 기능을 사용하겠다는것을 의미합니다.
즉, 위에는 버젼관리용이고 실제 사용하는것은 spring-cloud-aws-starter-parameter-store 입니다.
3. 로컬 테스트
1) 로컬에 IAM 권한 설정
로컬에서 IAM 권한을 가져다 쓸 수 있도록 저장해줍니다. 저는 Mac 환경에서 테스트했습니다.
터미널에서 brew를 통해 AWS CLI를 설치하고 aws configure 명령어로 보관했던 액세스키와 비밀 액세스키를 저장했습니다.
# awscli 설치
brew install awscli
# 액세스 키 설정
aws configure

액세스키, 비밀 액세스키, 리젼(지역)을 입력하였습니다.
그러면 ~/.aws/credentials와 ~/.aws/config 경로에 값이 저장됩니다.
권한이 잘 설정되었는지 확인하기 위해 저장된 값을 불러와봤습니다.
aws ssm get-parameter \
--name "/config/application_dev/datasourse.master.jdbc-url" \
--with-decryption --region ap-northeast-2

위와같이 값이 잘 불러와지는것을 확인했습니다.
2) Spring Boot 프로젝트 application.yaml에 적용
spring:
profiles:
active: local
group:
local:
- secret-key
- quartz-local
dev:
- secret-key
- quartz-dev
prod:
- secret-key
- quartz
config:
import:
- 'aws-parameterstore:/config/application/'
- 'aws-parameterstore:/config/application_${spring.profiles.active}/'
프로젝트의 application.yaml의 일부분입니다.
Spring Boot 애플리케이션 실행 시, spring.config.import에 명시한 위치에서 설정을 가져옵니다.
여기서 aws-parameterstore: 는 AWS Parameter Store에서 값ㅇ르 가져오겠다는 선언입니다.
현재 프로젝트에서는 spring.profiles.active를 통해 실행할 spring profile을 지정합니다.
해당 부분을 변수로 사용하고 parameter store의 계층구조를 이용하여 각 실행환경에 따라 변수를 다르게 가져올 수 있도록 하였습니다.
예를들어 local로 놓고 실행하면 /config/application_local에서 값을 가져오게 됩니다.
여기서 가장 주의해야할 점은 마지막이 /로 끝나게 해야한다는 것 입니다.
이것때문에 1~2시간 버렸기 때문에 이 글을 보시는 분들은 저와같은 고통을 겪지 않으셨으면 합니다.
application-secret-key.yaml에 적용한 암호를 예시로 가져오겠습니다.
spring:
config:
activate:
on-profile: secret-key
# security
auth:
publicKey: ${auth_publicKey}
parameter store를 적용할 부분은 Spring Security 관련 암호인 auth.publicKey 입니다.
두가지 경우를 보여드리기 위해 첫번째 암호는 완전한 계층 구조로 저장하였고, 두번째 암호는 _를 통해 키값을 구성하였습니다.

완전한 계층 구조로 암호를 저장하면 yaml에 해당 암호를 명시하지 않아도 알아서 값을 가져옵니다.

위와같이 주석처리하여도 값을 가져와서 정상적으로 실행됩니다.
주의할 점은 완전한 계층구조를 사용하고 ${auth.publicKey}를 값에 넣으면 자기자신을 참조하는 순환 참조가 일어나서 오류가 발생합니다.
저같은 경우는 yaml에서 값을 다 빼버리고 AWS에서만 관리하는것보다 어느정도 명시가 되어있는편이 좋을것같다고 판단하여 _를 통해 암호를 구성하였습니다.

4. Lightsail 테스트
1) IAM 권한 설정
로컬 테스트를 통해 IAM 권한을 설정하면 ~/.aws/credentials와 ~/.aws/config 경로에 값이 저장되는것을 확인할 수 있었습니다.
vim을 통해 직접 해당 내용을 넣었습니다.
# 로컬에서 읽을 내용 가져오기
cat ~/.aws/credentials
cat ~/.aws/config
# 인스턴스에 해당 내용 저장
mkdir -p ~/.aws
vim ~/.aws/credentials
vim ~/.aws/config
값에 넣을 내용은 로컬에서 cat 명령어를 통해 가져와 그대로 가져다 박았습니다.

2) 도커로 Spring Boot 프로젝트 실행
해당 설정이 적용된 프로젝트를 Docker를 통해 띄웠습니다.
여기서 중요한 점은 컨테이너 내부에는 방금 넣은 IAM 권한이 없기 때문에 볼륨 마운트를 통해 이를 적용해야 한다는 것 입니다.
다음과 같은 명령어를 통해 실행하였습니다.
docker run --name {컨테이너 이름} -p 8080:8080 -v $HOME/.aws:/root/.aws:ro {사용할 이미지}
-v가 볼륨마운트 부분입니다. :ro는 읽기 전용 옵션으로 컨테이너 내부에서 이를 변경할 수 없도록 합니다.

잘 실행된것을 확인할 수 있었습니다.
마지막 넋두리
위의 글에 다 작성해놨지만 글이 길어서 놓치실 분들을 위해 마지막 넋두리로 남겨놓겠습니다.
순환참조와 import에서 마지막 / 조심하시기 바랍니다.
참고
AWS Systems Manager Parameter Store - AWS Systems Manager
AWS Systems Manager Parameter Store AWS Systems Manager의 도구인 Parameter Store는 구성 데이터 관리 및 비밀 관리를 위한 안전한 계층적 스토리지를 제공합니다. 암호, 데이터베이스 문자열, Amazon Machine Image(AMI
docs.aws.amazon.com
Spring Boot에서 AWS Parameter Store 사용
프로젝트를 Github에 올리게 되면, application.yml에 있는 DB 접속정보, Jwt에 사용되는 secret key와 같은 중요 정보가 모두에게 노출 될 수 있습니다. 이런 중요 정보를 노출하지 않기위해 사용하는 방식
gong-story.tistory.com
내용이 많이 헤비해진것같습니다.
사실 간단하게 쓸라면 양 확 줄여서 쓸 수 있을것같은데 하면서 하나하나 다 캡쳐따고 적어놓고 한게 그냥 날려버리기 아까워서 겪은 과정을 최대한 다 집어넣으려고 했습니다.
누군가에겐 도움이 되겠죠 뭐
'Backend > Spring' 카테고리의 다른 글
| [Spring] 1 대 1 실시간 채팅 구현하기 - Stomp, MongoDB, Redis (0) | 2026.01.24 |
|---|---|
| [Spring] Redis Sorted Set, ZSet 을 이용한 매칭 시스템 구현하기 (0) | 2025.10.15 |
| [Spring] Spring AOP의 동작원리, JDK Dynamic Proxy와 CGLIB (1) | 2025.04.28 |
| [Spring] Apache.commons.exec 사용, 외부 명령어 실행 API 만들기, Java에서 Shell 사용 (0) | 2024.05.26 |
| [WebSocket] Spring, React, Stomp로 실시간 채팅, 저장 구현하기 (12) | 2024.02.19 |