실무환경에선 소프트웨어 개발(Development)과 ""운영(Operation)""이 결합되어있다.
쉽게말해, 효율적이고 "지속 가능한" 소프트웨어 제공을 목표로 한다.
(기업이 시장에서 생존하기 위해선,
실적을 높여야하고 더 좋은 서비스를 매일매일... 제공해야되기 때문이다.)
기업 및 실무에서 이를 핵심요소로 손 꼽고 있다.
이에 대한 전체 프로세스를 "Dev Ops"라고 부른다.
Dev Ops는 효율적이고, 시장에서 지속가능한 소프트웨어를 위해
개발 <-> 운영/경영을 하나의 과정으로 묶어두었다.
소프트웨어 개발임무를 맡은 "개발자"는 Dev Ops의 이해를 토대로 전반적인 개발 실무환경을 구축해야한다.
Dev Ops를 전반적으로 반영한 코드 개발 및 배포과정이 우리가 알고 있는
"CI/CD" 이다.
이번 글은 실무환경을 접하지 못했거나,
SI 업체 소속으로 플랫폼 개발 직무로 이직을 준비하는 사람들을 위해
소프트웨어 실무 Dev Ops의 핵심 기술구현 방법론인 CI/CD 자동화 배포 파이프라인 구축하는 방법을
A-Z까지 쉽게 설명한다.
CI/CD가 무엇일까 ?
CI/CD는 소프트웨어 개발 프로세스를 자동화하고 효율화하는 핵심적인 방법론이다.
이 과정은 코드 통합, 테스트, 배포 단계를 지속적이고 자동화된 방식으로 처리하여, 빠르고 안정적으로 소프트웨어를 제공한다.
쉽게 말해, 코드 통합, 테스트, 배포 단계에 대해 "개발자"간 종속성을 최대한 제거하여
소프트웨어 유지 관리에 대해 더 많은 시간과 비용을 쏟을 수 있게 하여 안정적인 소프트웨어를 제공한다.
(이는, 배포 Process가 특정 개발자 A에 의해 종속되어 이뤄지는 것이 아닌,
모든 개발자 (A,B,C,D..)가 배포 작업을 Git Push 만으로도 이뤄지게 만든다.)
따라서, 기능개발 후 즉각 배포하여 실서버 기능반영을 즉시 수행할 수 있고,
운영 (Operation) 팀에서 실서버 유저 사용 트래픽 데이터 분석을 기반으로
"새로운 서비스"를 이어서 계획할 수 있게된다.
시장의 흐름을 즉각적으로 대응할 수 있기에,
CI/CD는 기업 실무에서 필수적인 과정이다.
EC2 자동화 배포 파이프라인 CI/CD 구축
전체 프로세스 개요
- GitHub Actions를 활용하여 AWS EC2에 애플리케이션을 자동 배포하는 CI/CD 파이프라인 구축
- 코드 변경 사항이 자동으로 빌드, 테스트, Docker 이미지 생성 및 배포 과정을 거쳐 EC2에 최종 반영
- CI/CD 구축 간 사용한 인프라 리소스: Github Actions / ECR / S3 / CodeDeploy / Docker / EC2
Github Actions 구성
1. 배포 트리거 설정
>>>> .github/workflows/deploy.yml
on:
pull_request:
branches: [ CI/CD 적용 브랜치 ]
push:
branches: [ CI/CD 적용 브랜치 ]
특정 브랜치에 코드가 Push 또는 Pull Request로 변경될 때 GitHub Actions Workflow가 시작된다.
(CI/CD 작업 간 수행하는 환경에 따라서,
필요한 리소스를 ""on:"" 태그 아래에 추가하면된다)
2. 애플리케이션 빌드
빌드 실행
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
# Gradle 캐싱-> 빌드 속도 UP
- name: Gradle caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: $-gradle-$
restore-keys: |
$-gradle-
# gradlew 의 권한 설정
- name: Grant execute permission for gradlew
run: chmod +x gradlew
# Build Gradle
- name: Build with Gradle
run: ./gradlew clean build -x test --stacktrace
shell: bash
GitHub Actions에서 애플리케이션 빌드 및 의존성 설치
빌드 전, 테스트 단계를 진행한다. (이는 선택 사항)
3. Docker 이미지 생성 및 AWS ECR 전송
AWS Console 로그인 / ECR 로그인 / Docker 빌드
## AWS에 로그인. aws-region은 서울로 설정(ap-northeast-2)
- 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
# ECR 로그인
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
with:
mask-password: 'true'
# Build a docker container and
# push it to ECR so that it can
- name: Build, tag, and push image to Amazon ECR
run: |
docker build -t $app_name:${{steps.current-time.outputs.formattedTime}} .
docker tag $app_name:${{steps.current-time.outputs.formattedTime}} $aws_id.dkr.ecr.$Region.amazonaws.com/$app_name:${{steps.current-time.outputs.formattedTime}}
docker push $ams_id.dkr.ecr.$Region.amazonaws.com/$ecr_repo_name:${{steps.current-time.outputs.formattedTime}}
GitHub Secrets에 저장된 AWS 자격 증명을 사용하여 인증
(이는, 별도로 AWS Root 계정으로 IAM Role에 접속해 Key 값을 가져와서, Github Secrets에 삽입이 필요하다.)
Docker 이미지를 ECR Repository로 태깅(빌드 수행 현재시간) 후 푸시
AWS S3에 배포 스크립트 업로드
EC2에 배포할 AppSpec 파일 생성
배포 간 수행할 스크립트를 배포 Scripts 폴더에 구성 후 .ZIP 파일 하나로 압축 후, S3에 업로드한다.
(appspec.yml 파일은 EC2 인스턴스가 수행할 파일이다.
S3로부터 해당 파일을 받아서 AWS CLI 명령어가 담긴, .sh 파일을 실행한다.)
version: 0.0
os: linux
files:
# ECR에서 이미지를 다운로드하고 실행할 때는 파일 복사가 필요 없습니다.
# 대신 EC2 인스턴스에서 도커 실행 스크립트를 호출하는 작업을 설정합니다.
hooks:
ApplicationStop:
- location: scripts/application_stop.sh
timeout: 60
runas: root
# AfterInstall 단계에서 실행될 스크립트를 지정합니다.
AfterInstall:
- location: scripts/after_install.sh
runas: root # root 권한으로 실행
ApplicationStart:
- location: scripts/application_start.sh
timeout: 60
runas: root
(.sh 파일은 보안상 공개하지 않는다.)
AWS CodeDeploy를 통한 EC2 배포
CodeDeploy 서비스는 Github Actions의 자동화 배포수행 및 배포 이력 및 배포 로그를 통합 관리한다.
1. CodeDeploy 애플리케이션 설정
- CodeDeploy 애플리케이션 및 배포 그룹 생성
- EC2 태그 또는 Auto Scaling 그룹으로 배포 대상 지정
배포 그룹 설정 간 CodeDeploy에서 필요한 IAM Role도 함께 지정해준다.
>> S3 버킷 조회 권한 / EC2 SSM Agent 권한 <<
위와 같은 IAM Role 추가가 필요하니 참고하자.
2. Github Actions 배포 트리거 설정
GitHub Actions에서 AWS CLI를 사용해 CodeDeploy 배포 시작 명령 실행
# CodeDeploy 기반 EC2 배포
- name: Create deployment in CodeDeploy
run: |
aws deploy create-deployment \
--application-name $app_name \
--deployment-group-name $group_name \
--s3-location bucket=$bucket_name,key=$AppSpec.yml,bundleType=zip \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--description "Deploying new version"
CI/CD 파이프라인 배포 테스트
Github Actions에서 배포 트리거 설정 브랜치로 Git Push를 수행한다.
아래와 같이, Github Actions 탭에서 트리거가 동작하여 deploy.yml 파일이 실행되어 배포과정이 수행되고 있다.
(build 초록색 체크표시가 뜨면, 코드빌드 및 트리거가 정상작동되었다는 의미)
AWS Console CodeDeploy 서비스의 배포 그룹에서 "배포" 탭에 들어가
활성화된 배포 ID를 클릭해 조회한다.
(배포 상태 -> 초록색 성공 표시가 뜨면 된다.)
AWS EC2 CLI에서 $docker ps 로,
활성화 중인 도커 이미지 상태를 최종 확인한다.
아래와 같이, 도커 이미지가 활성화가 되어있다면
성공적으로 EC2 배포가 수행된 의미이다.
(필자는 Docker 기반 배포를 수행함. 이를 참고하길 바란다.)
CI/CD 파이프라인 구축은 실무에서 대체로 서버 리딩자가 임무를 맡아서 수행한다.
따라서, 서비스 전반적인 이해도가 높고, 배포 과정을 소속한 서비스 Dev Ops에 따라 효율적으로 구성해야하는 ""높은 책임""이 있다.
필자는 운이 좋게도, 릴리즈 전, 프로젝트 백엔드 팀에서 리딩자리로 백엔드 서버 관리를 맡아서 하고 있다.
아직 많이 부족하고 어설프지만, 이번 경험을 통해
전반적인 Dev Ops의 이해와 이에 대응하는 CI/CD를 스스로 구축해보고 적용해볼 수 있었다.
앞으로 갈 길이 멀지만, 서버 관리 경험을 하나씩 경험하며 본 블로그에 보다 더 많은 사람들이
백엔드 개발에 대한 실무경험을 간접적으로나마 느낄 수 있게 성의껏 글을 작성하겠다.
Jsut Do IT.