Spring boot 2.4 버전부터 적용되는 방법입니다.
Spring에서는 애플리케이션의 설정 정보를 관리하는 파일이 있는데, resoures
폴더의 application.yml (.properties)가 바로 그 프로필 파일입니다.
DB와 연동하기 위해서는 DB 비밀번호나 키 값을 넣어야하고, 외부 API를 이용하기 위해서는 API Secret 키를 사용해야 합니다. 이렇게 외부에 그대로 노출되어서는 안되는 기밀 정보를 application.yml에 포함됩니다.
이러한 중요한 기밀 정보(secret)가 그대로 외부로 노출되는 사례를 크리덴셜 스터핑(Credential stuffing)
이라고 합니다. Public Git 저장소에 무심코 기밀 정보를 그대로 Push하게 된다면, 기밀 정보가 노출되어 악용되거나 어마어마한 서비스 비용이 부과되는 등 매우 위험한 상황까지 이어질 수 있구요.
이번 포스트에서는 이러한 기밀 정보를 어떻게 관리하면 더 효율적이고 쉽게 처리할 수 있을지에 대한 방법들을 이야기해보려고 합니다.
환경변수란?
환경변수는 OS에서 스트링을 저장하는 변수로 OS의 환경설정 (실행파일 위치, 홈 디렉토리, ...)과 관련한 정보를 담고 있습니다.
Spring의 application.yml에서는 컴퓨터의 환경변수를 불러와서 삽입할 수 있습니다. 이 방법의 장점은 내 컴퓨터의 환경변수에 중요한 기밀정보들을 저장하고 application.yml에서 불러와 사용하면 Github에 그대로 파일을 올려도 기밀정보가 노출되지 않는다는 점입니다.
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test_db?serverTimezone=Asia/Seoul
username: root
password: $%1234%$
설정 파일에서 위와 같이 MySQL과 연결하기 위한 기밀정보가 있다고 해봅시다. password 부분이 그대로 노출되어 있어서 이 상태로 공개된 저장소에 파일을 업로드하게 되면 위험합니다. 하지만, 환경변수를 사용한다면 노출 위험이 사라지게 됩니다.
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test_db?serverTimezone=Asia/Seoul
username: root
password: ${MYSQL_PASSWORD}
${MYSQL_PASSWORD}
부분이 바로 컴퓨터의 환경변수를 가져오는 부분입니다. 컴퓨터의 환경변수에도 Key-Value처럼 MYSQL_PASSWORD
를 키로 하고, Value에 비밀번호를 입력하면 됩니다.
Spring 설정 프로필 파일은 개발자가 어떤 환경에서 실행할지에 따라 필요한 값이 달라질 수 있습니다. 환경변수를 통해 이를 제어할 수도 있겠지만 예를 들어, 배포 환경에서만 필요한 설정정보가 있고 로컬에서 테스트할 때에는 이 정보가 필요하지 않는 케이스가 있습니다. (ex. ssl 설정)
# default
spring:
profiles:
active: local
# default로 사용할 프로필 선택 (local)
---
spring:
config:
activate:
on-profile: local
# ...
---
spring:
config:
activate:
on-profile: dev
# ...
---
spring:
config:
activate:
on-profile: prod
# ...
가장 기본적인 방법으로 하나의 설정파일 안에 구분자 (---)를 넣어서, 여러개의 프로필을 만드는 방법입니다. 1개의 파일로 모든 환경을 관리할 수 있지만 설정 정보가 많아지면 가독성이 떨어져서 추천하는 방법은 아닙니다.
# application-local.yml
spring:
config:
activate:
on-profile: local
# application-dev.yml
spring:
config:
activate:
on-profile: dev
# application.yml
spring:
profiles:
active: local
# default로 사용할 프로필 선택 (local)
이렇게 환경별로 파일을 따로 만들고(이때, 파일명은 반드시 application-{이름}.yml 형태로 작성해야 합니다)
, default 파일인 application.yml에서 각 프로필을 import해서 활성화하는 방법입니다.
이때 기본값으로 설정된 프로필은 local
인데, dev로 변경하고 싶다면 자바를 실행할 때 -Dspring.profiles.active=dev
명령어를 함께 포함시켜서 Run해주시면 됩니다.
이제, 같은 경로상에 없는 프로필 파일 또한 등록할 수 있는데요. 그 방법은 아래와 같습니다.
# application.yml
spring:
config:
import:
- classpath:/yaml/application-local.yml
- classpath:/yaml/application-dev.yml
profiles:
active: local
저는 yaml이라는 폴더를 하나 만들고 그 안에 local, dev 프로필을 만들었습니다.
default로 설정된 스캔 범위는 resources
폴더로, 하위 폴더까지 스캔하지 않기 때문에 따로 import를 해주셔야 합니다.
설정파일을 용도에 따라 나눠서 분리한 후, 하나의 설정처럼 합쳐서 사용할 수도 있는데요.
# application.yml
spring:
profiles:
include: oauth, jwt
사진처럼 resources
폴더 아래에 application.yml, application-jwt.yml, application-oauth.yml 3개가 있을 때 spring.profiles.include
를 통해, application.yml이 로드될 때 함께 불러올 수도 있습니다.
마지막으로 프로필 그룹입니다.
프로필을 하나의 그룹처럼 등록해서 사용할 수도 있는데요.
# application.yml
spring:
profiles:
active: local # default
group:
local: # local, jwt, oauth profile을 그룹지어 함께 어플리케이션 구동
- jwt, oauth
dev: # dev, jwt, oauth profile을 그룹지어 함께 어플리케이션 구동
- jwt, oauth
이렇게 특정 프로필을 그룹으로 묶어서 함께 로드할 수 있습니다.