GitHub Action - CodeDeploy 배포 자동화(Amazon Linux, Spring)

Jang990·2024년 5월 9일
0

AWS 배포 환경 설정

목록 보기
5/5

Github Action - CodeDeploy

velog/juhyeon1114/실전! Github actions, AWS Code deploy로 Spring boot 배포 자동화하기
위 글을 기반으로 진행하고, 설정이 다른 부분과 오류가 발생한 부분을 이 글에 정리해둔다.

CodeDeploy 에이전트 설치

나는 우분투가 아닌 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

EC2 폴더 및 파일 사전 작업

-가 있는 부분은 디렉토리이고 -가 없는 부분은 파일이다.

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 (폴더 생성 필요)

Github Action 워크플로우 작성

deploy.sh - 워크 플로우 작성 전 스크립트

프로젝트의 루트 폴더에 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
    
    

CodeDeploy

appspec.yml

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/app/project/zip
    overwrite: yes

hooks:
  ApplicationStart:
    - location: deploy.sh
      timeout: 60

1% 실패 문제


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

오류 error: unable to access jarfile

이 경우 nohup을 할 때 경로 문제가 있었다.
나는 마지막 nohup 명령어에서 jar파일의 전체 경로인 $REPOSITORY가 누락돼 있었다.
그래서 $JAR_NAME -> $REPOSITORY/$JAR_NAME로 바꿨다.
이전에는 jar파일이 상대 경로로 동작해서 발생한 오류 였다.

이 오류가 발생한다면 해당 오류가 발생한 라인에 파일들의 경로를 다시 한 번 살펴보면 해결할 수 있을 것이다.

profile
공부한 내용을 적지 말고 이해한 내용을 설명하자

0개의 댓글