Externalized Configuration

Externalized Configuration 패턴은 마이크로서비스 아키텍처(MSA)에서 디자인 패턴 중 하나이다.
이 패턴은 애플리케이션의 구성 정보를 코드와 분리하여 외부에서 관리하는 방식을 말한다.

이 패턴은 애플리케이션의 구성 정보를 외부 저장소에 보관하고, 런타임에 이를 읽어오는 방식으로 동작한다.
구성 정보는 데이터베이스, 파일 시스템, 환경 변수 등 다양한 외부 저장소에 보관될 수 있다.
이를 통해 각 환경(개발, 테스트, 운영 등)에 따라 다른 설정을 적용할 수 있으며, 설정 변경 시 애플리케이션을 재배포하지 않아도 된다.

Externalized Configuration 패턴은 마이크로서비스 아키텍처에서 구성 관리의 복잡성을 줄이고, 시스템의 유연성과 확장성을 높이는 데 크게 기여한다. 이 패턴을 효과적으로 사용하면 다양한 환경에서 애플리케이션을 쉽게 배포하고 관리할 수 있다.

Externalized Configuration
https://learn.microsoft.com/en-us/azure/architecture/patterns/external-configuration-store

주요 특징

  1. 중앙 집중식 관리: 모든 구성 정보를 한 곳에서 관리할 수 있다.
  2. 동적 업데이트: 애플리케이션을 재배포하지 않고도 구성을 변경할 수 있다.
  3. 환경별 설정 관리: 개발, 테스트, 스테이징, 프로덕션 등 다양한 환경에 맞게 설정을 분리하여 관리할 수 있다. 예를 들어, 데이터베이스 연결 정보나 API 엔드포인트 등을 환경별로 다르게 설정할 수 있다.
  4. 보안 강화: 민감한 정보(예: 데이터베이스 비밀번호, API 키 등)를 코드에 포함시키지 않고 외부에서 안전하게 관리할 수 있어 보안성을 높일 수 있다.
  5. 코드와 설정의 분리: 설정 정보를 코드에서 분리함으로써 코드의 변경 없이 설정을 수정할 수 있다. 이는 배포 주기를 단축하고, 설정 변경으로 인한 오류를 최소화하는 데 도움이 된다.

구현 방법

  • 환경 변수(Environment Variables):
    • 운영 체제의 환경 변수를 활용하여 설정 정보를 관리한다. 이는 간단하고 널리 사용되는 방법이다.
  • 구성 서버(Configuration Server):
    • Spring Cloud Config와 같은 구성 서버를 사용하여 중앙에서 설정 정보를 관리하고, 각 서비스는 필요 시 해당 서버로부터 설정을 가져온다.
  • 컨피그맵(ConfigMap) 및 시크릿(Secret):
    • 쿠버네티스(Kubernetes)를 사용하는 경우, ConfigMap과 Secret을 활용하여 설정 정보를 관리할 수 있다.

장점

  1. 유연성 향상: 코드 변경 없이 애플리케이션의 동작을 수정할 수 있다.
  2. 배포 간소화: 환경별 구성을 쉽게 관리할 수 있어 배포 과정이 간소화된다.
  3. 보안 강화: 민감한 정보를 코드에서 분리하여 관리할 수 있다.
  4. 확장성 개선: 다수의 마이크로서비스 인스턴스에 대한 구성을 효율적으로 관리할 수 있다.

주의사항

  1. 구성 정보의 일관성 유지: 여러 서비스 간 구성 정보의 일관성을 유지해야 한다.
  2. 버전 관리: 구성 정보의 버전을 관리하여 롤백이 가능하도록 해야 한다.
  3. 보안: 외부화된 구성 정보에 대한 접근 제어와 암호화가 필요하다.

구현 코드

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Configuration
public class DatabaseConfig {
    @Value("${database.url}")
    private String databaseUrl;
    
    @Value("${database.username}")
    private String username;
    
    @Value("${database.password}")
    private String password;
    
    @Bean
    public DataSource dataSource() {
        return DataSourceBuilder.create()
            .url(databaseUrl)
            .username(username)
            .password(password)
            .build();
    }
}

// application.yml
database:
  url: jdbc:mysql://localhost:3306/mydb
  username: ${DB_USERNAME}  // 환경 변수에서 값을 가져옴
  password: ${DB_PASSWORD}  // 환경 변수에서 값을 가져옴

참고 및 출처