[I-project] application.yml 환경 분리와 민감한 정보는 submodule을 통해 관리

Jifrozen·2024년 1월 3일
0

I-project

목록 보기
3/4

application.yml 환경 분리

실무에서는 dev, stage, production 등으로 인프라를 구축하여 환경을 분리하여 사용한다.
예를 들어, dev에서는 dev를 위한 DB를 쓰는식으로 진행한다.
따라서 이를 설정해주는 파일인 application.yml에서 나눠줘야한다.
한 파일에서 모든 환경을 넣어준다면 굉장히 길고 피곤한 설정파일이 완성된다.

이를 해결하기 위해 우리는 각 환경에 맞춰 설정파일을 나눠주려고 한다.

우선은 개발초기이기 때문에
기본
local
dev
production
datasource
key ( 시크릿 키를 담은 파일 )
로 나누도록 한다.

설정파일을 분리하는 방법은
application-{환경}.yml로 post-fix를 통해 환경명을 설정하거나
spring.config.activate.on-profiles 를 통해 명시해줄 수 있다.

application.yml

spring:
  profiles:
    group:
      local: "local, key" // local 환경에서 local과 key를 사용한다.
      dev: "dev, datasource, key" // dev 환경에서 dev, datasource, key를 사용한다.
      prod: "production, datasource, key" // prod 환경에서 production, datasource, key를 사용한다.
    active: local

profile에 대한 전체적인 관리를 group을 통해 해준다.

application-local.yml

spring:
  config:
    activate:
      on-profile: "local"
  h2:
    console:
      enabled: true
      settings:
        web-allow-others: true

  datasource:
    url: jdbc:h2:mem:projecti
    driver-class-name: org.h2.Driver
    username: sa
    password:

  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      default_batch_fetch_size: 1000
      hibernate:
        format_sql: false
        show_sql: false

application-dev.yml

spring:
  config:
    activate:
      on-profile: "dev"
  jpa:
    hibernate:
      ddl-auto: update
    properties:
      default_batch_fetch_size: 1000
      hibernate:
        format_sql: false
        show_sql: false

application-production.yml

spring:
  config:
    activate:
      on-profile: "production"
  jpa:
    hibernate:
      ddl-auto: none

application-datasource.yml

spring:
  datasource:
    url: jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${DB_NAME}?useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true&tinyInt1isBit=false
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maxLifetime: 580000
      maximum-pool-size: 20
    password: ${MYSQL_PASSWORD}
    username: ${MYSQL_USERNAME}

  jpa:
    hibernate:
      ddl-auto: update
    properties:
      default_batch_fetch_size: 1000
      hibernate:
        format_sql: false
        show_sql: false

application-key.yml

spring:
  config:
    activate:
      on-profile: "key"
  cryptography:
    aes:
      secret-key: 
  api-key:
    google:
      google-calendar-api:
        key: 
    open-ai:
      open-ai-api:
        key: 
    cryptography:
      aes:
        secret-key: 

보면 알겠지만 key와 datasource는 공개적으로 보이면안되는 데이터를 담고있다. 이러한 변수들을 어떻게 관리할 수 있을지 살펴보자.

민감한 정보는 submodule을 통해 관리

민감한 정보를 관리하는 방법에는 여러가지 방법이 존재합니다.
1. jasypt를 사용한 설정 파일 암호화

키가 노출되었을때 암호화가 무의미하기 때문에 추가적으로 보안을 위해 행할 수 있는 조치라고 생각하였고 암호화한 키를 그대로 퍼블릭 환경에 노출하는 것은 위험하다고 느꼈습니다.

  1. github secret

Github Repository - Settings - Secrets and Variables - Actions

secret을 생성하여 application 내용을 집어넣는 경우입니다.

이는 application 파일이 수정될때마다 붙여넣어야하는 번거로움과 파일 변경 추적관리가 안되기 때문에 사용하지 않았습니다.

  1. 서브모듈 이용하기

private repository를 생성하여 설정파일을 보관하고 서브모듈로 연결하여 사용하는 방법입니다.

3-1. private repo생성
applicatione-key와 application-datasource push

3-2 기존 repo에 git submodule add {private repo 주소]
.gitmodules파일이 생성되고 root 저장소에 config 폴더가 생성됩니다.

기존 repo에서 commit push하면

다음과 같이 서브모듈이 생성됩니다.

3-3. build.gradle과 .gitignore
build.gradle에 해당 내용을 추가합니다.

task copyGitSubmodule(type: Copy) {
    copy {
        from './config'
        include '*.yml'
        into './src/main/resources'
    }
}

./config 폴더안에 있는 yml파일을 src/main.recources에 옮긴다는 의미입니다.

힘들게 옮겼으면 public git repo에 올라가면 안되겠죠?

.gitignore에 해당 내용을 추가합니다.

### Git Submodule
src/main/resources/application-key.yml
src/main/resources/application-datasource.yml

3-4. ci 워크플로우가 있다면 다음 내용을 추가하여 application이 반영되도록 합니다.

- name: Checkout repo
        uses: actions/checkout@v3
        with:
          token: ${{ secrets.SUBMODULE_TOKEN }}
          submodules: true

시크릿변수 SUBMODULE_TOKEN에 config(private repo)에 접근가능한 token을 집어넣습니다.

3-5 private repo에 새로운 내용을 반영한다면?
git submodule update --remote

git submodule foreach git pull

git add.
git commit
git push

해당 내용을 반영하여 config head가 최신내용을 바라보도록 합니다.

0개의 댓글