2072 단어
10 분
Git 서브모듈로 민감한 정보 관리하기
2025-04-02

인식한 문제#

버디야 프로젝트를 진행하면서 보안상의 문제로 Git에 올리면 안되는 데이터들이 존재하였다. AWS Access key 같은 아주 민감한 정보들은 GitHub가 push한 커밋에 포함된 코드나 텍스트에서 다음과 같은 패턴을 직접 탐지하여 올리지 못하도록 막아 이미 환경 변수로 설정하였다.

domain

하지만 jwt secret key 같이 깃허브에서 막아주지 않는 것들은 개발 초기 단계에서 개발 편의를 위해서 깃허브에 올려 사용을 하였다. 나중에 배포할 때 다른 key 값으로 변경해야겠다 라는 생각으로 미뤄뒀었다. 이제 이런 민감한 정보들을 모두 환경변수로 관리하려고 하니 설정 값들에 변경이 있을 때마다 AWS에 접근을 하여 직접 변경을 해줘야하는 번거로움이 있었다.

또한 여러개 동일한 서버를 두는 경우 동일한 환경변수 세팅을 여러 개의 EC2에 해줘야 하는 불편함이 있다. 따라서 보안상 노출되면 안되는 정보들을 어떻게 효율적으로 관리할까? 라는 문제에 대해 서브모듈을 학습하고 적용해보고자 한다.

서브 모듈이란?#

Git의 레포지토리 하위에 다른 저장소를 관리하기 위한 도구이다. 이때 상위 레포지토리를 슈퍼 프로젝트(superproject), 하위 레포지토리를 서브 모듈(submodule)이라고 부른다. (혹은 부모 저장소, 자식 저장소라고 부르기도 한다.) 서브모듈을 사용하면 특정한 Git 레포지토리를 다른 레포지토리의 하위 디렉토리로 사용할 수 있다.

슈퍼 프로젝트에 서브 모듈을 추가하면, 슈퍼 프로젝트가 하위 모듈의 특정 커밋을 가리키게 된다. 그리고 슈퍼 프로젝트는 현재 가리키고 있는 하위 모듈의 파일을 슈퍼 프로젝트에 추가하게 된다.

이 프로젝트에서는 앞서 말했듯이 서브모듈을 공통으로 사용하는 라이브러리를 관리하기 위해 사용한 것이 아닌 외부에 노출되면 안되는 데이터들을 관리하기 위해 사용하였다.

부모 - 자식 간 주의해야 할 점#

서브모듈은 부모 레포지토리 하위에 자식 레포지토리를 둬서 관리하는 것인데 이 때 부모가 자식을 관리한다고 생각해서는 안된다. 부모 - 자식 관계는 둘 사이 연결되어 있다는 뜻일 뿐, 부모가 자식의 값을 변경한다거나 자식이 변경되면 부모가 변경을 알아차리지 못한다.(처음에 이 개념이 익숙하지 않아 서브모듈이 변경됐는데 왜 부모는 상태가 변경되지 않지? 많이 고생했다..)

domain

왼쪽은 서브모듈을 적용한 부모 레포지토리, 오른쪽은 서브모듈의 커밋이다. 이 때 34baa40이라는 커밋 해시 코드가 새롭게 추가되었는데 부모 레포지토리는 여전히 이전 버전인 5726af4 커밋 해시 코드를 가리키는 것을 볼 수 있다.

즉, 부모와 자식은 별개의 프로젝트로 관리가 되어 별도로 버전 관리가 된다. 따라서 서브 모듈 파일들을 수정하려면 부모 레포지토리가 아닌 자식(서브모듈) 레포지토리에 들어가 직접 수정해야 한다. 그리고 부모는 변경 사항을 알지 못하기 때문에 직접 개발자가 부모 레포지토리에서 최신화된 자식 레포지토리로 업데이트 해줘야 한다.

적용 방법#

1. 서브모듈 레포지토리 생성#

domain

먼저 다음과 같이 private 레포를 생성하고 우리가 서브모듈로 관리하고 싶은 정보들을 추가한다. 위 프로젝트에서는 개발 환경 설정, 로컬 환경 설정, 공통 환경 설정 파일들을 위치시켰다.

  • application-dev.properties
  • application-local.properties
  • application.properties

