이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • Spring profile은 단순 환경 이름이 아니라 어떤 운영 위험을 제어하는가?
  • Environment와 property source 우선순위 때문에 어떤 설정 사고가 생기는가?
  • 운영에서 active profile과 실제 설정 값을 어떻게 확인해야 하는가?

개요

Spring profile은 실행 환경에 따라 bean과 property를 다르게 활성화하는 장치다.

local, dev, staging, prod라는 이름만 외우면 부족하다.

profile은 datasource, cache, external API endpoint, logging level, actuator exposure, security setting 같은 운영 동작을 바꾼다.

잘못된 profile로 뜨면 코드가 정상이어도 운영 장애가 난다.

Profile이 바꾸는 것

profile은 설정 파일만 바꾸는 것이 아니다.

Spring에서는 profile 조건에 따라 bean 자체가 달라질 수 있다.

@Bean
@Profile("local")
PaymentClient fakePaymentClient() {
    return new FakePaymentClient();
}
 
@Bean
@Profile("prod")
PaymentClient realPaymentClient() {
    return new RealPaymentClient();
}

prod에서 local profile이 켜지면 실제 결제가 호출되지 않을 수 있다.

반대로 local에서 prod profile이 켜지면 운영 외부 시스템을 호출할 수 있다.

설정 예시

공통 설정은 기본 파일에 두고, 환경별 차이는 profile 파일에 둔다.

application.yml

spring:
  application:
    name: order-api
management:
  endpoints:
    web:
      exposure:
        include: health,prometheus

application-prod.yml

spring:
  datasource:
    url: ${DB_URL}
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
logging:
  level:
    root: INFO

운영 Secret 값은 파일에 직접 쓰지 않고 외부에서 주입한다.

Environment와 우선순위

Spring Boot는 여러 property source를 합쳐 Environment를 만든다.

명령행 인자, 환경 변수, system property, profile별 설정 파일, 기본 설정 파일 등이 함께 작동한다.

문제는 같은 key가 여러 곳에 있을 때다.

예를 들어 서버 환경 변수에 오래된 SPRING_PROFILES_ACTIVE=dev가 남아 있으면 image나 jar는 새 버전이어도 dev profile로 뜰 수 있다.

echo "$SPRING_PROFILES_ACTIVE"
printenv | grep -E 'SPRING|DB_|REDIS|PROFILE'

운영에서 설정을 확인할 때는 repository 파일만 보지 말고 실제 process environment도 확인해야 한다.

Active Profile 확인

Spring Boot startup log에는 active profile이 나온다.

The following 1 profile is active: "prod"

Actuator env endpoint로도 확인할 수 있지만 운영에서는 민감 값 노출 위험이 있으므로 접근 권한과 masking을 조심해야 한다.

더 안전한 방법은 release note, startup log, 배포 도구의 environment snapshot을 함께 남기는 것이다.

장애 신호

  • 운영 로그에 active profile이 dev 또는 local로 찍힌다.
  • prod에서 debug logging이 켜져 로그량이 급증한다.
  • staging에서 운영 DB URL을 바라본다.
  • 특정 인스턴스만 다른 external API endpoint를 호출한다.
  • feature flag나 timeout 값이 문서와 다르게 적용된다.
  • Actuator endpoint가 운영에서 과도하게 노출되어 있다.

운영 체크리스트

  • active profile을 배포 후 로그나 health info로 확인하는가?
  • profile별 datasource, cache, external API endpoint가 문서화되어 있는가?
  • profile 파일에 Secret 값이 직접 들어 있지 않은가?
  • 운영 서버 environment variable이 release note와 일치하는가?
  • command line argument로 임시 override한 값이 남아 있지 않은가?
  • actuator exposure가 profile별로 다르게 관리되는가?
  • staging이 prod와 충분히 비슷하지만 prod Secret을 사용하지 않는가?

안전한 완화 조치

잘못된 profile이 의심되면 신규 배포를 멈추고 active profile과 process environment를 확인한다.

운영 설정을 바로 여러 개 수정하지 않는다.

profile 하나를 바꾸면 datasource, cache, endpoint, actuator exposure가 함께 바뀔 수 있다.

임시로 환경 변수를 고쳐 재시작해야 한다면 변경 전후 값을 기록하고 rollback 값을 준비한다.

외부 API나 DB를 잘못 바라본 상태라면 데이터 쓰기 여부를 먼저 확인해야 한다.

인프라 담당자와 공유할 자료

서비스: order-api prod
증상: 운영에서 dev payment endpoint 호출
확인: startup log active profile=prod, PAYMENT_API_URL=dev endpoint
최근 변경: 배포 도구 environment variable 수정
요청: 인스턴스별 environment variable snapshot 확인
주의: 결제 요청 일부가 dev endpoint로 갔는지 trace id로 확인 필요

profile과 environment 문제는 “프로필 이름”보다 실제 key/value 출처를 공유해야 한다.

실전 팁

  • profile 이름은 환경뿐 아니라 위험도를 담게 설계한다.
  • local profile에는 운영 외부 시스템을 직접 호출하지 못하게 한다.
  • prod profile의 actuator exposure는 최소화한다.
  • startup log에서 active profile을 반드시 확인한다.
  • profile별 차이는 README나 release checklist에 표로 남긴다.

위험 신호!

  • SPRING_PROFILES_ACTIVE를 서버에서 수동으로 바꾸고 기록하지 않는다.
  • prod profile 파일에 Secret 값이 직접 들어 있다.
  • profile별 DB URL과 external API endpoint를 팀원이 모른다.
  • staging이 prod와 너무 달라 배포 전 검증 의미가 없다.
  • 운영에서 actuator env를 넓게 열어 민감 설정이 노출된다.

확인 질문

확인 질문

  • Spring profile을 단순 환경 이름으로만 보면 위험한 이유는 무엇인가?
    • profile은 설정 파일뿐 아니라 bean, datasource, external API, actuator 노출, logging level까지 바꿀 수 있기 때문이다.
  • 운영에서 실제 설정을 확인할 때 repository 파일만 보면 부족한 이유는 무엇인가?
    • 환경 변수, 명령행 인자, 배포 도구 override가 더 높은 우선순위로 실제 값을 바꿀 수 있기 때문이다.
  • 잘못된 profile이 의심될 때 먼저 확인할 증거는 무엇인가?
    • startup log의 active profile, process environment, release note의 기대 profile, datasource와 external endpoint 값이다.

참고 문서