개발진행목록/학습 커뮤니티 서비스
[학습 커뮤니티] AWS로 CI/CD 구축하기(2) - GitHub Actions 설정
o3oppp
2025. 6. 26. 22:18
1. GitHub Secrets 값 설정
- AWS에 접근하기 위해 IAM에서 사용자 액세스 키를 발급받은 후 GitHub Secrets에 설정해주어야 한다.
- 액세스 키 발급은 사용중인 IAM 계정을 클릭하여 액세스 키 만들기를 진행하면 된다.
- Github -> Setting -> Security -> Secrets and Variables -> Actions -> New repository secret
- 발급받은 ACCESS KEY와 SECRET KEY를 등록한다.
2. GitHub Workflow 생성
# deploy.yml
name: Yakchat Server CI/CD
on:
push:
branches: [ "dev-temp" ] # 해당 브랜치에 push 되면 스크립트 실행
#pull_request:
# branches: [ "dev-temp" ] # 해당 브랜치에 pull request 되면 스크립트 실행
env:
# 버킷에 저장할 폴더 이름
PROJECT_NAME: ap-northeast-2
# S3 버킷 이름
BUCKET_NAME: pillchat-deploy-bucket
# CodeDeploy의 애플리케이션 이름
CODE_DEPLOY_APP_NAME: pillchat-dev-server-CD
# CodeDeploy의 배포그룹 이름
DEPLOYMENT_GROUP_NAME: pillchat-dev-server-deployment-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: 'corretto'
# Gradle 파일 실행권한 설정
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
shell: bash
# Gradle build (Test 제외)
- name: Build with Gradle
run: ./gradlew clean build -x test
# 압축 파일 만들기 (S3에서는 jar가 저장되지 않기 때문에 zip으로 생성)
- name: Make Zip File
run: zip -r ./$GITHUB_SHA.zip .
shell: bash
# AWS 인증
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_CICD_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_CICD_SECRET_KEY }}
aws-region: ap-northeast-2
# S3 버킷으로 파일을 업로드
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
# S3 버킷에 업로드 된 파일을 대상으로 CodeDeploy에서 배포 요청
- name: Code Deploy
run: aws deploy create-deployment --application-name $CODE_DEPLOY_APP_NAME --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name $DEPLOYMENT_GROUP_NAME --s3-location bucket=$BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip
- Actions -> new workflow -> set up a workflow yourself를 선택하여 deploy.yml을 생성한다.
3. AppSpec 파일 작성
# AppSpec.yml
version: 0.0 # 반드시 0.0이어야 함
os: linux
# 배포 파일 설정
files:
- source: / # 인스턴스에 복사할 디렉터리 경로
destination: /home/ubuntu/Yakchat_Server_CICD # 인스턴스에서 파일이 복사되는 위치
overwrite: yes #복사할 위치에 파일이 있는 경우 대체
# files 섹션에서 복사한 파일에 대한 권한 설정
permissions:
- object: / # 권한이 지정되는 파일 또는 디렉터리
pattern: "**" # 매칭되는 패턴에만 권한 부여(optional)
# owner: ec2-user # object 의 소유자(optional)
# group: ec2-user # object 의 그룹 이름(optional)
# 배포 이후에 실행할 일련의 라이프사이클
hooks:
ApplicationStart: # 종료 및 새로운 애플리케이션을 실행
- location: scripts/deploy.sh # hooks 에서 실행할 스크립트 위치
timeout: 300 # 스크립트 실행에 허용되는 최대 시간이며, 넘으면 배포 실패로 간주됨(optional)
# runas: ec2-user # 스크립트를 실행하는 사용자(optional)
- 배포를 할 때 CodeDeploy에서 사용할 AppSpec 파일을 작성한다.
- AppSpec 파일은 yml 형식이며 배포 프로세스에서 각 인스턴스에 실행할 스크립트를 지정하는 역할을 가진다.
- AppSpec 파일은 반드시 소스코드의 루트 디렉토리에 위치해야 한다.
4. 배포 쉘 스크립트 작성
# scripts/deploy.sh
#!/bin/bash
BUILD_JAR=$(ls /home/ubuntu/Yakchat_Server_CICD/build/libs/*.jar)
JAR_NAME=$(basename $BUILD_JAR)
echo "> build 파일명: $JAR_NAME" >> /home/ubuntu/Yakchat_Server_CICD/deploy.log
echo "> build 파일 복사" >> /home/ubuntu/Yakchat_Server_CICD/deploy.log
DEPLOY_PATH=/home/ubuntu/Yakchat_Server_CICD/
cp $BUILD_JAR $DEPLOY_PATH
echo "> 현재 실행중인 애플리케이션 pid 확인" >> /home/ubuntu/Yakchat_Server_CICD/deploy.log
CURRENT_PID=$(pgrep -f .jar)
if [ -z $CURRENT_PID ]
then
echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다." >> /home/ubuntu/Yakchat_Server_CICD/deploy.log
else
echo "> kill -9 $CURRENT_PID"
kill -9 $CURRENT_PID
sleep 5
fi
DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> DEPLOY_JAR 배포" >> /home/ubuntu/Yakchat_Server_CICD/deploy.log
source /home/ubuntu/.bashrc
nohup java -jar $DEPLOY_JAR >> /home/ubuntu/Yakchat_Server_CICD/deploy.log 2>/home/ubuntu/Yakchat_Server_CICD/deploy_err.log &
- AppSpec 파일의 hooks 단계의 location 위치에 배포 쉘 스크립트를 작성한다.
- stop.sh와 start.sh를 나누는 경우도 있지만 나의 경우는 한번에 진행하였으니 작성자 마음대로 작성하면 된다.
5. bulid.gradle 수정
jar {
enabled = false
}
- Spring boot 2.5 버전 이상부터는 build 시 plain.jar 파일도 생성된다.
- 배포 쉘 스크립트 실행 시 *.jar 파일이 여러개라면 오류가 발생한다.
- 그래서 plain.jar 파일을 생성하지 않기 위해 build.gradle을 수정한다.
6. 배포 및 확인
- deploy.yml에서 설정한 브랜치로 push를 GitHub의 Actions를 확인하여 build 상태를 확인한다.
- AWS CodeDeploy에서 배포 내역을 확인한다.
- AppSpec 파일에서 작성한 파일이 복사되는 위치에서 실제 복사됨을 확인한다.
- ps-ef 명령어를 통해 jar 파일이 정상 실행됨을 확인하였다.