Github Action으로 Spring boot 배포하기(4)

김우진·2022년 9월 9일
0

배포 자동화를 위한 AWS CodeDeploy 생성

  1. AWS 페이지에서 CodeDeploy Service로 들어가 Application 생성을 누릅니다.

  2. Application 이름을 입력해주고 플랫폼을 EC2/온프레미스로 설정해주고 생성해줍니다.

  3. 생성된 Application의 배포 그룹을 생성 해주기위해 배포 그룹 생성을 누릅니다.

  1. 배포 그룹의 이름을 입력하고 서비스를 수행할 수 있는 역할을 연결합니다. 여기서 이전 게시글에서 만든 CodeDeploy 역할을 선택합니다.

  2. 아래로 내려 환경 구성 탭에서 EC2 인스턴스를 클릭 후 배포하기위해 만든 EC2를 선택한 뒤 그룹을 생성해줍니다.

Github에 배포를 위한 코드 스크립트 생성

  1. EC2에서 CodeDeploy agent로 배포하기위해 설정파일인 appspec.yml을 만들 것입니다.

  2. root 바로 아래(build.gradle과 같은 위치)에 appspec.yml을 생성하고 아래 코드를 작성해줍니다.

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ubuntu/{{target directory}}
    overwrite: yes
    
permissions:
  - object: /
    pattern: "**"
    owner: ubuntu
    group: ubuntu
    
hooks:
  ApplicationStart:
    - location: deploy.sh
      timeout: 60
      runas: ubuntu

코드 내용(이해할 수 있는 정도로만 이해하였습니다.)
정확히 맞는지는 모르지만 EC2에 배포된 후의 작업들을 위한 설정을 해줍니다.
배포가 실행되면 EC2에 설치된 CodeDeploy agent에서 이 파일을 보고 받아온 프로젝트를 어디에 저장하고 무엇을 실행할 지 정하기 때문에 배포가 실행될 위치, 권한, 실행 hooks 설정 등을 이 파일에서 해주는 것 같습니다.

  1. 동일한 경로에 scripts/deploy.sh를 생성하고 아래의 코드를 작성해줍니다. (즉, root아래엔 appspec.yml과 scripts 폴더가 있고 scripts 안에 deploy.sh가 존재하면 됩니다.)
#!/usr/bin/env bash

# 기본은 /home/ubuntu로 하시면 되고 Ec2내에 폴더를 만들었으면 폴더 이름을 repository name에 넣어주세요
REPOSITORY=/home/ubuntu/{{ repository name }}

echo "> 현재 구동 중인 애플리케이션 pid 확인"

CURRENT_PID=$(pgrep -fla action | grep java | awk '{print $1}')

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/*.jar | tail -n 1)

echo "> JAR NAME: $JAR_NAME"

echo "> $JAR_NAME 에 실행권한 추가"

chmod +x $JAR_NAME

echo "> $JAR_NAME 실행"

nohup java -jar -Duser.timezone=Asia/Seoul $JAR_NAME >> $REPOSITORY/nohup.out 2>&1 &

코드 내용
실행중인 application이 있다면 PID를 잡아 종료시키고, jar 파일을 이용하여 nohup으로 무중단 배포를 진행해줍니다.

생성한 코드 스크립트를 git action의 설정 파일에 추가

  1. github action의 배포 설정 파일에 아래 내용을 추가해줍니다.
name: Java CI with Gradle

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

permissions:
  contents: read
  
env:
  S3_BUCKET_NAME: {{ 자신의 buck name }}

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v3
    
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
        
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
        
    - name: Build with Gradle
      uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
      with:
        arguments: build

    - name: Make Directory
      run: mkdir -p deploy
      
    - name: Copy Jar
      run: cp ./build/libs/*.jar ./deploy
      
    - name: Copy appspec.yml
      run: cp appspec.yml ./deploy
      
    - name: Copy script
      run: cp ./scripts/*.sh ./deploy
      
    - name: Make zip file
      run: zip -r ./{{zip 파일 이름}}.zip ./deploy
      shell: bash
      
    - 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: ap-northeast-2
        
    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./mylist.zip s3://$S3_BUCKET_NAME/
      
      # Code Deploy 설정 추가
    - name: Deploy 
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      run: aws deploy create-deployment --application-name {{자신의 application 이름}} --deployment-group-name {{자신이 설정해준 group name}} --file-exists-behavior OVERWRITE --s3-location bucket={{자신의 bucket name}},bundleType=zip,key={{자신의 bucket zip 파일 이름}}.zip --region {{자신의 region (서울 : ap-northeast-2)}}

Git action 동작 시 EC2에 접근할 수 있도록 포트 열기

  1. EC2의 Category 중 보안 그룹을 누르고 보안 그룹 생성을 누릅니다.

  2. 보안 그룹의 이름과 설명을 작성하고, 인바운드 규칙에서 자신의 server port에 맞춰 열어줍니다.(아래와 같이 열면 보안에 취약하지만 지금은 연습용이니 넘어갑니다.)

  3. 내 인스턴스로 가서 오른쪽 버튼을 누른 뒤 보안의 보안 그룹 변경으로 방금 만든 보안 그룹으로 지정해줍니다.

Github Action에서 코드 push 후 배포 확인

  1. 배포를 위한 임의의 코드를 작성해줍니다. (/으로 get 요청 시 문자열 "hello home"이 화면에 출력되는 코드를 작성합니다.)
@RestController
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "hello home";
    }
}
  1. 변경사항을 저장하고 main branch에 push를 하면 아래와 같이 github action이 build와 deploy를 한 것을 확인할 수 있습니다.

  1. AWS의 codedeploy를 확인하면 역시 재대로 배포된 것을 확인할 수 있습니다.

✒️ 참고
AWS codedeploy 에서 error가 발생한다면 여기를 참고하면 됩니다.

  1. EC2 서버의 DNS나 public IP로 접속하면 화면에 "hello home"이 뜨는 것을 확인 할 수 있습니다.

여기까지 진행하시면, github action을 이용한 spring boot project 배포가 끝납니다.
혹시나 작성 중 문제가 발생했다면, 제가 겪은 문제를 다음 게시글에 남겨두었으니 참고하시길 바랍니다.

0개의 댓글