Github) Github actions에서 Secrets로 환경변수 관리하기

2ast·2022년 11월 15일
21

github actions와 환경변수 이슈

github actions란

github actions는 github에서 제공하는 기능으로, 특정 트리거가 발동되었을 때 미리 설정한 워크플로를 실행시키는 자동화 툴이다. github actions를 활용하면 main 브랜치에 코드가 푸시되었을 때 자동으로 코드를 테스트하고, 문제가 없다면 배포까지 진행하는 등 프로세스 자동화가 가능해진다.

환경변수 관리 문제

다만 github actions를 사용할 때 한가지 걸림돌이 있는데, 바로 환경변수 문제다. api키나, 각종 password 등의 민감한 데이터들은 보안을 이유로 github에 직접 업로드하지 않는 것이 일반적이다. 때문에 이런 데이터들은 .env와 같이 환경변수 파일을 만들고, 이 환경변수 파일을 .gitignore에 등록하여 github에 올라가지 못하도록 막게 된다.

github actions는 워크플로를 가상의 머신위에서 테스트하고 빌드하기 때문에(물론 선택에 따라 본인의 컴퓨터를 사용할 수도 있지만...) 환경변수가 없는 상태에서는 제대로된 테스트와 빌드가 이루어질 수 없다. 하지만 그렇다고 .env파일을 그대로 github에 업로드하기에는 굳이 .env파일을 분리한 목적 자체가 불문명해진다. 이런 문제를 해결하기 위해 github은 secrets라는 기능을 제공하고 있다.

Secrets

secrets는 말 그대로 비밀이라는 뜻을 갖고 있다. 즉, api키나 password와 같이 우리가 남들에게 숨기고 싶어하는 데이터를 관리해주는 역할을 한다. 사용 방법은 간단하다. github에서 secrets에 원하는 값을 입력하면, actions의 workflow가 실행될 때 이 secrets에 접근이 가능해진다. 그러면 이때 동적으로 secrets의 데이터를 취합해 .env파일을 새로 생성하면 되는 것이다.

사용방법

  1. secrets를 등록하고 싶은 github repo에 접속한 뒤에, "Settings>Security>Secrets>Actions" 탭에 접근해 나오는 페이지에서 우측 상단 "New repository secret"을 누른다.

  2. Name에는 변수명을, Secret에는 값을 입력하고 "add secret"을 누른다. 예를들어 map api key를 저장하고 싶다면 Name에 MAP_API_KEY와 같이 유니크한 이름을 입력하고 Secret에 jansdkjn-1uy1bnjanjkh-128u3hj와 같이 그 값을 입력해주면 된다.

  3. 이제 이렇게 저장된 값은 workflow에서 ${{secrets.VARIABLE_NAME}} 형태로 접근이 가능하다. 이제 secrets를 이용해서 .env파일을 생성해야하는데, 여기에 사용되는 명령어가 바로 'echo'다. echo는 단순히 터미널에 문자를 표현해주는 js의 console.log와 동일한 역할을 하지만 '>' 또는 '>>'와 같이 화살표와 함께 사용하게 되면 새로운 파일을 만들어 줄 수도 있다.

jobs:
  release-ios:
    name: Build and release iOS app
    runs-on: macos-latest
    steps:
      - name: access to secrets
        run: |
          echo "MAP_API_KEY=$MAP_API_KEY" >> .env
        env:
          MAP_API_KEY: ${{secrets.MAP_API_KEY}}
          

위와 같이 코드를 작성하면 MAP_API_KEY 환경변수가 저장된 .env파일이 생성된다.

여기서 주의할 점은 '>'와 '>>'를 구분하는 것이다. '>'는 기존에 동일한 이름의 파일이 없다면 생성하고, 동일한 파일이 있다면 새로운 파일로 덮어쓰기 한다. 하지만, '>>'를 사용하면 기존에 파일이 없다면 생성하고, 동일한 파일이 있다면 파일 내부에 새로운 내용을 추가하는 방식으로 동작한다. 따라서 여러줄의 환경변수를 입력하는 경우 '>>'를 사용해 주어야 한다.

keystore 또는 json 파일을 저장하는 방법

우리가 github에 직접 업로드하지 못하는 파일이 .env뿐만은 아니다. credentails 정보를 담고 있는 json이나 android에서 서명에 사용되는 keystore파일도 보안상의 이유로 gitignore파일에 추가해놓곤 한다. 이런 형태의 파일들은 .env파일처럼 변수단위로 secrets에 등록하기 애매한데, 이럴 때 사용하는 것이 base64 암호화 방식이다. 파일의 내용을 base64로 인코딩하여 일련의 문자열로 치환하고, 이를 secrets에 저장한 뒤에, 워크플로에서 다시 decode하여 사용하는 것이다.

encode

base64로 인코딩하는 방법에는 여러가지가 있는데, 대표적으로 openssl을 사용하는 방법과 '|' 연산자를 사용하는 방법이 있다.

//openssl 사용
openssl base64 -in <input file path> -out <output file path>

// '|' 사용
cat <input file path> | base64

여기서 cat 명령어는 파일의 내용을 출력해주는 기능을 한다. 이때 "| base64"를 붙이면, 출력의 내용을 base64로 인코딩해서 보여주겠다는 의미가 된다.

두 가지 방법 모두 base64로 인코딩하는데에는 문제가 없지만, openssl 방식으로 인코딩한 내용을 ubuntu 환경에서 "|"을 사용해 decode할 때 invalid input 에러가 발생하는 경험을 했다. 그 이유에 대해서는 아직 명확히 알 수는 없지만 openssl 방식의 encoding과 '|' 방식의 decoding의 호환성 문제라고 막연히 추측하고 있다. 따라서 이왕이면 후자의 방식으로 인코딩하는 것을 추천한다. (ubuntu환경에서 openssl을 사용하려면 따로 설치해야하므로 가상머신에서 굳이 추가 작업을 더하고 싶지 않았다.)

decode

decode도 간편한데, 그냥 출력문 뒤에 "| base64 --decode"만 붙여주면 된다. 이를 echo를 이용해 파일을 만드는 문법에 적용하면 다음과 같다.

jobs:
  release-ios:
    name: Build and release iOS app
    runs-on: macos-latest
    steps:
      - name: access to secrets
        run: |
          echo $CREDENTIALS >> credentials.json
        env:
          CREDENTIALS: ${{secrets.CREDENTIALS}}
          

이렇듯 base64를 이용하면 json, keystore, properties 등등 어떠한 형태의 파일이라도 secrets에 저장하고 이용할 수 있다.

profile
React-Native 개발블로그

4개의 댓글

comment-user-thumbnail
2023년 7월 13일

좋은 글 감사합니다~

1개의 답글
comment-user-thumbnail
2023년 8월 27일

궁금한 부분이 있습니다 ㅠㅠㅠ
현재 application.yml 파일에 민감한 정보들이 있는데 github 에 말씀해주신 secrets를 사용하여 업로드 하려고 합니다.
다만 업로드는 블로그글을 자세히 써주셔서 따라하면 되긴 하는데 그럼 로컬 application.yml 에는 어떤식으로 사용할 수 있는건가요....?

1개의 답글