일전에 무작위 트래픽 공격으로 DB가 삭제되는 사건 이후로 접속 정보 등의 민감 정보를 repository에 올리지 않고 GitHub Actions CI/CD를 사용할 방도가 떠오르지 않아 app 빌드, 도커 이미지 빌드, 배포까지 수동으로 진행해왔다.
그동안 찾아본 방법으로는 application.yml 파일 자체를 인코딩하여 secrets로 올려버리는 방법, Vault와 같은 외부 서비스를 따로 구축하여 관리하는 방법 등이 있었다.
그 중에서 나는 git submodule을 활용하기로 했다.
우선 application.yml 파일을 저장하기 위한 private repo를 만들어준다. 나는 egomoya-secrets
라는 이름으로 만들었다.
그 후 app repo에 해당 repo를 submodule로 등록해주면 된다.
git submodule add <private repo url>
그럼 이런식으로 submodule이 등록된다.
그리고 submodule에서 업데이트가 있는 경우
git submodule update --remote
명령어를 통해 내용을 업데이트 한다. 그런데 위 명령어를 통해 바로 app repo에 submodule의 변경점이 적용되는 것은 아니다.
업데이트 후 app repo에서 커밋과 푸쉬를 해주면 반영할 수 있다.
git add egomoya-secrets
git commit -m "commit message"
git push
그리고 CI/CD 파이프라인에서 submodule을 사용하도록 추가해주면 private repo에서 민감 정보를 가져와 쓸 수 있게 된다.
- name: Checkout-source code
uses: actions/checkout@v4
with:
token: ${{ secrets.ACTION_TOKEN }}
submodules: true
이떄 토큰은 git clone 등에 쓰는 로그인 대용 토큰을 쓰면 된다
하지만 위 방법을 쓰고도 빌드 시 private repo의 정보를 불러오지 못했다. 하지만 원인은 매우 간단했다. 내가 자바와 스프링에 익숙하지 않은 탓이었다.
빌드시 당연히 src/main/resources
경로에서 application.yml을 찾아야 한다. 하지만 나는 submodule만 추가해 줬을 뿐 해당 파일을 옮기지 않았다.
그래서 build.gradle
안에 submodule에서 파일을 복사하는 task를 만들어주고 사용했다.
# build.gradle
tasks.register('copySubmodule', Copy) {
from './egomoya-secrets'
include '*.yml'
into './src/main/resources'
}
---
# mail.yml -> 파이프라인
# Spring boot application 빌드
- name: Build with gradle
run: |
./gradlew copySubmodule
./gradlew bootJar
이 과정을 모두 마치고 드디어 CI/CD 성공했다!
하지만 아직 남은 문제점이 있다. private repository를 썼지만 어찌됐든 github에 정보를 업로드 하는 것은 같다. 이 부분은 그래도 신경 쓸 필요가 있는 것 같다. 그래도 파일 통째로 secret 등록하는 것 보다는 나은 것 같다. 어짜피 그것도 github에 정보 올리는 건 마찬가지니까.
그리고 아직 Vault와 같은 외부 서비스를 도입하기엔 작은 개발이고 관리를 위한 리소스가 더 들어갈 것 같았다.