CI/CD는 빌드부터 배포까지의 과정을 자동화하하고 모니터링하는 방법입니다. CI/CD 없이도 배포에는 전혀 지장이 없기 때문에 CI/CD의 필요성에 대해 의문을 갖는 사람도 적지 않습니다.
물론, 작은 규모의 프로젝트에 CI/CD를 도입하면, 오히려 작업량이 더 많아지고 귀찮아지는 것이 사실입니다. 실제로 CI/CD를 도입하는 작업은 에러가 발생할 수 있는 부분이 많고, 프로젝트마다 설정해야 할 부분도 조금씩 달라서 따라하기조차 어려울 수 있습니다. 그래서 저 또한 CI/CD를 도입하는 과정에서 수 많은 시행 착오를 겪어야 했습니다.
그러나 코드 수정, 로컬 테스트, jar 파일 생성 등의 과정이 복잡한 대규모 프로젝트의 경우, CI/CD 도입이 필수적이기 때문에 CI/CD를 몰라서는 안 됩니다. CI/CD 도입 과정이 쉽지는 않지만, 배워놓으면 분명히 도움이 될 것입니다. 그러면 이제부터 본격적으로, CI/CD의 개념에 대해 학습해보고 실습도 진행해봅시다.
CI는 Continuos Integration(지속적 통합)의 줄임말로, 빌드와 테스트를 자동화하는 과정을 의미한다. CI는 변경 사항을 자동으로 테스트해 애플리케이션에 문제가 없음을 보장해준다. 또한, 코드를 정기적으로 빌드하고, 테스트하기 때문에 여러 명의 개발자가 동시에 작업하더라도 충돌을 방지할 수 있다. CI는 변경사항이 Repository에 업로드되는 시점에 실행된다.
CD는 CI가 끝난 다음 실행되는 작업으로, 배포 준비가 된 코드를 자동으로 서버에 배포한다. CD는 Continuos Delivery(지속적 제공) 또는 Continuos Deployment(지속적 배포)의 두 가지 의미를 갖는다. 이 두 가지 의미를 해석하면 아래와 같다.
① Continuos Delivery
② Continuos Deployment
본격적인 CI/CD 도입에 앞서 CI를 위한 사전 준비를 먼저 진행한다. 이 과정은 말 그대로 CI 연습을 위한 과정으로써, CI/CD 경험이 있다면 건너 뛰어도 된다.
깃허브 액션은 깃허브에서 제공하는 서비스로, Repository에 이벤트 트리거를 지정하거나, 주기적으로 특정 작업을 반복하기 위해 사용한다. 즉, 깃허브 액션을 사용하면 깃허브에 코드를 업로드하는 것만으로 코드를 빌드 > 테스트 > 배포할 수 있다.
깃허브 액션 스크립트를 작성하기 전에 본인의 Github Repository에 코드가 업로드되어 있어야 한다. 깃허브에 코드를 업로드하는 방법은 아래의 링크를 참조하기 바란다.
>> 깃허브에 파일 업로드하기
① IntelliJ 파일을 열고 root 디렉토리 > .github 디렉토리 하위로 workflows 디렉토리를 생성한다.
② workflows 디렉토리 하위로 ci.yml 파일을 추가하고, 아래의 코드를 입력한다.
# 워크 플로의 이름
name: CI
# 워크 플로의 시작 조건: 어떤 브랜치에서든 push 이벤트가 발생하면 실행
on:
push:
branches:
- '*'
jobs:
build:
runs-on: ubuntu-latest # 실행 환경
# 작업의 실행 단계를 정의
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew clean build
③ CI가 잘 동작하는지 확인해보기 위해 commit과 push를 진행해보면, 아래와 같은 에러가 발생할 것이다.
refs/heads/HelloThere-122:refs/heads/HelloThere-122 [remote rejected] (refusing to allow a Personal Access Token to create or update workflow `.github/workflows/ci.yml` without `workflow` scope)
④ 이 에러는 사용자 인증을 위해 사용하는 깃허브 Access Token에 workflow 수정 권한이 없어서 발생한다. 그러므로 Access Token에 workflow 수정 권한을 부여해주어야 한다.
⑤ 다시 push를 진행한 후, Respository의 Actions 탭에 가보면 새로운 workflow가 생성되어있다.
application.yml, ServiceAccountKey.json, Secret 클래스 파일이 Repository에 없어 build에 실패하는 것을 확인하였다. 그래서 이번에는 깃허브 Secrets를 이용해 해당 파일들을 업로드한 후, build 해보기로 하자.
원활한 CI 실습 진행을 위해 Secret 클래스 파일은 일단 git ignore를 해제하여 Repository에 추가하기로 하고, application.yml, ServiceAccountKey.json 파일을 깃허브 Secrets에 저장해보자.
만약 Secret 클래스 파일을 공개하고 싶지 않다면, yml 파일에 정보를 입력한 뒤, @Value injection으로 값을 입력 받으면 된다. @Value injection을 사용하는 방법은 아래의 링크에서 확인하기 바란다.
>> @Value injection
① application.yml 파일을 secrets에 바로 등록할 수는 없고, 먼저 Base64 encoding을 진행해야 한다. 아래의 링크에 접속하여 yml 파일을 Base64로 encoding하자.
>> Base64 Encoder
② 인코딩 결과를 복사한다. 참고로 Base64 인코딩은 보안을 위한 Encoding이 아니므로, 외부에 유출되지 않도록 주의한다.
③ 깃허브에 들어가 Repository > Settings > Secrets and Variables > Actions에 들어가 New repository secret 버튼을 클릭한다.
④ Name(key)에는 APPLICATION_YML을 입력하고, Secret(value)에는 Base64 encoding 결과를 입력한다.
⑤ secrets에 등록이 완료되었다.
application.yml 파일 이외에 다른 비밀 파일도 존재하다면, 마찬가지 방법으로 secrets에 등록하면 된다.
① ServiceAccountKey.json 파일을 Base64로 Encoding 한다.
② Base64 Encoding 결과를 깃허브 Secrets에 추가한다.
③ secrets에 등록이 완료되었다.
IAM Access Key와 Secret Key도 깃허브 Secrets에 등록해주어야 한다. 대신, Access Key와 Secret Key는 별도의 Base64 Encoding 없이 곧바로 입력한다.
마지막으로 깃허브 Access Token을 깃허브 Secrets에 등록한다. 마찬가지로 별도의 Encoding 없이 바로 입력하면 된다.