MSA 환경에서 각 서비스가 각자 설정을 관리하면 관리 포인트가 너무 많아진다.
Spring Cloud Config Server로 중앙 집중식 설정 관리를 구현했다.
처음에는 간단해 보였는데 환경변수 주입 방식 때문에 꽤 삽질했다.
1. Config Server 구조
config-repo (GitHub)
├── application.yml # 전체 공통
├── application-local.yml # 로컬 공통
├── application-prod.yml # 운영 공통
└── payment-service/
├── payment-service.yml # payment-service 공통
├── payment-service-local.yml # payment-service 로컬
└── payment-service-prod.yml # payment-service 운영
config-server (Spring Cloud Config Server)
→ config-repo를 읽어서 각 서비스에 전달
payment-service
→ config-server에서 설정을 받아서 사용설정 우선순위는 더 구체적인 파일이 일반적인 파일을 덮어쓴다.
payment-service-local.yml > payment-service.yml > application-local.yml > application.yml2. config-repo 설정 파일 작성
payment-service.yml (공통)
spring:
jpa:
properties:
hibernate:
format_sql: true
show-sql: true
payment-service-local.yml (로컬)
server:
port: 8085
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: create-drop
flyway:
enabled: false
toss:
secret-key: '{cipher}암호화된값'
payment-service-prod.yml (운영)
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://postgres:5432/payment
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: validate
flyway:
enabled: true
toss:
secret-key: ${TOSS_SECRET_KEY}
prod는 민감정보를 환경변수로 관리한다. DB 비밀번호처럼 팀 공통 ENCRYPT_KEY로 암호화하기 어려운 값은 서버 환경변수로 주입한다.
3. payment-service application.yml 수정
기존 application.yml에 있던 datasource, jpa 설정을 전부 제거하고 Config Server 연동 설정만 남겼다.
spring:
application:
name: payment-service
config:
import: "optional:configserver:${CONFIG_SERVER_URL:http://localhost:8888}"
cloud:
config:
username: ${CONFIG_SERVER_USERNAME}
password: ${CONFIG_SERVER_PASSWORD}
payment-service라는 이름이 config-repo의 폴더명/파일명과 일치해야 한다.
4. 삽질 1 — 401 Unauthorized
처음 실행하니까 이런 에러가 났다.
401 on GET request for "http://localhost:8888/payment-service/default"Config Server에 Basic Auth가 걸려있는데 인증 정보를 못 넘기고 있었다.
원인 분석
application.yml에 이렇게 되어있었다.
spring:
cloud:
config:
username: ${CONFIG_SERVER_USERNAME:}
password: ${CONFIG_SERVER_PASSWORD:}
${CONFIG_SERVER_USERNAME:}은 기본값이 빈 문자열이라 인증이 항상 실패했다.
그리고 .env 파일에 값이 있어도 터미널에서 확인하니 환경변수가 주입이 안 되어있었다.
echo $CONFIG_SERVER_USERNAME
# (아무것도 안 나옴)
원인: build.gradle에서 .env를 읽어서 Gradle 변수로는 사용하지만 Spring 실행 시 시스템 환경변수로 주입되지 않는다.
해결: IntelliJ Run Configuration → Environment variables에 직접 추가했다.
CONFIG_SERVER_USERNAME=admin
CONFIG_SERVER_PASSWORD=admin1234그리고 application.yml에서 기본값 제거했다.
spring:
cloud:
config:
username: ${CONFIG_SERVER_USERNAME}
password: ${CONFIG_SERVER_PASSWORD}
5. 삽질 2 — payment-service/default로 요청
로그를 보니 이런 로그가 있었다.
GET "http://localhost:8888/payment-service/default"default 프로파일로 요청하고 있어서 payment-service-local.yml을 못 읽어왔다.
해결: payment-service IntelliJ Run Configuration에 Active profiles에 local 추가했다.
Active profiles: local이후 로그가 이렇게 바뀌었다.
Located environment: name=payment-service, profiles=[local]6. toss.secret-key 암호화
config-repo에 토스 시크릿 키가 평문으로 올라가 있으면 보안 문제다. Config Server의 /encrypt 엔드포인트로 암호화했다.
curl -u admin:admin1234 \
-X POST http://localhost:8888/encrypt \
-d "test_sk_6bJXmgo28e71a9Obm2JjVLAnGKWx"
응답받은 암호문을 payment-service-local.yml에 저장했다.
toss:
secret-key: '{cipher}41da203e17de7526e41751252bffc8e117...'
반드시 작은따옴표로 감싸야 한다. 없으면 YAML 파싱 에러가 난다.
Config Server가 ENCRYPT_KEY로 자동 복호화해서 payment-service에 평문으로 전달한다.
7. 최종 동작 확인
config-server 실행 후 payment-service를 재시작하니 이런 로그가 찍혔다.
Fetching config from server at : http://localhost:8888
Located environment: name=payment-service, profiles=[local]Config Server에서 설정을 잘 받아오고 있다.
마무리
Config Server 연동에서 겪은 삽질을 정리하면 이렇다.
삽질 1 — 401 Unauthorizedbuild.gradle에서 .env를 읽어도 Spring 실행 시 환경변수로 주입되지 않는다. IntelliJ Run Configuration에 직접 추가해야 한다.
삽질 2 — default 프로파일로 요청
payment-service Run Configuration에 Active profiles에 local을 추가해야 payment-service-local.yml을 읽어온다.
민감정보 암호화
Config Server의 /encrypt 엔드포인트로 암호화 후 {cipher} 접두어와 함께 저장한다. 작은따옴표 필수!
다음 편에서는 아웃박스 패턴 구현을 다룰 예정이다.
'Spring 개발일지' 카테고리의 다른 글
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - X-User-Id 헤더 기반 사용자 인증 적용 (0) | 2026.05.11 |
|---|---|
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 아웃박스 패턴 구현 (0) | 2026.05.08 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - PaymentErrorCode 예외처리 구현 (0) | 2026.05.06 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 환불 및 결제 조회 API 구현 (2) | 2026.05.04 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 토스 ACL + 결제 승인 API 구현 삽질기 (0) | 2026.05.01 |