2. 부모 레포지토리에 만든 서브모듈 추가#

이제 앞서 만든 레포지토리를 서브모듈로 추가해야 한다.

서브모듈 추가 명령어

git submodule add {추가할 저장소의 url}
domain 다음과 같이 추가한 프로젝트 저장소의 이름으로 디렉토리가 생성된다.domain

이 때 .gitmodules라는 이름의 숨김 파일이 생성된다. .gitmodules 도 .gitignore 와 마찬가지로 버전관리 대상이다. 이 파일을 통해 프로젝트 참여자들이 이 프로젝트에 어떤 서브 모듈이 있는지 확인할 수 있다.

3. 서브모듈 수정 후 슈퍼 프로젝트에 반영#

서브 모듈을 변경해보고 그 변경 내용을 슈퍼 프로젝트에서 반영해보자.

domain 다음과 같이 서브모듈 내용을 수정한다. 그리고 서브모듈 디렉토리로 이동(부모 디렉토리가 아님!)하여 어래 명령어를 입력해준다.
git add .
git commit -m 'add submodule file'
git push origin main

이 상태는 서브모듈만 업데이트 된 상태이므로 부모는 업데이트가 되지 않은 상태이다. 따라서 부모 레포지토리에 동기화를 해주는 작업을 거쳐야 한다. 일단 서브모듈 디렉토리에서 빠져나와 부모 디렉토리로 이동한다.

git이 알아서 서브모듈을 fetch하고 업데이트하는 명령어

git submodule update --remote

다음 명령어로 부모 레포지토리가 관리하는 서브모듈도 업데이트를 해줄 수 있다.

4. 빌드 시점에 적용하기#

build.gradle

processResources.dependsOn('copySecret')
tasks.register('copySecret', Copy) {
	from './be-submodule' // 서브 모듈 디렉토리 경로
	include "*.properties"  // 설정 파일 복사
	into 'src/main/resources'  // 붙여넣을 위치
}

build.gradle에 다음과 같이 작성하여 프로젝트 빌드/배포할 때 submodules의 설정 파일들을 /src/main/resources으로 복사하여 사용한다.

.gitignore

### application*.properties ###
src/main/resources/*.properties

또한 복사된 설정 파일들이 public 저장소(부모 레포지토리)에 노출되면 안되기 때문에 .gitgnore에 등록해 push하지 않게 한다.

결과#

더 이상 git에 민감한 정보들이 노출되지 않게 되었고 팀원 한 명이 환경 변수를 수정하면 다른 팀원들이 일일이 환경변수를 설정하지 않고 submodule 업데이트만 하여 효율적으로 관리하게 되었다.

적용 pr 링크#

https://github.com/buddy-ya/be/pull/117

  • ec2에 배포에 서브모듈을을 적용하다 추가적으로 생긴 문제입니다!

ec2에 서브모듈 적용 시 문제 해결#

ec2에서 배포하고 ec2 환경에서 private 파일을 가져오려면 추가적인 자격 검증을 해줘야 한다.

git submodule update --init --recursive

be 폴더에서 다음과 같은 명령어를 작성해서 submodule을 가져와야 하는데 private이라 접근할 수 없다

[ec2-user@ip-172-31-5-208 be]$ git submodule update --remote
Cloning into '/home/ec2-user/be/be-submodule'...
Username for 'https://github.com': maark1106
Password for 'https://maark1106@github.com':

clone하려면 다음과 같이 username과 password를 입력해줘야 하는데 private 파일인 submodule에 접근할 수 있는 자격이 있는지 검증해줘야 한다.

submodule에 접근 권한이 있는 계정에서 생성한 token을 넣어줘야 하는데

settings → developer Settings → Personal access tokens (classic) → generate new token(classic)

  • repo (Full control of private repositories 선택)
  • read:packages
  • write:packages

다음과 같은 설정 후 token을 발급 받는다 다시 git submodule update --init --recursive 명령어 입력 후 github id와 방금 발급 받은 token을 입력하여 private에 접근할 수 있는 자격을 검증하면 된다.

참고 링크#

Git 서브모듈로 민감한 정보 관리하기
저자
Joonyoung Hwang
게시일
2025-04-02