이런 민감한 정보들을 Repository에 그대로 노출하게 되면 무조건 큰일이 날 수 밖에 없다. 그렇다면 해당 정보는 어떻게 감출 수 있을까?
AWS의 Secret Manager 와 GitHub의 Secrets 가 생각났다.
AWS는 아무래도 비용이 들기 때문에 GitHub의 Secrets를 사용해보기로 결정했다!!
Repository로 가서 Settings를 클릭!
왼쪽의 Secrets and variables의 Actions 를 클릭!
그럼 위와 같은 화면으로 가게 됩니다. 나는 이미 추가를 해뒀기 때문에 3개의 Secrets를 가지고 있는 상황.
여기서 초록색 버튼을 클릭!
그럼 이렇게 새롭게 Secret을 등록할 수 있다. Name 에는 내가 알아볼 수 있는 이름을 작성하고 Secret에 실제 숨길 데이터를 작성하면 된다.
자~ 이제 여기서부터 뻘짓 들어갑니다잉?
spring:
datasource:
url: ${FINALE_DB_URL}
username: ${FINALE_DB_USERNAME}
password: ${FINALE_DB_PASSWORD}
그냥 무작정 application.yml 에 때려박아버리기~
분명 처음 구글링을 할 때는 이렇게 바로 설정하면 된다고 적혀있었는데 아무리 빌드를 해도 test에서 실패하는 것.
엥? 뭐야 어디서 실패야!! 했더니
> Task :test
FinaleApplicationTests > contextLoads() FAILED
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:180
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:802
Caused by: org.springframework.beans.factory.BeanCreationException at ConstructorResolver.java:655
Caused by: org.springframework.beans.BeanInstantiationException at SimpleInstantiationStrategy.java:177
Caused by: java.lang.IllegalArgumentException at Assert.java:111
5 tests completed, 1 failed
> Task :test FAILED
스프링부트 프로젝트를 생성할 때 기본으로 만들어주는 test 파일의 contextLoads() 에서 에러가 난다는 것!
제대로 확인해보니 DB에 연결을 못해서 나는 에러였다. 그래서 아!! yml 파일에 해당 데이터가 제대로 들어가지 않고 있구나!! 라고 생각.
그래서 더 찾아보니...
GitHub Actions의 gradle.yml에만 환경변수가 적용되어 Spring Boot 의 application.yml 에서는 바로 사용할 수 없다는 것.... ㅠㅠㅠ
그러면 gradle.yml 에서 해당 변수를 받아서 다시 Spring Boot 로 값을 넘겨줘야 한다는 소리다.
- name: yml 값 세팅
uses: microsoft/variable-substitution@v1
with:
files: ./src/main/resources/application.yml
env:
spring.datasource.url: ${{ secrets.FINALE_DB_URL }}
spring.datasource.username: ${{ secrets.FINALE_DB_USERNAME }}
spring.datasource.password: ${{ secrets.FINALE_DB_PASSWORD }}
코드를 보기만 해도 아주 깔끔하게 이해 할 수 있다. properties 파일처럼 줄줄줄 써야 한다는게 살짝 아쉽긴 하지만..
이렇게 코드를 작성하면 해당 설정 값에 자동으로 덮어쓰기 되어 secrets 값이 스프링에서도 잘 적용되게 된다!
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
name: Java CI with Gradle(finale CI)
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: yml 값 세팅
uses: microsoft/variable-substitution@v1
with:
files: ./src/main/resources/application.yml
env:
spring.datasource.url: ${{ secrets.FINALE_DB_URL }}
spring.datasource.username: ${{ secrets.FINALE_DB_USERNAME }}
spring.datasource.password: ${{ secrets.FINALE_DB_PASSWORD }}
- name: Gradle 명령 실행을 위한 권한을 부여합니다
run: chmod +x gradlew
- name: Setup Gradle
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
with:
gradle-version: '8.5'
- name: Build with Gradle 8.5
run: gradle build
이전 포스트에서 Secrets 변수까지 포함해서 완성된 코드!
Secrets 값을 받아오는 부분에서 조금 오래 걸리긴 했는데
정리를 너무 잘 해주셔서 아주 쉽게 해결 할 수 있었다.
다른 블로그에서 본 코드는 base64 인코딩(이게 맞았나...?)을 사용해서 값을 집어넣는 방식을 사용하던데 해당 코드에서는
uses: microsoft/variable-substitution@v1
를 사용해서 아주 깔끔하게 해결할 수 있었다.
저 microsoft/variable-substitution@v1
이 너무 궁금해서 지피티에게 물어봤다.
이 액션은 사용자가 원하는 파일에 대해 변수 치환을 적용하는 등의 작업을 할 수 있도록 지원합니다. 예를 들어, YAML 파일에서 특정 값들을 동적으로 설정하거나, 설정 파일에서 환경 변수 값을 적용하는 등의 작업이 가능합니다.
내가 생각한게 맞았다. 이 녀석을 사용해서 아주 쉽게 변수 값을 넣을 수 있었던 것.
민감한 정보를 노출하지 않고 모두 즐겁게 코딩했으면 좋겠습니다~!