[Tistory] Git Action을 활용한 CI/CD

원글 페이지 : 바로가기

1. 개요 이번에는 CI/CD를 해당 프로젝트에 적용시켜 보기로 했다. 구구모에 적용되어 있으나 다른 팀원 분이 해주셔서 직접 익혀보고자 이 프로젝트에 적용하게 되었다. 2. 아키텍처 CI/CD에서 주로 사용하는 배포 절차는 다음과 같다. 각 요소가 어떤 역할을 하는 지 간단히 살펴보자 Github Action: 깃허브에서 빌드, 배포 파이프라인을 자동화할 수 있는 CI/CD 플랫폼 AWS S3(Amazon Simple Storage Service): 업계 최고의 확장성, 데이터 가용성, 보안 및 성능을 제공하는 객체 스토리지 서비스 AWS CodeDeploy: CodeDeploy Amazon EC2 인스턴스, 온프레미스 인스턴스, 서버리스 Lambda 함수 또는 Amazon ECS 서비스로의 애플리케이션 배포를 자동화하는 배포 서비스 AWS EC2: AWS에서 제공하는 클라우드 컴퓨팅 서비스 이제 위 아키텍쳐들을 하나씩 만들어보자. https://velog.io/@juhyeon1114/%EC%8B%A4%EC%A0%84-Github-actions-AWS-Code-deploy%EB%A1%9C-Spring-boot-%EB%B0%B0%ED%8F%AC-%EC%9E%90%EB%8F%99%ED%99%94%ED%95%98%EA%B8%B0#-appspecyml-%EC%9E%91%EC%84%B1 실전! Github actions, AWS Code deploy로 Spring boot 배포 자동화하기 아휴 힘드러 🤮 velog.io 해당 글을 참고하여 구성했으므로 간단히만 설명하고자 한다. 3. IAM 계정 생성 CI/CD를 AWS를 통해 하기 위해 IAM 계정을 생성하여 구축에 필요한 권한을 부여한다. 다음의 두 권한을 받아 계정을 만들어준다. 그 다음 이를 클릭하고 보안 자격증명->액세스 키->액세스 키 만들기를 눌러 키를 발급받는다. 발급이 완료되면 csv 파일로 이를 다운받을 수 있다. 이 두 key를 프로젝트 리포지토리의 settings->Secrets and Variables->actions->New repository secrets를 눌러 저장해준다. 이후 해당 계정에 다음 두 정책을 가진 역할을 생성해준다. 4. EC2 생성 ubuntu 22.04 LTS 버전으로 인스턴스 하나를 생성해주었다. 포트는 다음과 같이 설정해주었다. 다음 글을 참고하여 인스턴스에 code deploy agent를 설치해준다. https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/codedeploy-agent-operations-install-ubuntu.html Ubuntu CodeDeploy 서버용 에이전트 설치 – AWS CodeDeploy 출력을 임시 로그 파일에 쓰는 것은 Ubuntu Server 20.04에서 install 스크립트를 사용하여 알려진 버그를 해결하는 동안 사용해야 하는 해결 방법입니다. docs.aws.amazon.com 다음 명령어로 자바 17버전을 설치한다. sudo apt update
sudo apt install openjdk-17-jdk IAM 계정을 만들 때 생성한 AmazonS3FullAccess 정책이 담긴 역할을 연결해준다. 5. S3 버킷 생성 빌드된 애플리케이션을 저장할 버킷을 만들어주었다. 6. Code Deploy 애플리케이션 생성 code deploy 애플리케이션을 생성해주었다. 그리고 그 내부에 있는 배포 그룹을 만들어준다. 7. 워크플로우 작성 아래 파일들은 리포지토리 최상단에서의 올바른 경로에 작성해주어야 한다. ./.github/workflows/ci_test.yml name: CICD Test
run-name: Running
on:
push:
branches:
– main

env:
AWS_REGION: ap-northeast-2
AWS_S3_BUCKET: adreamleaf-cicd-test-bucket
AWS_CODE_DEPLOY_APPLICATION: adreamleaf-cicd-test
AWS_CODE_DEPLOY_GROUP: adreamleaf-cicd-test-group
working-directory: ./Backend/aDreamLeaf

jobs:
build-with-gradle:
runs-on: ubuntu-latest
steps:
– name: Checkout master branch
uses: actions/checkout@v3
with:
token: ${{secrets.ADREAMLEAF_PROPERTIES}}
submodules: true
ref: main

