velog/juhyeon1114/실전! Github actions, AWS Code deploy로 Spring boot 배포 자동화하기
위 글을 기반으로 진행하고, 설정이 다른 부분과 오류가 발생한 부분을 이 글에 정리해둔다.
나는 우분투가 아닌 Amazon Linux이기 때문에 설치 방법이 아주 약간 다르다.
sudo yum update
sudo yum install ruby -y
sudo yum install wget -y
# 홈 디렉터리 이동
cd /home/ec2-user
wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
sudo ./install auto > /tmp/logfile
# 설치 확인
sudo systemctl status codedeploy-agent
밑에서 CodeDeploy 1% 실패 문제
를 만나기 싫다면 다음 명령어도 추가적으로 실행해주자.
sudo service codedeploy-agent restart
-
가 있는 부분은 디렉토리이고 -
가 없는 부분은 파일이다.
app 디렉토리 하위에 yml은 github에 올릴 수 없는 파일들은 따로 ec2에 배치해준 것이다.
그래서 프로젝트 yml 환경에 따라 바꿔주면 된다.
이 yml에 따라 밑에서 다루는 deploy.sh
에 마지막 nohup java -jar
명령어가 달라진다.
이것도 프로젝트 환경에 따라 같이 변경해주면 된다.
/home/ec2-user 하위 디렉토리 및 파일들.
- app (폴더 생성 필요 mkdir app)
application-oauth.yml
application-prod.yml
application-openai.yml
- project (폴더 생성 필요)
- zip (폴더 생성 필요)
프로젝트의 루트 폴더에 script 폴더를 생성해주고 필요한 스크립트를 생성해준다.
나는 stop과 start를 쓰지 않고 deploy.sh를 만들어서 쓴다.
#!/bin/bash
REPOSITORY=/home/ec2-user/app/project
echo "> Build 파일복사"
cp $REPOSITORY/zip/*.jar $REPOSITORY/
echo "> 현재 구동중인 애플리케이션 pid 확인"
CURRENT_PID=$(ps -ef | grep java | awk '{print $2}')
echo "연재 구동중인 애플리케이션 pid: $CURRENT_PID"
if [ -z $CURRENT_PID]; then
echo "> 현재 구동중인 애플리케이션 없음.";
else
echo "> kill -15 $CURRENT_PID"
kill -15 $CURRENT_PID
sleep 5
fi
echo "> 새 애플리케이션 배포"
JAR_NAME=$(ls -tr $REPOSITORY/ | grep jar | tail -n 1)
echo "> JAR Name: $JAR_NAME"
echo "$JAR_NAME 실행"
nohup java -jar -Dspring.config.location=classpath:/application-interview.yml,/home/ec2-user/app/application-prod.yml,/home/ec2-user/app/application-openai.yml,/home/ec2-user/app/application-oauth.yml -Dspring.profiles.active=prod $REPOSITORY/$JAR_NAME > $REPOSITORY/nohup.out 2>&1 &
env만 적절하게 수정해주면 될 것 같다.
AWS_S3_OBJECT_NAME
이 추가됐다.
달라진 점으로 글의 워크플로우는 전체 프로젝트를 S3에 zip파일로 업로드하지만,
이 워크플로우는 depoly 폴더를 만들고 jar 파일과 스크립트 파일만을 S3에 업로드한다.
name: CICD Gpterview
run-name: Running
on:
push:
branches:
- main
env:
AWS_REGION: ap-northeast-2
AWS_S3_BUCKET: S3 버킷 이름
AWS_S3_OBJECT_NAME: S3 버킷에 저장될 위치 이름
AWS_CODE_DEPLOY_APPLICATION: CodeDeploy 애플리케이션 이름
AWS_CODE_DEPLOY_GROUP: CodeDeploy 그룹 이름
jobs:
build-with-gradle:
runs-on: ubuntu-latest
steps:
- name: main 브랜치로 이동
uses: actions/checkout@v3
with:
ref: main
- name: JDK 17 설치
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'
- name: gradlew에 실행 권한 부여
run: chmod +x ./gradlew
- name: 프로젝트 빌드
run: ./gradlew clean build -x test
- name: 업로드할 deploy 디렉토리 생성
run: |
mkdir deploy/
cp build/libs/*.jar deploy/
cp script/*.sh deploy/
cp appspec.yml deploy/
- 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: deploy 폴더를 S3 업로드
run: |
aws deploy push --application-name ${{ env.AWS_CODE_DEPLOY_APPLICATION }} --ignore-hidden-files \
--s3-location s3://$AWS_S3_BUCKET/$AWS_S3_OBJECT_NAME/$GITHUB_SHA.zip \
--source deploy
- 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=$AWS_S3_OBJECT_NAME/$GITHUB_SHA.zip,bundleType=zip
version: 0.0
os: linux
files:
- source: /
destination: /home/ec2-user/app/project/zip
overwrite: yes
hooks:
ApplicationStart:
- location: deploy.sh
timeout: 60
1%로 진행이 안되는데 실패 발생까지 시간이 오래 걸리는 것을 보니까,
애초에 연결이 안되고 타임아웃 문제가 발생한 것 같았다.
EC2와 CodeDeploy는 AWS에서 제공해주는 태그로 연결을 했기 때문에 문제가 아닌 것 같고
문제는 EC2에 있다고 생각했다.
정확한 오류 내용을 확인해보고 싶다면, 개발자 도구 > CodeDeploy > 배포
에서 실패한 배포 ID로 들어가서 View events
를 확인하자.
에러 내용은 다음과 같았다. 역시나 EC2에 있는 codedeploy-agent 문제였다.
CodeDeploy agent was not able to receive the lifecycle event. Check the CodeDeploy agent logs on your host and make sure the agent is running and can connect to the CodeDeploy server.
문제 해결방법은 간단했다.
EC2에 들어가서 codedeploy-agent를 재시작하니까 정상 동작했다.
sudo service codedeploy-agent restart
이 경우 nohup을 할 때 경로 문제가 있었다.
나는 마지막 nohup 명령어에서 jar파일의 전체 경로인 $REPOSITORY
가 누락돼 있었다.
그래서 $JAR_NAME
-> $REPOSITORY/$JAR_NAME
로 바꿨다.
이전에는 jar파일이 상대 경로로 동작해서 발생한 오류 였다.
이 오류가 발생한다면 해당 오류가 발생한 라인에 파일들의 경로를 다시 한 번 살펴보면 해결할 수 있을 것이다.