레넌의 개발 일기

Git Submodule로 비밀 정보 관리하기 본문

Git

Git Submodule로 비밀 정보 관리하기

brorae 2022. 10. 12. 01:04

Git Submodule 이란?

Git Submodule은 메인(부모) 레포지토리에 하위(자식) 레포지토리를 두고 관리하기 위한 도구이다. 하나의 프로젝트에서 다른 프로젝트를 함께 사용해야 하는 경우 주로 활용한다.

 

사용 계기

프로젝트를 하면서 application.yml에 담기는 민감 정보들을 관리해야 할 일이 생겼다. 지금까지는 application.yml에 환경변수를 설정하여 직접 EC2에서 이를 처리했지만, Git Submodule이라는 좋은 방법이 있어서 해당 개념과 적용 방법에 대해서 작성을 해보려고 한다.

 

적용 과정

Repository 만들기

우선 submodule을 위한 레포지토리를 생성해야 한다. 다음과 같은 과정을 통해 생성을 하면 된다.

  1. 팀 organization 계정 생성
  2. 비밀 정보를 보관할 Repository를 private으로 생성
2022-gong-seek           // 팀 organization
        ⌙ secret         // private 레포지토리

 

비밀 파일 만들기

이제 민감한 정보를 저장하는 파일 application.yml을 private repository에 루트 디렉토리에 생성해 준다.

2022-gong-seek
        ⌙ secret
                ⌙ application-prod.yml
                ⌙ application-dev.yml
                ⌙ application-local.yml

 

메인 Repository에 서브모듈 추가하기

아래의 두 명령어는 어떤 차이가 있을까? 사실 -b {branch_name}을 제외하면 동일하다. 단지 -b 옵션을 주면 하위 레포지토리의 특정 브랜치를 기준으로 submodule을 추가한다. 해당 옵션이 없으면 default branch를 기준으로 submodule을 등록한다.

$ git submodule add {submodule_repository_url}

또는

$ git submodule add -b {branch_name} {submodule_repository_url}

이제 프로젝트로 이동해서 서브모듈을 등록해보도록 하겠다. 다음 명령어를 통해 submodule을 추가할 수 있다.

$ git submodule add https://github.com/[Private Repository URL].git src/main/resources/secret

위 명령어의 결과로 .gitmodules 라는 파일이 생성된다.

[submodule "backend/src/main/resources/secret"]
	path = backend/src/main/resources/secret
	url = https://github.com/gong-seek/secret.git

이제 프로젝트 구조는 아래와 같이 변경되었다.

root
├── frontend
└── backend
	└───── src/main/resources
				└───── secret
					├───── application-prod.yml
					└───── application-dev.yml
					└───── application-local.yml

서브 모듈을 추가한 내용을 이제 커밋해주면 된다. 다음 명령어로 커밋해 주도록 하자.

$ git add *
$ git commit -m "feat: 서브모듈 적용"

이 후 원격 레포지토리로 푸쉬해주면 기본적인 설정은 끝이다.

 

팀원들에게 submodule 적용시키기

다른 팀원이 submodule을 사용하기 위해서는, 먼저 메인 프로젝트를 클론한 후, 밑의 명령어를 입력하면 된다. 처음으로 project를 clone할 때만 입력하면 된다.

$ git submodule init

$ git submodule update

추가로, 메인 프로젝트 clone에서 하위 프로젝트 적용까지 하나의 명령어로 처리할 수도 있다.

$ git clone --recurse-submodules {project_url}

메인 프로젝트에 submodule이 이미 있고, 하위 프로젝트의 새로운 커밋을 가져와야하는 상황에선 update 명령어를 활용한다. 

$ git submodule update --remote  // .gitmodules 파일에 정의되어 있는 브랜치(default는 main 또는 master)의 최신 버전으로 업데이트

$ git submodule update --remote --merge  // 로컬에서 작업 중인 부분과 원격에 작업된 부분이 다른 경우 머지까지 진행

 

서브모듈 내용 수정하기

서브 모듈에서 무언가를 수정하면, 경로를 서브모듈 경로로 이동한 다음, 일반 레포지토리와 똑같이 진행하면 된다.

$ cd .../src/main/resources/secret
$ git checkout main
$ git pull

$ git add .
$ git commit -m "feat: 서브모듈 추가 반영"
$ git push origin main

여기서 중요한 점은 서브 모듈의 커밋을 메인 커밋보다 먼저 해야한다는 것이다. 메인 프로젝트는 서브 모듈을 그대로 저장하는 게 아니라 서브 모듈의 url, path, commit을 저장하고 있다. 즉, 메인 프로젝트가 나중에 커밋된 서브모듈의 변경 사항을 추적하지 못하기 때문에 의도하지 않은 오류가 생길 수 있다.

 

서브모듈 내용을 수정하기 - Push

푸쉬도 커밋과 마찬가지로 서브모듈 먼저, 메인 프로젝트를 다음에 하는 것을 반드시 기억해야 한다.

 

Gradle에서 활용하기

서브 모듈은 도입했지만 해당 설정 파일을 읽지 못해 설정 파일을 빌드에 포함시켜야 하는 문제가 있었다. 이를 해결하기 위해서 gradle.build를 활용해 빌드 시에 파일을 복사하는 방안을 사용해서 문제를 해결했다.

processResources.dependsOn('copySecret')

task copySecret(type: Copy) {
    from 'src/main/resources/secret/application-prod.yml' 
    into 'src/main/resources'

    from 'src/main/resources/secret/application-dev.yml' 
    into 'src/main/resources'
    
    from 'src/main/resources/secret/application-local.yml' 
    into 'src/main/resources'
}

 

마무리

서브모듈을 통해 민감정보를 조금이나마 더 편하게 관리할 수 있게 되었다.

처음에 application-local.yml은 서브모듈로 관리하지 않고, .gitignore를 활용하여 관리하였다. 하지만 이렇게 하니, 팀원들끼리 파일이 최신화가 안되는 경우가 많았다. 이를 해결하기 위해 프로필 별 yml 파일을 모두 한번에 서브모듈로 관리하기로 하여 local도 함께 관리하게되었다.

 

참고

https://tecoble.techcourse.co.kr/post/2021-07-31-git-submodule/

'Git' 카테고리의 다른 글

Git Merge와 Rebase의 차이  (0) 2022.02.17