– name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: ’17’
distribution: ‘corretto’

– name: gradlew 실행 권한 부여
run: chmod +x ./gradlew
working-directory: ${{ env.working-directory }}

– name: 프로젝트 빌드(테스트 코드 제외)
run: |
./gradlew copyGitSubmodule
./gradlew clean build –exclude-task test
working-directory: ${{ env.working-directory }}

– name: AWS credential 설정
uses: aws-actions/configure-aws-credentials@v1
with:
aws-region: ${{ env.AWS_REGION }}
aws-access-key-id: ${{ secrets.CICD_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.CICD_SECRET_KEY }}

– name: S3에 업로드
run: aws deploy push –application-name ${{ env.AWS_CODE_DEPLOY_APPLICATION }} –ignore-hidden-files –s3-location s3://$AWS_S3_BUCKET/cicdtest/$GITHUB_SHA.zip –source .

– name: EC2에 배포
run: aws deploy create-deployment –application-name ${{ env.AWS_CODE_DEPLOY_APPLICATION }} –deployment-config-name CodeDeployDefault.AllAtOnce –deployment-group-name ${{ env.AWS_CODE_DEPLOY_GROUP }} –s3-location bucket=$AWS_S3_BUCKET,key=cicdtest/$GITHUB_SHA.zip,bundleType=zip env:
working-directory: ./Backend/aDreamLeaf

– name: gradlew 실행 권한 부여
run: chmod +x ./gradlew
working-directory: ${{ env.working-directory }}

– name: 프로젝트 빌드(테스트 코드 제외)
run: |
./gradlew copyGitSubmodule
./gradlew clean build –exclude-task test
working-directory: ${{ env.working-directory }} 이 프로젝트에서는 클라이언트와 서버 코드를 한 리포지토리에서 관리하였다. 따라서 CI의 과정을 working-directory를 추가하여 처리하였다. 각 job은 진행될 때 마다 새로 실행되므로 working-directory를 모두 적어주어야 한다. 또, 서버를 시작할 때, 종료할 때의 스크립트를 각각 작성해주었다. ./scripts/start.sh #!/bin/bash

ROOT_PATH=”/home/ubuntu/spring-github-action”
JAR=”$ROOT_PATH/application.jar”

APP_LOG=”$ROOT_PATH/application.log”
ERROR_LOG=”$ROOT_PATH/error.log”
START_LOG=”$ROOT_PATH/start.log”

NOW=$(date +%c)

echo “[$NOW] $JAR 복사” >> $START_LOG
cp $ROOT_PATH/Backend/aDreamLeaf/build/libs/DreamLeaf-0.0.1-SNAPSHOT.jar $JAR

echo “[$NOW] > $JAR 실행” >> $START_LOG
nohup java -jar $JAR > $APP_LOG 2> $ERROR_LOG &

SERVICE_PID=$(pgrep -f $JAR)
echo “[$NOW] > 서비스 PID: $SERVICE_PID” >> $START_LOG bootjar 수행 이후 경로에 plain 파일이 같이 있어 jar파일의 파일명을 명시해주었다. ./scripts/stop.sh #!/bin/bash

ROOT_PATH=”/home/ubuntu/spring-github-action”
JAR=”$ROOT_PATH/application.jar”
STOP_LOG=”$ROOT_PATH/stop.log”
SERVICE_PID=$(pgrep -f $JAR) # 실행중인 Spring 서버의 PID

NOW=$(date +%c)

if [ -z “$SERVICE_PID” ]; then
echo “[$NOW] > 서비스 NouFound” >> $STOP_LOG
else
echo “[$NOW] > 서비스 종료 ” >> $STOP_LOG
kill “$SERVICE_PID”
# kill -9 $SERVICE_PID # 강제 종료를 하고 싶다면 이 명령어 사용
fi 또, 루트 경로에 code deploy가 수행할 일들인 appspec.yml을 작성해준다. version: 0.0
os: linux

files:
– source: /
destination: /home/ubuntu/spring-github-action
overwrite: yes

permissions:
– object: /
owner: ubuntu
group: ubuntu

hooks:
AfterInstall:
– location: scripts/stop.sh
timeout: 60
ApplicationStart:
– location: scripts/start.sh
timeout: 60 7. 테스트 서버가 정상적으로 실행된 것을 확인할 수 있었다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다