기존의 젠킨스 구성

최종 프로젝트를 진행하면서 CI/CD 도구로 Jenkins를 사용하였다. 위의 사진과 같이 깃허브 특정 브랜치에 push 이벤트가 발생하면 webhook이 전달되어 젠킨스에서 파이프라인이 돌아가는 구성이었다.
CI 과정이 끝나면 도커 이미지를 만들어서 도커 허브로 푸시하고 k8s 마스터 노드에 새로운 deployment.yml 파일 배포하였다.
GitHub Actions와 AWS CodeDeploy로 CI/CD를 구성한 이유
젠킨스를 계속 사용해도 좋지만 이번 최종 프로젝트가 끝난 뒤 나 혼자서 서비스를 배포할 때는 GitHub Actions와 AWS CodeDeploy를 사용하기로 했다.
깃허브 액션을 선택한 이유로는 CI/CD 구성이 젠킨스 보다 편리하고, 내가 사용할 수 있는 자원을 고려했을 때 로컬에서 사용하는 젠킨스 보다 클라우드로 제공되는 깃허브 액션이 더 효율적이라고 판단하였다.
깃허브 액션 구성

백엔드와 프론트엔드의 CI/CD가 어떻게 동작하는지 살펴보자.
Backend
- 개발자가 깃허브 repo에 backend 브랜치로 PR을 진행한다.
- 깃허브에서는 개발자가 미리 작성한 GitHub Actions를 통해 CI를 진행한다.
- CI가 정상적으로 완료되면 스프링 프로젝트를 .jar 파일로 만들고 appspec.yml 파일과 빌드 스크립트를 zip 파일로 압축하여 AWS S3 저장소로 업로드를 진행한다.
- 그다음 AWS CodeDeploy에게 AWS S3에 있는 jar 파일로 배포를 진행하라고 전달한다.
- AWS CodeDeploy는 .jar 파일을 배포할 EC2 인스턴스 내부에 있는 CodeDeploy Agent에게 배포 명령을 내리고 해당 jar 파일을 S3에서 받아서 빌드 스크립트에 따라 배포를 진행한다.
Frontend
- 개발자가 깃허브 repo에 frontend 브랜치로 PR을 진행한다.
- 깃허브에서는 개발자가 미리 작성한 GitHub Actions를 통해 CI를 진행한다.
- CI가 정상적으로 완료되면 vue 프로젝트를 dist 파일로 만들고 zip 파일로 압축하여 AWS S3 저장소로 업로드를 진행한다.
백엔드 구성하기
name: Backend CI/CD
on:
pull_request:
branches: [ "backend" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
cache: maven
- name: Project Clean
run: |
cd ./backend
pwd
mvn clean
- name: Project Compile
run: |
cd ./backend
mvn compile
- name: Project Test
run: |
cd ./backend
mvn test
- name: Project build
run: |
cd ./backend
mvn package
먼저 backend 브랜치로 PR이 생성되면 CI가 되는 과정이다.
하니씩 살펴보자.
- 우분투로 빌드를 진행
- 자바 11 버전으로 설치를 진행
- 스프링 프로젝트 클린 진행
- 스프링 프로젝트 컴파일 진행
- 스프링 프로젝트 테스트 진행
- 스프링 프로젝트 패키지 진행
그다음으로는 AWS EC2 서버로 CD가 되는 과정이다.
- name: Make Zip File
run: |
mkdir ssm-cicd
ls -al
cp ./backend/target/*.jar ./ssm-cicd
cp ./appspec.yml ./ssm-cicd
cp ./scripts/backend-deploy-start.sh ./ssm-cicd
zip -r ./$GITHUB_SHA.zip ./ssm-cicd
- name: Configuration AWS
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://${{ secrets.AWS_S3_BUCKET_NAME }}/backend/$GITHUB_SHA.zip
- name: Deploy to EC2
run: aws deploy create-deployment
--application-name ${{ secrets.AWS_CD_APPLICATION_NAME }}
--deployment-config-name CodeDeployDefault.AllAtOnce
--deployment-group-name ${{ secrets.AWS_CD_GROUP_NAME }}
--s3-location bucket=${{ secrets.AWS_S3_BUCKET_NAME }},bundleType=zip,key=backend/$GITHUB_SHA.zip
- name: Test Report
uses: EnricoMi/publish-unit-test-result-action@v1
if: always()
with:
files: ./backend/target/surefire-reports/*.xml
- jar 파일, appspec, 배포 스크립트들을 zip 파일로 압축 진행
- AWS 인증
- AWS S3로 업로드
- AWS CD로 배포 명령을 전달
- 테스트 결과를 확인
프론트엔드 구성하기
다음으로는 프론트엔드 프로젝트를 깃허브 액션으로 CI/CD 하는 과정이다.
name: Frontend CI/CD
on:
pull_request:
branches: [ "frontend" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: ./frontend/package-lock.json
- name: Install Dependencies
run: |
cd ./frontend
npm i --force
- name: Project Test
run: |
cd ./frontend
npm run test
- name: Project Build
run: |
cd ./frontend
npm run build
frontend 브랜치로 PR을 생성하면 CI/CD가 이뤄진다.
먼저 CI 과정을 살펴보자.
- 우분투로 CI/CD를 진행
- 프로젝트에 맞는 node 버전 설정
- npm install을 진행
- npm run test로 jest 단위 테스트 진행
- build 명령어를 통해 프론트엔드 프로젝트를 dist 파일로 빌드
다음으로는 CD 과정을 살펴보자.
- name: Configuration AWS
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: |
cd ./frontend
aws s3 sync ./dist/ s3://${{ secrets.AWS_S3_BUCKET_NAME }}/frontend --region ${{ secrets.AWS_REGION }}
- name: Test Report
uses: EnricoMi/publish-unit-test-result-action@v1
if: always()
with:
files: ./frontend/test-results/*.xml
- AWS 인증
- AWS S3에 dist 파일을 업로드
- 테스트 결과를 확인
appspec.yml
CI/CD 구성이 완료되면 이제 appspec.yml 파일을 작성해야 한다.
appspec은 AWS EC2에 배포하기 위해 AWS CodeDeploy가 실행하는 파일로 특정 Event Hook을 사용자가 직접 작성하여 Event들을 실행시킬 수 있다.
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu
file_exist_behavior: OVERWRITE
permissions:
- object: /
pattern: "**"
owner: root
group: root
hooks:
ApplicationStart:
- location: backend-deploy-start.sh
timeout: 300
runas: root
내가 작성한 appspec 파일을 통해 구조를 하나씩 살펴보자.
Files 섹션
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu
file_exist_behavior: OVERWRITE
먼저 files 섹션을 살펴보면 source 명령을 통해 EC2로 복사할 파일 혹은 디렉터리를 지정해 준다.
현재 appspec에서는 '/'로 설정하여 모든 파일을 EC2 인스턴스로 복사되게 설정하였다.
그다음으로 destination을 통해 EC2 인스턴스에서 어떤 위치로 복사할 것인지 지정하였다. 내가 사용하는 EC2 인스턴스는 ubuntu 운영체제를 사용하고 있어서 /home/ubuntu로 경로를 지정하였다.
마지막으로 file_exist_behavior를 OVERWRITE로 설정하여 기존의 백엔드 배포 파일이 있다면 덮어쓸 수 있게 구성하였다.
Permissions 섹션
permissions:
- object: /
pattern: "**"
owner: root
group: root
다음으로는 권한 섹션에 대해서 살펴보자.
appspec 파일을 작성할 때 permissions에 해당하는 부분은 EC2/온프레미스로 배포할 때만 필요한 과정으로 추후 AWS Lambda를 배포할 경우 resource 섹션을 참고해서 설정해야 한다.
먼저 필수 입력 값인 object 명령어는 파일이 EC2 인스턴스에 복사된 후 사용자가 지정한 권한이 적용되는 파일 혹은 디렉터리를 지정해 준다. 현재 내가 작성한 appspec의 object 명령어로 '/' 경로를 지정하였다.
그다음 pattern을 통해서 권한을 적용할 패턴을 지정해 준다. 여기서 "**"를 사용하면 권한이 type에 따라 일치하는 모든 파일 또는 디렉터리에 적용된다.
마지막으로 owner와 group은 object의 소유자 이름과 그룹 이름으로 백엔드 파일이 배포될 경우 해당 위치의 소유자와 그룹 이름인 root로 지정하였다.
hooks 섹션
hooks:
ApplicationStart:
- location: backend-deploy-start.sh
timeout: 300
runas: root
appspec의 마지막 섹션으로는 hooks이 있다.
hooks에는 여러 가지 배포 생명 주기 이벤트가 있는데 그중에서 ApplicationStart만 사용하였다.
hooks 섹션에 대해서 하나씩 살펴보자.
먼저 배포 생명 주기 이벤트 이름을 필수로 지정해줘야 한다. 내가 작성한 appspec에서는 ApplicationStart로 지정하였다.
그다음으로는 location 명령을 통해 실행할 스크립트의 위치를 지정해주는데 이때 Application root를 기준으로 한다.
그 다음으로 timeout을 설정하여 스크립트가 실패로 간주되기 전에 실행할 수 있는 시간을 정해주는데 해당 시간을 초과하게 되면 이벤트는 실패 처리가 된다. (기본값은 1시간)
마지막으로 runas는 EC2 인스턴스에서 실행 중인 CodeDeploy 에이전트를 의미한다. 배포할 EC2 인스턴스에 CodeDeploy 설정을 따로 변경하지 않았다면 기본 설정으로 root가 되기 때문에 runas를 root로 지정하였다.
지금까지 appspec.yml 파일에 관해서 알아봤는데 아직은 CI/CD 테스트를 진행하는 중이어서 따로 hooks 이벤트를 추가하지 않았다.
추후 테스트가 완료되면 AWS 공식 문서를 보면서 다른 이벤트들을 추가할 예정이다.
AppSpec '후크' 섹션 - AWS CodeDeploy
배포의 시작 DownloadBundle, 설치 BlockTrafficAllowTraffic, 및 종료 이벤트는 스크립팅할 수 없으므로 이 다이어그램에서 회색으로 표시됩니다. 하지만 파일의 '파일' 섹션을 편집하여 설치 이벤트 중에
docs.aws.amazon.com
배포 스크립트
Build_JAR=$(ls /home/ubuntu/*.jar)
JAR_NAME=$(basename $Build_JAR)
DEPLOY_PATH=/home/ubuntu/
echo "> build 파일명: $JAR_NAME" >> /home/ubuntu/deploy.log
echo "> 현재 실행중인 애플리케이션 pid 확인" >> /home/ubuntu/deploy.log
CURRENT_PID=$(pgrep -f $JAR_NAME)
if [ -z $CURRENT_PID ]; then
echo "> 현재 실행중인 애플리케이션이 없으므로 종료하지 않습니다." >> /home/ubuntu/deploy.log
else
echo "> kill -9 $CURRENT_PID" >> /home/ubuntu/deploy.log
kill -9 $CURRENT_PID
sleep 5
fi
DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> $DEPLOY_JAR 배포" >> /home/ubuntu/deploy.log
nohup java -jar $DEPLOY_JAR >> /home/ubuntu/deploy.log 2>/home/ubuntu/error.log &
위에서 살펴본 appspec.yml 파일을 보면 ApplicationStart 이벤트에서 쉘 스크립트를 확인할 수 있다. 어떤 내용들이 있는지 하나씩 살펴보자.
먼저 백엔드 프로젝트인 .jar 파일을 Build_JAR 변수에 저장한 다음 JAR_NAME으로 설정해 준다.
echo 명령어를 통해서 현재 build 할 jar 파일 이름을 deploy.log 파일에 추가해 준다.
그다음으로 pgrep을 통해 설정한 .jar 파일의 PID를 CURRENT_PID로 설정해 주고 if문으로 해당 프로세스가 실행 중인지 확인한다.
만약 실행 중인 프로세스가 있다면 kill -9를 통해서 종료시켜 주고 없다면 그냥 넘어가게 된다.
마지막으로 실행할 jar 파일의 위치를 DEPLOY_JAR로 설정해 주고 nohup을 통해 백그라운드로 jar 파일을 실행시킨다. 해당 실행 과정에서 발생하는 로그는 deploy.log 파일에 추가해 주고 에러가 발생한다면 error.log 파일에 추가해 준다.
'프로젝트' 카테고리의 다른 글
[SSM_프로젝트] - Spring Cloud Gateway 적용하기 (0) | 2024.06.12 |
---|---|
[SSM_프로젝트] - 프로필 이미지 성능 개선하기 (0) | 2024.06.12 |
[SSM_프로젝트] 다시 처음으로... (0) | 2024.06.03 |
[SSM_프로젝트] - GitHub Actions와 AWS Code Deploy를 활용한 CI/CD 적용 - (2) (0) | 2024.06.01 |
한화 시스템 부트캠프 수료 및 향후 계획 (0) | 2024.05.10 |
기존의 젠킨스 구성

최종 프로젝트를 진행하면서 CI/CD 도구로 Jenkins를 사용하였다. 위의 사진과 같이 깃허브 특정 브랜치에 push 이벤트가 발생하면 webhook이 전달되어 젠킨스에서 파이프라인이 돌아가는 구성이었다.
CI 과정이 끝나면 도커 이미지를 만들어서 도커 허브로 푸시하고 k8s 마스터 노드에 새로운 deployment.yml 파일 배포하였다.
GitHub Actions와 AWS CodeDeploy로 CI/CD를 구성한 이유
젠킨스를 계속 사용해도 좋지만 이번 최종 프로젝트가 끝난 뒤 나 혼자서 서비스를 배포할 때는 GitHub Actions와 AWS CodeDeploy를 사용하기로 했다.
깃허브 액션을 선택한 이유로는 CI/CD 구성이 젠킨스 보다 편리하고, 내가 사용할 수 있는 자원을 고려했을 때 로컬에서 사용하는 젠킨스 보다 클라우드로 제공되는 깃허브 액션이 더 효율적이라고 판단하였다.
깃허브 액션 구성

백엔드와 프론트엔드의 CI/CD가 어떻게 동작하는지 살펴보자.
Backend
- 개발자가 깃허브 repo에 backend 브랜치로 PR을 진행한다.
- 깃허브에서는 개발자가 미리 작성한 GitHub Actions를 통해 CI를 진행한다.
- CI가 정상적으로 완료되면 스프링 프로젝트를 .jar 파일로 만들고 appspec.yml 파일과 빌드 스크립트를 zip 파일로 압축하여 AWS S3 저장소로 업로드를 진행한다.
- 그다음 AWS CodeDeploy에게 AWS S3에 있는 jar 파일로 배포를 진행하라고 전달한다.
- AWS CodeDeploy는 .jar 파일을 배포할 EC2 인스턴스 내부에 있는 CodeDeploy Agent에게 배포 명령을 내리고 해당 jar 파일을 S3에서 받아서 빌드 스크립트에 따라 배포를 진행한다.
Frontend
- 개발자가 깃허브 repo에 frontend 브랜치로 PR을 진행한다.
- 깃허브에서는 개발자가 미리 작성한 GitHub Actions를 통해 CI를 진행한다.
- CI가 정상적으로 완료되면 vue 프로젝트를 dist 파일로 만들고 zip 파일로 압축하여 AWS S3 저장소로 업로드를 진행한다.
백엔드 구성하기
name: Backend CI/CD
on:
pull_request:
branches: [ "backend" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
cache: maven
- name: Project Clean
run: |
cd ./backend
pwd
mvn clean
- name: Project Compile
run: |
cd ./backend
mvn compile
- name: Project Test
run: |
cd ./backend
mvn test
- name: Project build
run: |
cd ./backend
mvn package
먼저 backend 브랜치로 PR이 생성되면 CI가 되는 과정이다.
하니씩 살펴보자.
- 우분투로 빌드를 진행
- 자바 11 버전으로 설치를 진행
- 스프링 프로젝트 클린 진행
- 스프링 프로젝트 컴파일 진행
- 스프링 프로젝트 테스트 진행
- 스프링 프로젝트 패키지 진행
그다음으로는 AWS EC2 서버로 CD가 되는 과정이다.
- name: Make Zip File
run: |
mkdir ssm-cicd
ls -al
cp ./backend/target/*.jar ./ssm-cicd
cp ./appspec.yml ./ssm-cicd
cp ./scripts/backend-deploy-start.sh ./ssm-cicd
zip -r ./$GITHUB_SHA.zip ./ssm-cicd
- name: Configuration AWS
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://${{ secrets.AWS_S3_BUCKET_NAME }}/backend/$GITHUB_SHA.zip
- name: Deploy to EC2
run: aws deploy create-deployment
--application-name ${{ secrets.AWS_CD_APPLICATION_NAME }}
--deployment-config-name CodeDeployDefault.AllAtOnce
--deployment-group-name ${{ secrets.AWS_CD_GROUP_NAME }}
--s3-location bucket=${{ secrets.AWS_S3_BUCKET_NAME }},bundleType=zip,key=backend/$GITHUB_SHA.zip
- name: Test Report
uses: EnricoMi/publish-unit-test-result-action@v1
if: always()
with:
files: ./backend/target/surefire-reports/*.xml
- jar 파일, appspec, 배포 스크립트들을 zip 파일로 압축 진행
- AWS 인증
- AWS S3로 업로드
- AWS CD로 배포 명령을 전달
- 테스트 결과를 확인
프론트엔드 구성하기
다음으로는 프론트엔드 프로젝트를 깃허브 액션으로 CI/CD 하는 과정이다.
name: Frontend CI/CD
on:
pull_request:
branches: [ "frontend" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: ./frontend/package-lock.json
- name: Install Dependencies
run: |
cd ./frontend
npm i --force
- name: Project Test
run: |
cd ./frontend
npm run test
- name: Project Build
run: |
cd ./frontend
npm run build
frontend 브랜치로 PR을 생성하면 CI/CD가 이뤄진다.
먼저 CI 과정을 살펴보자.
- 우분투로 CI/CD를 진행
- 프로젝트에 맞는 node 버전 설정
- npm install을 진행
- npm run test로 jest 단위 테스트 진행
- build 명령어를 통해 프론트엔드 프로젝트를 dist 파일로 빌드
다음으로는 CD 과정을 살펴보자.
- name: Configuration AWS
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: |
cd ./frontend
aws s3 sync ./dist/ s3://${{ secrets.AWS_S3_BUCKET_NAME }}/frontend --region ${{ secrets.AWS_REGION }}
- name: Test Report
uses: EnricoMi/publish-unit-test-result-action@v1
if: always()
with:
files: ./frontend/test-results/*.xml
- AWS 인증
- AWS S3에 dist 파일을 업로드
- 테스트 결과를 확인
appspec.yml
CI/CD 구성이 완료되면 이제 appspec.yml 파일을 작성해야 한다.
appspec은 AWS EC2에 배포하기 위해 AWS CodeDeploy가 실행하는 파일로 특정 Event Hook을 사용자가 직접 작성하여 Event들을 실행시킬 수 있다.
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu
file_exist_behavior: OVERWRITE
permissions:
- object: /
pattern: "**"
owner: root
group: root
hooks:
ApplicationStart:
- location: backend-deploy-start.sh
timeout: 300
runas: root
내가 작성한 appspec 파일을 통해 구조를 하나씩 살펴보자.
Files 섹션
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu
file_exist_behavior: OVERWRITE
먼저 files 섹션을 살펴보면 source 명령을 통해 EC2로 복사할 파일 혹은 디렉터리를 지정해 준다.
현재 appspec에서는 '/'로 설정하여 모든 파일을 EC2 인스턴스로 복사되게 설정하였다.
그다음으로 destination을 통해 EC2 인스턴스에서 어떤 위치로 복사할 것인지 지정하였다. 내가 사용하는 EC2 인스턴스는 ubuntu 운영체제를 사용하고 있어서 /home/ubuntu로 경로를 지정하였다.
마지막으로 file_exist_behavior를 OVERWRITE로 설정하여 기존의 백엔드 배포 파일이 있다면 덮어쓸 수 있게 구성하였다.
Permissions 섹션
permissions:
- object: /
pattern: "**"
owner: root
group: root
다음으로는 권한 섹션에 대해서 살펴보자.
appspec 파일을 작성할 때 permissions에 해당하는 부분은 EC2/온프레미스로 배포할 때만 필요한 과정으로 추후 AWS Lambda를 배포할 경우 resource 섹션을 참고해서 설정해야 한다.
먼저 필수 입력 값인 object 명령어는 파일이 EC2 인스턴스에 복사된 후 사용자가 지정한 권한이 적용되는 파일 혹은 디렉터리를 지정해 준다. 현재 내가 작성한 appspec의 object 명령어로 '/' 경로를 지정하였다.
그다음 pattern을 통해서 권한을 적용할 패턴을 지정해 준다. 여기서 "**"를 사용하면 권한이 type에 따라 일치하는 모든 파일 또는 디렉터리에 적용된다.
마지막으로 owner와 group은 object의 소유자 이름과 그룹 이름으로 백엔드 파일이 배포될 경우 해당 위치의 소유자와 그룹 이름인 root로 지정하였다.
hooks 섹션
hooks:
ApplicationStart:
- location: backend-deploy-start.sh
timeout: 300
runas: root
appspec의 마지막 섹션으로는 hooks이 있다.
hooks에는 여러 가지 배포 생명 주기 이벤트가 있는데 그중에서 ApplicationStart만 사용하였다.
hooks 섹션에 대해서 하나씩 살펴보자.
먼저 배포 생명 주기 이벤트 이름을 필수로 지정해줘야 한다. 내가 작성한 appspec에서는 ApplicationStart로 지정하였다.
그다음으로는 location 명령을 통해 실행할 스크립트의 위치를 지정해주는데 이때 Application root를 기준으로 한다.
그 다음으로 timeout을 설정하여 스크립트가 실패로 간주되기 전에 실행할 수 있는 시간을 정해주는데 해당 시간을 초과하게 되면 이벤트는 실패 처리가 된다. (기본값은 1시간)
마지막으로 runas는 EC2 인스턴스에서 실행 중인 CodeDeploy 에이전트를 의미한다. 배포할 EC2 인스턴스에 CodeDeploy 설정을 따로 변경하지 않았다면 기본 설정으로 root가 되기 때문에 runas를 root로 지정하였다.
지금까지 appspec.yml 파일에 관해서 알아봤는데 아직은 CI/CD 테스트를 진행하는 중이어서 따로 hooks 이벤트를 추가하지 않았다.
추후 테스트가 완료되면 AWS 공식 문서를 보면서 다른 이벤트들을 추가할 예정이다.
AppSpec '후크' 섹션 - AWS CodeDeploy
배포의 시작 DownloadBundle, 설치 BlockTrafficAllowTraffic, 및 종료 이벤트는 스크립팅할 수 없으므로 이 다이어그램에서 회색으로 표시됩니다. 하지만 파일의 '파일' 섹션을 편집하여 설치 이벤트 중에
docs.aws.amazon.com
배포 스크립트
Build_JAR=$(ls /home/ubuntu/*.jar)
JAR_NAME=$(basename $Build_JAR)
DEPLOY_PATH=/home/ubuntu/
echo "> build 파일명: $JAR_NAME" >> /home/ubuntu/deploy.log
echo "> 현재 실행중인 애플리케이션 pid 확인" >> /home/ubuntu/deploy.log
CURRENT_PID=$(pgrep -f $JAR_NAME)
if [ -z $CURRENT_PID ]; then
echo "> 현재 실행중인 애플리케이션이 없으므로 종료하지 않습니다." >> /home/ubuntu/deploy.log
else
echo "> kill -9 $CURRENT_PID" >> /home/ubuntu/deploy.log
kill -9 $CURRENT_PID
sleep 5
fi
DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> $DEPLOY_JAR 배포" >> /home/ubuntu/deploy.log
nohup java -jar $DEPLOY_JAR >> /home/ubuntu/deploy.log 2>/home/ubuntu/error.log &
위에서 살펴본 appspec.yml 파일을 보면 ApplicationStart 이벤트에서 쉘 스크립트를 확인할 수 있다. 어떤 내용들이 있는지 하나씩 살펴보자.
먼저 백엔드 프로젝트인 .jar 파일을 Build_JAR 변수에 저장한 다음 JAR_NAME으로 설정해 준다.
echo 명령어를 통해서 현재 build 할 jar 파일 이름을 deploy.log 파일에 추가해 준다.
그다음으로 pgrep을 통해 설정한 .jar 파일의 PID를 CURRENT_PID로 설정해 주고 if문으로 해당 프로세스가 실행 중인지 확인한다.
만약 실행 중인 프로세스가 있다면 kill -9를 통해서 종료시켜 주고 없다면 그냥 넘어가게 된다.
마지막으로 실행할 jar 파일의 위치를 DEPLOY_JAR로 설정해 주고 nohup을 통해 백그라운드로 jar 파일을 실행시킨다. 해당 실행 과정에서 발생하는 로그는 deploy.log 파일에 추가해 주고 에러가 발생한다면 error.log 파일에 추가해 준다.
'프로젝트' 카테고리의 다른 글
[SSM_프로젝트] - Spring Cloud Gateway 적용하기 (0) | 2024.06.12 |
---|---|
[SSM_프로젝트] - 프로필 이미지 성능 개선하기 (0) | 2024.06.12 |
[SSM_프로젝트] 다시 처음으로... (0) | 2024.06.03 |
[SSM_프로젝트] - GitHub Actions와 AWS Code Deploy를 활용한 CI/CD 적용 - (2) (0) | 2024.06.01 |
한화 시스템 부트캠프 수료 및 향후 계획 (0) | 2024.05.10 |