개발진행목록/학습 커뮤니티 서비스

[학습 커뮤니티] 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 파일이 정상 실행됨을 확인하였다.