CI/CD Tool CircleCI를 이용해서 CircleCI 파이프라인에 ECS를 연결하며 공부한 내용을
정리하고자 합니다.
CICD가 해결하는 문제
기존에 최신 코드를 배포하기위해서
프로덕션에 맞게 환경설정 작성 → 도커 빌드 → ECR Push → ECS Task 개정 생성 → 서비스 업데이트 개정 생성
과정을 거쳐야 했고 Github 통계서버, 블로그 서버, 프론트 서버 모두 이런 과정을 직접 해야하는 문제가 있었습니다
하지만 CICD는 자동화와 모니터링을 통해 지속적인 통합, 지속적인 배포를 할 수 있게 하고
배포 시 마다 개발 코드를 프로덕션 환경에 맞게 코드를 수정, 개선 하기 위해 오랜 시간 작업해야 하는
integration Hell 문제를 해결할 수 있습니다
CICD 키워드 정리
DevOps
Development + Operatorions 개발과 운영의 경계를 허물고
개발 테스트 배포 운영을 통합해 개발 속도를 높이는 것을 목표로 하는 문화이고
DevOps를 구현한 결과가 바로 CI/CD 파이프라인입니다
CI (지속적 통합 : Continuous Integration)
다수의 개발자가 작성하고 수정한 소스 코드가 자동화된 Test( 단위, 통합 테스트 ), Build를 상시로 실시하는 것
CD (지속적 전달 : Continuous Delivery )
코드의 변경사항을 github 또는 컨테이너 레지스트리에 자동으로 업로드되고 이후 프로덕션 환경으로 릴리스 하는것
CD ( 지속적 배포 : Continuous Deployment )
지속적 전달(Continuous Delivery)과 달리 코드의 변경사항을 프로덕션 환경까지 자동으로 릴리스하는 것
CircleCI 선택과 이유
- 무료입니다
- 무료플랜에서 Private 저장소를 사용할 수 있습니다
- Orb를 통해 추가 쉘스크립트 작성 없이 AWS 서비스에 쉽게 연결하고 배포할 수 있습니다
- 알림( 메일, 슬랙, JIRA )을 빠르게 구성할 수 있습니다
이곳에서 다른 다양한 CICD도구의 특징에 대해서 자세히 알아볼 수 있습니다.
CircleCI 키워드
Orb
실행환경, 환경변수, 작업, 명령어가 미리 정의된 공유가능한 오픈소스 패키지 입니다
환경변수는 매개변수화되어 사용할 때 작업의 하위 옵션으로 전달해줄 수 있습니다
Pipeline
파이프라인은 프로젝트의 전체 .circleci/config.yml 파일을 포함하는 작업의 최상위 단위입니다
파이프라인은 .circleci/config.yml 구성파일이 포함된 프로젝트의 변경사항이 푸시될 때 시작됩니다
파이프라인에는 워크플로우가 포함됩니다
Workflow
작업 모음과 실행순서를 정의하기위한 규칙의 집합입니다
Job
작업은 스탭의 모음입니다
step
스탭은 실행가능한 명령어를 정의합니다
프로젝트 CICD Pipeline 구성
버전관리 : Github
CI/CD : CircleCI
빌드 이미지 저장소: AWS ECR
컨테이너 오케스트레이션 : AWS ECS
컨테이너 인스턴스: AWS EC2
Dockerfile
프로젝트 앱의 도커파일을 작성합니다
도커파일에는 프로젝트의 구성환경, 빌드 명령어가 명시되어 있습니다
# 베이스 이미지를 지정합니다
FROM node:16
# MAINTAINER argon1025@gmail.com
# 각명령어의 디렉토리 위치는 매번 초기화되기 때문에
# 기본 디렉토리를 생성하고 해당 디렉토리로 위치를 고정 합니다
WORKDIR /usr/src/app
# 프로젝트를 복사합니다
COPY ./ ./
# 모듈을 설치합니다
RUN npm install
# 프로젝트를 빌드합니다
RUN npm run build
# 포트를 오픈합니다
EXPOSE 80
# 앱을 시작합니다
CMD [ "node", "dist/main.js"]
CircleCI config.yml
CircleCI config.yml 파일에는 푸시가 되었을때 실행되는 파이프라인에대한 설정을 포함하고 있습니다
version: 2.1
# 오브를 추가합니다
# 오브엔 실행환경, 환경변수 작업, 명령이 미리 구성되어 있습니다
orbs:
aws-ecr: circleci/aws-ecr@7.3.0
aws-ecs: circleci/aws-ecs@2.2.1
# 워크플로우에서 사용할 작업을 정의합니다
# <https://circleci.com/docs/2.0/configuration-reference/#jobs>
jobs:
# nestJS 빌드를 진행하는 작업입니다
BuildTest:
docker:
- image: cimg/node:lts-browsers
steps:
# 프로젝트 폴더를 복사합니다
- checkout
# 명령어를 실행합니다
- run:
name: 'install npm module'
command: |
cd src
npm i
- run:
name: 'build project'
command: |
cd src
npm run build
# CircleCI 컨텍스트를 활용해 .ENV 파일을 프로젝트 폴더에 생성해주는 작업입니다
createEnv:
machine: true
steps:
- checkout
- run:
name: 'Create .env file'
command: |
./.circleci/scripts/generate-env-files.sh
ls -al
cat .env
- persist_to_workspace:
root: .
paths:
- .
# 워크플로우를 정의합니다
workflows:
# 빌드 테스트
# 작업 조건 : TIL 로 시작하는 브랜치
Test-build:
jobs:
- BuildTest:
filters:
branches:
only: /^TIL-.*/
# 이미지 푸시
ECR-push-ECS-deploy:
jobs:
# CircleCI 컨텍스트를 활용해 .ENV 파일을 프로젝트 폴더에 생성해주는 작업
# 작업 조건 : release 브랜치 커밋
- createEnv:
context:
- TILOG_STATS_BACKEND_PROD
filters:
branches:
only:
- release
# Dockerfile을 빌드하고 ECR에 푸시하는 작업
# 작업 조건 : 상위 createEnv 작업 종료, release 브랜치 커밋
- aws-ecr/build-and-push-image:
# 이전 작업영역을 이어받습니다
attach-workspace: true
checkout: false
# AWS 액세스 키
aws-access-key-id: AWS_ACCESS_KEY_ID
# AWS 시크릿 액세스 키
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
# ECR 저장소 링크
account-url: AWS_ECR_ACCOUNT_URL
# ECR 저장소가 존재하지 않으면 생성합니다
create-repo: true
# dockerfile 명
dockerfile: Dockerfile
# 서비스 리전
region: AWS_DEFAULT_REGION
# 레포지토리 명
repo: '${AWS_ECR_NAME}'
# 이미지 태그
tag: '$CIRCLE_SHA1'
# 선행되어야하는 작업
requires:
- createEnv
# 특정 브랜치에 푸시된 커밋만 진행합니다
filters:
branches:
only:
- release
# ECR에 푸시된 컨테이너 이미지를 사용해 ECS 태스크 서비스를 업데이트 하는 작업
# 작업 조건 : 상위 aws-ecr/build-and-push-image 작업 종료, release 브랜치 커밋
- aws-ecs/deploy-service-update:
# 컨테이너:태그 container:tag
container-image-name-updates: 'container=${AWS_ECR_NAME},tag=${CIRCLE_SHA1}'
# ECS 클러스터 이름
cluster-name: '${AWS_ECR_NAME}-ECS-Cluster'
# 업데이트할 서비스명
service-name: '${AWS_ECR_NAME}-service'
# 개정할 작업 정의 명
family: '${AWS_ECR_NAME}'
# 선행되어야하는 작업
requires:
- aws-ecr/build-and-push-image
# 특정 브랜치에 푸시된 커밋만 진행합니다
filters:
branches:
only:
- release
적용 결과
깃허브 PR 결과확인
테스트 빌드가 실패, 성공했을경우
배포가 성공하면
ECS에서 새로운 태스크가 개정되고 서비스가 업데이트됩니다
Else
CircleCI에서 Slack으로 메시지 전송하기
Orb를 사용하면 Slack에 쉽게 사용자정의 메시지를 전송할 수 있습니다