DevOps/AWS

[AWS] 스프링 부트 프로젝트 배포 자동화하기 (2)

jyjyjy25 2023. 12. 3. 00:13

6. Github Action 워크플로우 작성

프로젝트를 빌드한 후 AWS S3 버킷에 푸시 후 CodeDeploy를 수행한다.

name: Build and Deploy Spring Boot to AWS EC2

# main 브랜치에 푸쉬 했을 때
on:
  push:
    branches: [ main ]

# 리전, s3 버킷 이름, CodeDeploy 앱 이름, CodeDeploy 배포 그룹 이름
env:
  AWS_REGION: ap-northeast-2
  S3_BUCKET_NAME: my-github-action-s3-bucket-i-0108286cf8acc8920
  CODE_DEPLOY_APPLICATION_NAME: my-codedeploy-test
  CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: my-codedeploy-development-group

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-20.04

    steps:
      # (1) 기본 체크아웃
      - name: Checkout
        uses: actions/checkout@v3

      # (2) JDK 11 세팅
      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          distribution: 'temurin'
          java-version: '11'

      # (3) gradlew 파일 실행 권한 설정
      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew
        shell: bash

      # (4) Gradle build (Test 제외)
      - name: Build with Gradle
        uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
        with:
          arguments: clean build -x test

      # (4) AWS 인증 (IAM 사용자 Access Key, Secret Key 활용)
      - name: Configure AWS credentials
        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: ${{ env.AWS_REGION }}

      # (5) 빌드 결과물을 S3 버킷에 업로드
      - name: Upload to AWS S3
        run: |
          aws deploy push \\
            --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \\
            --ignore-hidden-files \\
            --s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \\
            --source .

      # (6) S3 버킷에 있는 파일을 대상으로 CodeDeploy 실행
      - name: Deploy to AWS EC2 from S3
        run: |
          aws deploy create-deployment \\
            --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \\
            --deployment-config-name CodeDeployDefault.AllAtOnce \\
            --deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \\
            --s3-location bucket=$S3_BUCKET_NAME,key=$GITHUB_SHA.zip,bundleType=zip

 

7. appspec.yml 작성

CodeDeploy에서 배포를 위해 참조하는 파일이다.

  • AppSpec 파일은 루트 디렉터리에 위치해야 한다.
  • AppSpec 파일을 사용해서 프로젝트의 어떤 파일들을 EC2의 어떤 경로에 복사할지 설정 가능하고, 배포 프로세스 이후에 수행할 스크립트를 지정하여 자동으로 서버를 띄울 수도 있다.
version: 0.0
os: linux

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

permissions:
  - object: /
    owner: ubuntu
    group: ubuntu

hooks:
  ApplicationStart:
    - location: scripts/deploy.sh
      timeout: 60
      runas: ubuntu

 

 

files 섹션

files:
  - source:  /
    destination: /home/ubuntu/spring-github-action
    overwrite: yes
  • source: 인스턴스에 복사할 디렉터리 경로
  • destination: 인스턴스에서 파일이 복사되는 위치
  • overwrite: 복사할 위치에 파일이 있는 경우 대체 여부

 

permissions 섹션

permissions:
  - object: /
    owner: ubuntu
    group: ubuntu
  • object: 권한이 지정되는 파일 또는 디렉터리
  • owner (optional): object의 소유자
  • group (optional): object의 그룹 이름

 

hooks 섹션

배포 이후에 수행할 스크립트를 지정할 수 있다.

hooks:
  ApplicationStart:
    - location: scripts/deploy.sh
      timeout: 60
      runas: ubuntu
  • location: hooks에서 실행할 스크립트 위치
  • timeout (optional): 스크립트 실행에 허용되는 최대 시간이며, 넘으면 배포 실패로 간주
  • runas (optional): 스크립트를 실행하는 사용자

 

8. scripts/deploy.sh 작성

#!/bin/bash

ROOT_PATH="/home/ubuntu/spring-github-action"
JAR_NAME=$(ls $ROOT_PATH/build/libs/ | grep 'SNAPSHOT.jar' | tail -n 1)
JAR_PATH=$ROOT_PATH/build/libs/$JAR_NAME

APP_LOG="$ROOT_PATH/application.log"
ERROR_LOG="$ROOT_PATH/error.log"
START_LOG="$ROOT_PATH/start.log"
STOP_LOG="$ROOT_PATH/stop.log"

SERVICE_PID=$(pgrep -f $JAR) # 실행 중인 Spring 서버의 PID

if [ -z "$SERVICE_PID" ]; then
  echo "서비스 NouFound" >> $STOP_LOG
else
  echo "서비스 종료 " >> $STOP_LOG
  kill "$SERVICE_PID"
fi

NOW=$(date +%c)

# build 파일 복사
echo "[$NOW] $JAR 복사" >> $START_LOG
cp $JAR_PATH $ROOT_PATH/$JAR_NAME

# jar 파일 실행
echo "[$NOW] > $JAR 실행" >> $START_LOG
nohup java -jar $ROOT_PATH/$JAR_NAME > $APP_LOG 2> $ERROR_LOG &

SERVICE_PID=$(pgrep -f $ROOT_PATH/$JAR_NAME)
echo "[$NOW] > 서비스 PID: " $SERVICE_PID >> $START_LOG

nohup: 프로세스를 실행한 터미널의 세션 연결이 끊기더라도 프로세스를 계속해서 동작시키는 명령어

 

9. 배포 확인

1) 워크플로우 확인

2) S3 확인

3) CodeDeploy 확인

4) 기타 확인

  • jar 파일 생성 확인

  • 서비스 구동 확인
ps -ef | grep java

  • 페이지 접속 확인