자동 배포, CI/CD란?

HGY·2024년 2월 23일

이번 주제는 CI/CD의 적용이다.
2월부터 시작한 팀 프로젝트에서는 CI/CD를 적용한 상태로 개발을 진행하기로 했고,
본격적인 프로젝트 시작 전에 개념을 잡고 들어가고자 이 글을 작성한다.

CI

CI (Continuous Integration)는 한글로 해석하면 지속적 통합이다.
여러사람이 함께 개발하는 과정에서 소스 코드를 통합할때는 많은 충돌이 일어날 수 있다.
이 부분을 위한 안전장치로 CI는 변경사항을 자동으로 빌드하고, 테스트를 수행하여 코드 통합 과정의 충돌을 방지하고, 모니터링 할 수 있게된다.

위 사진에서 개발(Code) -> 빌드(Bulid) -> 테스트(Test) 이 세 단계를 CI 로 볼 수 있다.

CD

CD (continuous delivery, continuous deployment)는 두가지 뜻을 가지고 있다.
지속적 배포, 지속적 제공으로 해석할 수 있는데, 뜻이야 어쨌든 목적은 CI를 통해 안정된 코드를 자동으로 서버에 배포하는 작업이다.
배포 과정을 수작업으로 하게되면 코드가 변경될 때마다 pull받고, 다시 빌드하고, 실행하고...
똑같은 작업을 매번 반복 하게 된다. 이 부분을 자동화 하는것이 CD이다.

CI/CD 툴

Jenkins

가장 유명한 CI/CD 툴.
일단 가장 큰 장점은 무료이고, 파이프라인을 사용해서 거의 모든 환경 및 통합을 지원한다는 점이 있다.
실무에서도 많이 사용하는 편이고, 플러그인 추가를 통해 맞춤형 파이프라인을 구성할 수 있다.
하지만 초기 설정과 관리가 복잡한 편이고, 별도 서버가 필요하며, 호스팅을 전부 일일이 설정해줘야 하기 때문에 비용이 드는 편이다.

GitHub Actions

경량화된 CI/CD를 제공하는 툴.
GitHub와 통합하여 관리할 수 있고, GitHub 레파지토리와 함께 사용하여 비교적 간단하게 CI/CD를 구축할 수 있다. 또한 클라우드로 관리되기 때문에 별도의 서버가 필요없다
단점으로는 규모가 큰 파이프라인을 구축하게 될 경우 제한사항이 생길 수 있다.

이 외에도 CircleCI, Travis CI, GitLab... 등이 있는데, 대부분 비슷하며 Jenkins에 비해 설정은 간단하나 확장성이 제한적이라는 공통점이 있다.

GitHub Actions 동작방식

Workflow

GitHub Actions의 최상위 개념은 Workflow다.
Workflow는 여러개의 Job으로 구성되고, Event에 의해 동작되는 자동화된 프로세스를 의미한다.
Workflow는 yaml로 작성되어 레파지토리의 .gitbub/workflows 폴더에 저장된다.

Event

특정 동작이 발생했을 때 Workflow를 실행하게 하는 규칙이다.
예를들어 특정 브랜치에 Push 됐을때 실행하게 할 수 있다.

Job

Workflow에서 처리할 작업의 단위를 의미한다.
Job은 하나 이상의 Step으로 이루어지며 모든 작업은 동시에 실행되지만 필요 시에는 Job간에 의존 관계를 설정해서 순서를 제어할 수 있다.

Step

Job내에서 정확히 어떤 명령을 실행할 지를 결정하는 단위다.
run속성을 통해 커맨드나 스크립트를 실행하고,
Action을 사용할 때는 uses속성을 통해 실행할 수 있다.

Action

플러그인과 비슷한 개념으로, 공개 코드 저장소에 공유된 Action을 GitHub 상의 모든 코드 저장소에서 사용할 수 있다.
대표적으로 레파지토리에서 코드를 내려받고, 실행하는 일련의 과정을 actions/checkout을 통해 압축할 수 있다.

예제 코드

name: Github Actions Example

on:
  push:
    branches: [ develop ]

jobs:
  Github Actions Job:
    runs-on: ubuntu-18.04
    timeout-minutes: 10

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2

      - name: Create ENV File
        run: |
          touch .env
          echo "${{ secrets.DEV_ENV }}" >> .env

	  - name: Setup Node
	    uses: actions/setup-node@v3
        with:
          node-version: '16'

      - name: Build
        run: |
          npm i
          CI= npm run build

      - name: Compress
        run: tar -zcvf test.tar.gz build

      - name: Upload to S3
        run: |
          aws s3 mv --region ap-northeast-2 \
          test.tar.gz \
          ${{ secrets.S3_DEV_FRONT_LOCATION }}/test.tar.gz

      - name: Deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          port: ${{ secrets.PORT }}
          key: ${{ secrets.KEY }}
          script: |
            ./deploy_front.sh

위 코드는 GitHub Actions에서 사용하는 yaml 파일의 예시다.

  • 먼저 Workflow의 이름을 선언하고
name: Github Actions Example
  • develop 브랜치에 push 이벤트가 발생하면
on:
  push:
    branches: [ develop ]
  • Github Actions Job라는 이름의 Job을 Ubuntu 18.04 환경에서 최대 10분 동안 실행하고
jobs:
  Github Actions Job:
    runs-on: ubuntu-18.04
    timeout-minutes: 10
  • 아래의 step을 쭉 진행하게 된다
  1. Github 최신 코드 pull
- name: Checkout
	uses: actions/checkout@v2
  1. AWS 접속을 위한 인증
- name: Configure AWS Credentials
	uses: aws-actions/configure-aws-credentials@v1
	with:
		aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
		aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
		aws-region: ap-northeast-2
  1. React 빌드에 필요한 .env 파일 작성
- name: Create ENV File
	run: |
		touch .env
		echo "${{ secrets.DEV_ENV }}" >> .env
  1. Node 환경 구성 버전은 16버전
- name: Setup Node
	uses: actions/setup-node@v3
	with:
		node-version: '16'
  1. React 빌드
- name: Build
	run: |
		npm i
		CI= npm run build

- name: Compress
	run: tar -zcvf test.tar.gz build
  1. 압축한 빌드물 S3에 업로드
- name: Build
	run: |
		npm i
		CI= npm run build

- name: Compress
	run: tar -zcvf test.tar.gz build
  1. AWS ssh 접속 후 배포 진행
- name: Deploy
	uses: appleboy/ssh-action@master
	with:
		host: ${{ secrets.HOST }}
		username: ${{ secrets.USERNAME }}
		port: ${{ secrets.PORT }}
		key: ${{ secrets.KEY }}
		script: |
			./deploy_front.sh

위 흐름을 쭉 보다보면 수많은 secrets 값들을 확인할 수 있다.
api키와 같은 민감한 값들은 코드상에서 env 파일을 통해 관리하듯 GitHub의 secret 탭을 통해 관리할 수 있다.

profile
바보 개발자 지망생

0개의 댓글