CI/CD는 어플리케이션의 개발 단계를 자동화하여 앱을 더 빠른 주기로 클라이언트에게 제공하는 방법이다.
어플리케이션의 통합 및 테스트 단계에서부터 제공 및 배포까지의 전체 라이프 사이클에 걸쳐 지속적으로 자동화/모니터링 기능을 제공한다.
이러한 구축 사례를 일반적으로 CI/CD 파이프라인이라 부르며, 개발 및 운영팀의 애자일 방식 협력을 통해 DevOps 또는 SRE 방식으로 지원된다.
CI(Continuous Integration)
CI는 Continuous Integration(지속적 통합)의 약어이다. 지속적 통합이 제대로 구현되면 어플리케이션의 코드 변경 사항이 자동적으로 빌드 및 테스트를 거쳐 공유 레포지토리에 병합된다.
예를 들어 팀원 중 한 명이 회원가입 기능을 구현하는 상황을 가정해보자.
해당 팀원은 문법적인 오류가 있어 build가 안된다거나, build가 잘 되기는 하지만 비즈니스 로직의 문제가 있어 회원가입을 시도해도 DB에 저장이 안되는 소스코드를 미처 확인하지 못한채로 github 공유 레포지토리에 push를 해버렸다.
설상가상으로 이를 다른 팀원들도 눈치채지 못한 채로 main 브랜치로 merge가 된다면 서비스의 치명적인 문제를 일으킬 것이다.
혹은 작업을 했던 브랜치에서는 정상적으로 동작하는데, main 브랜치로 병합이 되었을 때 문제가 생기는 경우도 있다.
하지만 CI가 잘 지켜지는 시스템에서는 github 공유 레포지토리에 push를 하거나 다른 브랜치로 병합을 시도할 때 자동적으로 해당 소스코드의 문법 검사, build 체크, 비즈니스 로직 테스트가 이루어져 실수가 발생했다고 하더라도 즉각적으로 대응할 수 있다.
CD(Continuous Deployment)
CD는 Continuous Delivery(지속적 배포) 혹은 Continuous Deployment(지속적 배포)의 약어이다.
CD는 배포를 자동화시켜주는 단계로, 보통 CI와 연계되어 사용되는 경우가 많다.
예를 들어 github 레포지토리의 main 브랜치에 신규 기능이 추가가 되었고, 이에 대한 충분한 테스트가 이루어져 실제 production 환경으로 배포하고자 한다고 해보자.
그렇다면 배포용 컴퓨터(AWS 등)으로 접속하고, github 레포지토리의 main 브랜치의 작업 내용을 pull 받고, build를 하고, 마지막으로 버그 테스트를 진행하고, 서버를 재가동할 것이다.
이렇게 수동적인 배포 프로세스는 어플리케이션 제공 속도를 저해하고, 불필요한 노동력이 들어갈뿐더러 휴먼 에러가 발생할 여지가 있다.
CI/CD가 잘 지켜지는 시스템에서는 CI 단계에서 새로 적용한 기능에 대한 테스트가 자동적으로 이루어지고, CD 단계에서 실시간 production 환경으로 자동적으로 배포할 수 있다.
Github Actions
이렇게 CI/CD 시스템을 적용하면 개발 단계에서 발생할 수 있는 실수를 예방하여 협업의 능률을 올리고, 배포를 자동화시킬 수 있다. 그렇다면 이런 프로세스를 어떻게 서비스에 적용할 수 있을까?
Github Actions는 github 레포지토리에서 개발 워크플로우를 자동화시켜주는 유용한 기능을 제공한다.
앞서서 언급한 CI/CD를 포함하여 여러 워크플로우를 생성할 수 있다.
yaml 파일을 통해 워크플로우를 작성할 수 있는데, 원하는 기능을 직접 설정할 수도 있고, github 상에서 제공해주는 template을 활용할 수도 있다.
레포지토리의 Actions 탭에서 set up a workflow yourself를 클릭하여 yaml 파일을 생성할 수 있다.
Github Actions 용어 정리
Github Actions를 사용하기 위해서 필수적인 개념을 알아야 한다.
Workflow
•
앞에서도 언급했었던 Workflow는 여러 Job으로 구성되고, 특정 Event에 의해 trigger될 수 있는 자동화된 최상위 프로세스를 의미한다.
•
yaml 파일로 작성되며, Github 레포지토리의 .github/workflows/디렉토리 아래 저장된다.
(set up a workflow yourself를 클릭하여 생성하면 자동으로 commit해준다.)
Event
•
Workflow를 trigger하는 특정 활동 혹은 규칙을 의미한다.
특정 브랜치로 push나 pull Request를 한다거나 특정 시간마다 동작하도록 스케줄링(Cron 등)을 걸어둘 수 있다.
•
작성 예시
on:
push:
branches: [ main, dev ]
pull_request:
branches: [main, dev ]
YAML
복사
main, dev 브랜치로 push가 되거나 PR이 올라오면 Event가 trigger 된다.
Job
•
Workflow는 여러 Job으로 구성되고 Job은 다시 여러 Step으로 구성된다.
•
도커와 같은 가상 환경의 인스턴스에서 주로 실행된다.
•
다른 Job과 의존 관계를 가질 수도 있고, 독립적/병렬적 실행도 가능하다.
•
작성 예시
jobs:
backend-CI:
runs-on: ubuntu-latest
steps:
step-1:
.
.
step-2:
.
.
YAML
복사
Job의 이름을 적고, 그 하위에 runs-on으로 Job이 수행될 환경의 이미지를 적으면 해당 이미지로부터 컨테이너 인스턴스를 생성하고 그 안에서 작업이 이루어진다.
Step
•
name으로 태스크의 이름을 지정할 수 있다.
•
태스크들의 집합으로 인스턴스 환경에서 run으로 명령어를 수행하거나 uses로 action을 수행할 수 있다.
•
작성 예시
steps:
- name: NodeJS 16.x Version
- uses: actions/setup-node@v1
.
.
- name: Install Node Modules for Backend
- run: npm run install --prefix backend
.
.
YAML
복사
uses로 NodeJS를 설치해주는 외부 action을 연결하여 사용한다.
run으로 npm run install명령어를 수행하여 필요한 node modules을 설치한다.
Action
•
Workflow의 최소 단위 블럭
•
Job을 만들기 위해 Steps을 연결할 수 있다.
•
Runner
•
Github Actions Workflow를 실제로 돌리는 프로그램을 의미한다.
•
Runner 하나당 Workflow 하나를 수행할 수 있다.
•
Gihub에서 호스팅하는 Github-hosted Runner와 직접 호스팅하는 Self-hosted Runner 두 가지 종류가 있다. (Github-hosted Runner 방식은 여기에서 비용 정보를 확인하실 수 있습니다. (특정 횟수/용량까지는 무료))
아래는 Github Actions yaml 파일 작성 예시입니다.