효율적인 애플리케이션 개발과 운영을 위해 자동화된 CI/CD 파이프라인 구축은 필수적이다. 이를 통해 코드 변경 사항이 신속하고 안전하게 배포될 수 있으며, 개발자는 더 빠르게 기능을 릴리즈하고 버그를 수정할 수 있다. 이번 글에서는 ParmNav 프로젝트에 CI/CD 파이프라인을 구축하는 과정과 이를 통해 얻을 수 있는 이점을 소개하고자 한다.
AWS CodeDeploy 에이전트 설치
AWS 가이드라인에 따라 필요한 패키지를 설치하고 CodeDeploy 에이전트를 설치한다. 다음 명령어를 실행하여 에이전트를 설치하고 로그 파일을 생성한다.
sudo apt install ruby-full
sudo apt install wget
wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto > /tmp/logfileCopy
설치 후에는 다음 명령어로 에이전트의 실행 상태를 확인한다.
systemctl status codedeploy-agent
IAM 설정 사용
이전에 생성한 IAM 설정을 사용한다. 자세한 설정은 이전 포스트를 참고한다.
https://eunchaan.tistory.com/170
약국 인스턴스에 IAM 롤을 연결해서 인스턴스가 AWS 리소스에 접근할 수 있게 해 준다.
S3 버킷 생성
프로젝트의 빌드 파일을 저장할 S3 버킷을 생성한다. 이 버킷은 프로젝트의 빌드 파일을 EC2 인스턴스로 전송하는 데 사용된다.
CodeDeploy 설정
CodeDeploy 애플리케이션을 생성하고, EC2 인스턴스를 배포 그룹에 추가한다. 배포 그룹 설정은 애플리케이션을 EC2 인스턴스에 배포할 때 사용된다.
GitHub Secrets 설정
프로젝트 리포지토리의 GitHub Actions에서 사용할 AWS 자격증명을 설정한다.
배포 스크립트 설정
EC2 인스턴스에 배포를 위한 스크립트를 작성하고 실행 권한을 부여한다. 이 스크립트는 현재 실행 중인 애플리케이션의 프로세스 ID를 확인하여, 실행 중인 애플리케이션이 있을 경우 이를 종료시키고, 없을 경우 종료하지 않고 넘어간다. 이후 빌드 파일을 복사하고 Docker Compose를 재시작하여 새 애플리케이션을 배포한다.
scripts/deploy.sh
#!/bin/bash
REPOSITORY=/home/ec2-user/Pharmacy-Recommendation
PROJECT_NAME=Pharmacy-Recommendation
echo "> 현재 구동 중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -f ${PROJECT_NAME}.*.jar)
if [ -z "$CURRENT_PID" ]; then
echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
echo "> kill -15 $CURRENT_PID"
kill -15 $CURRENT_PID
sleep 5
fi
echo "> 새 어플리케이션 배포"
echo "> Build 파일 복사"
cp $REPOSITORY/*.jar $REPOSITORY/
JAR_NAME=$(ls -tr $REPOSITORY/ | grep jar | tail -n 1)
echo "> JAR Name: $JAR_NAME"
echo "> Docker Compose 재시작"
cd $REPOSITORY
docker-compose down
docker-compose up -d
echo "> 새 어플리케이션 배포 완료"
- 현재 실행 중인 애플리케이션의 프로세스 ID 확인
- 실행 중인 애플리케이션이 있다면 종료
- 빌드 파일을 복사하여 새 애플리케이션으로 준비
- Docker Compose를 사용하여 컨테이너를 재시작하고 새 애플리케이션을 배포
인스턴스 서버에서 아래 명령어로 실행 권한을 부여한다.
chmod +x deploy.sh
appspec.yml 생성
AWS CodeDeploy에 사용될 appspec.yml 파일을 설정한다. 이 파일은 배포 과정에서 필요한 파일 위치, 실행 권한, 환경 변수 설정 등을 정의한다.
version: 0.0
os: linux
files:
- source: /
destination: /home/ec2-user/Pharmacy-Recommendation
overwrite: yes
file_exists_behavior: OVERWRITE
hooks:
ApplicationStart:
- location: scripts/deploy.sh
timeout: 600
runas: ec2-user
environment:
variables:
PATH: /usr/local/bin:/usr/bin:/bin
- 소스 경로, 대상 경로 및 파일 덮어쓰기 옵션을 설정한다.
- 배포 후 실행될 스크립트와 해당 스크립트의 타임아웃, 실행 사용자를 지정한다.
.github/workflows/deploy.yaml에 스크립트를 작성
deploy.yaml 파일은 GitHub Actions를 사용하여 자동화된 CI/CD 파이프라인을 구축하는 데 사용된다. 이 파일은 push 이벤트를 기반으로 코드가 푸시될 때마다 빌드 및 배포 과정을 자동으로 실행한다.
name: CI-CD
on:
push:
branches:
- main
env:
PROJECT_NAME: Pharmacy-Recommendation
S3_BUCKET_NAME: s3-eunchan
CODE_DEPLOY_APPLICATION_NAME: CODE-DEPLOY
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: CODE-DEPLOY-GROUP
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Cache Gradle packages
uses: actions/cache@v3
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
restore-keys: ${{ runner.os }}-gradle
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- name: Build with Gradle
run: ./gradlew clean build -x test
- name: Grant execute permission for deploy.sh
run: chmod +x ./scripts/deploy.sh
- name: Make zip file
run: |
zip -r ./$GITHUB_SHA.zip . -x "*.git*"
echo "Zip file contents:"
unzip -l ./$GITHUB_SHA.zip
shell: bash
- 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: ${{ secrets.AWS_REGION }}
- name: Upload to S3
run: aws s3 cp --region ${{ secrets.AWS_REGION }} ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
- name: Code Deploy
run: |
aws deploy create-deployment \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
--s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip
- on: push: main 브랜치로 푸시가 발생할 때만 파이프라인이 작동하도록 설정한다.
- env: 프로젝트 이름, S3 버킷 이름, AWS CodeDeploy 애플리케이션 및 배포 그룹과 같은 중요한 환경 변수를 설정한다.
- jobs: build: 빌드 및 배포 작업을 정의한다. 이 작업은 GitHub Actions에서 최신 Ubuntu 환경을 사용하여 실행된다.
- Checkout: 코드를 체크아웃하여 GitHub Actions 환경으로 가져온다.
- Set up JDK 17: 프로젝트에 필요한 Java 17 버전을 설정한다.
- Cache Gradle packages: 빌드 시간을 줄이기 위해 Gradle 패키지를 캐시한다.
- Grant execute permission for gradlew: Gradle 실행 파일의 권한을 설정한다.
- Build with Gradle: 테스트를 제외하고 프로젝트를 빌드한다.
- Grant execute permission for deploy.sh: 배포 스크립트 파일에 실행 권한을 부여한다.
- Make zip file: 프로젝트를 zip 파일로 압축하여 S3로 업로드할 준비를 한다.
- Configure AWS credentials: AWS 자격 증명을 설정하여 S3와 CodeDeploy에 접근할 수 있도록 한다.
- Upload to S3: 생성된 zip 파일을 AWS S3에 업로드한다.
- Code Deploy: AWS CodeDeploy를 통해 업로드된 파일을 배포한다.
Actions에서 빌드 확인
GitHub Actions에서 빌드가 성공적으로 완료되었는지 확인한다.
AWS CodeDeploy 배포 확인
AWS의 CodeDeploy에서 배포가 성공적으로 이루어졌는지 확인한다.
서버 접속 후 Docker 실행 확인
서버에 접속하여 Docker가 정상적으로 실행 중인지 확인한다.
이렇게 CI/CD 파이프라인 구축을 완료했다. 이제 코드 수정 후 푸시하면 자동으로 서버에 배포되며, 이를 통해 더 효율적이고 안정적인 배포 프로세스를 유지할 수 있다.
'BackEnd > Project' 카테고리의 다른 글
[PharmNav]Base62 vs Base64 비교 분석 (1) | 2024.09.24 |
---|---|
[PharmNav] Redis vs DB 조회 성능 비교 분석 (0) | 2024.09.24 |
[PharmNav] Kafka vs Redis 성능 비교 분석 (1) | 2024.09.24 |
[PharmNav] kafka를 통한 성능 향상 (0) | 2024.09.20 |
[BigData] Ch12. Kafka추가 활용 사례 (2) | 2024.09.19 |