본문 바로가기
Study/Devops

[Continuous Deploy] Github actions .env 파일 관리하기 with Github private repository

by 리노 Linho 2022. 10. 14.

목적

Continuous Deploy 과정에서 Dotenv 파일을 꽤 번거로운(?) 녀석이다. 보안상 Github repository에 push하긴 찝찝하다. 그래서 이 파일을 Continuous Deploy 과정에서 리눅스의 Echo & Cat 과 Github Actions Secret Key를 사용해서 만들어줬는데, 가독성과 관리면에서 "이게 맞나?" 싶다. 이를 해결하기 위한 첫번째 방법을 찾아서 기록해본다.

사용 된 아키텍처

글에서 다루는 내용의 아키텍처

Github Public & Private Repository는 빌드될 파일이 있는 레포지토리를 뜻하며 Github Private Repository는 .env 파일이 따로 보관되어 있는 Repository를 뜻한다. 위 두가지를 한개의 계정으로 진행할 수 있지만 본 글에서는 API 통신으로 .env를 가져오기 때문에 각각의 레포지토리를 계정별로 나누어 테스트를 진행하였다. 예를들어 Github Public & Repository 는 Github - linho1150 계정에 생성하였고 Github Private Repository는 Github - luna301150 계정에 생성하였다.

기존에 .env를 관리하던 방식

Creat .evn file step 결과 화면

- name: Create .env file
        run: |
          touch .env
          echo PORT=${{ secrets.PORT }} >> .env
          echo DBHOST=${{ secrets.DBHOST }} >> .env
          echo DBUSERNAME=${{ secrets.DBUSERNAME }} >> .env
          echo DBPASSWORD=${{ secrets.DBPASSWORD }} >> .env
          echo DBDATABASE=${{ secrets.DBDATABASE }} >> .env
          echo DBPORT=${{ secrets.DBPORT }} >> .env
          echo SENTRY_DSN=${{ secrets.SENTRY_DSN }} >> .env
          cat .env

익숙해져 있는 Github Actions workflow의 코드다. env에 들어갈 항목을 하나하나 작성하여 관리한다. 이는 사실상 "하드코딩"으로 간주하고 관리하는 면이나 가독성이 안좋은 구조를 갖고있다.

어떻게하면 될까?

AWS의 S3를 사용하여 .env 데이터를 불러오는 방법이 있다는 얘기를 들었다. 이를 기반으로 Github Actions를 사용하면 Github를 사용한다는 가정하에 진행되는데 AWS까지 연결해야할까? 따라서 Github Private Repository에 .env 파일을 저장하고 이를 불러와보기로 하였다.

.env 파일의 경로와 내용
.env 파일을 RAW 형태로 열었을 때

생성해준 .env 파일을 RAW 형태로 열어보면 [ https://raw.githubusercontent.com/luna301150/config-file/main/.env?token=토큰값 ] 처럼 URL이 형성된다. 따라서, 본 글은 사용자가 토큰을 직접 발급하여 토큰값을 채워주고 해당 링크를 API GET 요청하여 내부 값을 가져오기로 한것이다.

설정 방법

두 개의 계정에서 진행하다보니 레포지토리를 명명하기가 어려워서 다음과 같이 정의한다.

  • Github Actions을 실행시킬 레포지토리 = 원본 레포
  • .env 파일이 있는 레포지토리 = 구성 레포

계정의 Token 값 생성하기

구성 레포를 포함하는 계정의 Settings / Developer settings 에 들어가서 repo를 선택한 후 토큰을 발급 받는다

Token 발급 받는 화면

발급시 repo를 꼭 선택해야하며 Expiration이 지나면 작동하지 않을 수 있음으로 참고하여 정확한 기간을 입력한다. 주기적으로 Token을 바꿔서 관리하는 것도 보안상 장점이 될 수 있을 것 같다. 그럼 구성레포의 Token 발급이 완료되었다.

원본레포의 Github Actions SecretKey에 구성레포의 토큰 등록하기

원본레포의 Settings > Security: Secrets > Actions 로 접근하여 New repository secret 생성하기

Github Actions Secret Key 생성

Name 은 GIT_TOKEN으로 생성하며 Secret에는 구성레포를 포함하는 계정의 Token값을 넣으면 된다.

Github Actions WorkFlow 작성하기

name: TEST github Actions
on:
  push:
    branches:
      - main
jobs:
  env-print:
    name: Print ENV Secret Key
    runs-on: ubuntu-latest
    steps:
      - uses: octokit/request-action@v2.x
        id: download_file
        with:
          route: GET https://raw.githubusercontent.com/luna301150/config-file/main/.env?token=$env.GITHUB_TOKEN
          mediaType: |
            format: raw
        env:
          GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }}
      
      - name: Create .env file
        run: |
          touch .env
          echo "${{ steps.download_file.outputs.data }}" >> .env
          cat .env

해당 workflow는 배포과정이 빠져있으며 배포과정 중간에 해당 step을 추가하면 된다. 수정해야할 상황으로 API GET으로 요청하는 주소의 형식을 [ https://raw.githubusercontent.com/구성레포의 계정명/구성레포명/브랜치명/.env?token=$env.GITHUB_TOKEN ] 로 변경하면 된다. 이후 cat .env 명령어를 통해 실행여부를 확인하면 아래와 같이 정상적으로 작동하는걸 볼 수 있다.

결과하면

주의사항 및 고려해볼점

해당 시스템을 공격한다면 Github actions workflow파일을 의도적으로 변경하여 env 파일의 내부 정보를 탈취할 수 있을 것 같다.

암호화할 방법을 찾아봐야할 것같다.

마무리

Global Config Server 서비스를 만들어서 세상의 모든 env 파일을 관리해볼까 한다 🤔