Server

Github Action과 AWS CodeDeploy를 통한 CI/CD 설정

meizzi 2024. 9. 9. 18:09
728x90
반응형
환경: AWS EC2 인스턴스(Linux), MySQL, SpringBoot 3.3.3

CI/CD 과정

CI/CD 흐름은 위 이미지와 같습니다. 

  1. Github 상으로 코드를 Push 하게 되면 GitHub Actions이 자동으로 실행되어 CI (빌드) 작업을 수행하게 됩니다.
  2. 코드상에 문제가 없다면 이때 빌드 작업을 통해 jar파일이 생성되게 되고 사전에 작성한 배포 스크립트 파일과 함께 AWS의 스토리지 서비스인 S3에게 전달되어 저장되게 됩니다.
  3. S3에 성공적으로 저장되었다면 EC2에 설치한 CodeDeploy Agent가 S3에 저장된 프로젝트 파일을 가져와서 내려받습니다.
  4. 그 후, 배포 스크립트 파일을 읽어 들여서 프로젝트 실행을 시작합니다.

즉, 깃허브 상으로 코드를 push 하기만 하면 자동으로 최신 버전의 프로젝트가 EC2에 내려받아져서 이 프로젝트를 실행하게 됩니다.

1. Github Action - CI 설정

CI.yml 파일 생성

# workflow의 이름
name: CI

# 해당 workflow가 언제 실행될 것인지에 대한 트리거를 지정
on:
  push:
    branches: [ "main" ] # main branch로 push 될 때 실행됩니다.
  pull_request:
    branches: [ "main" ] # main branch로 pull request될 때 실행됩니다.
    
# workflow는 한개 이상의 job을 가지며, 각 job은 여러 step에 따라 단계를 나눌 수 있습니다.
jobs:
  build:
    name: CI
    # 해당 jobs에서 아래의 steps들이 어떠한 환경에서 실행될 것인지를 지정합니다.
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'corretto'

    - name: Grant execute permission for gradlew
      run: chmod +x ./gradlew
      shell: bash
      
    - name: Build with Gradle
      run: ./gradlew build
      shell: bash

2. IAM 설정

AWSCodeDeployFullAccess 권한 설정
AmazonS3FullAccess 권한 설정
액세스 키 생성
지금만 확인할 수 있으니까 따로 저장해놓고나 아래 .csv 파일 저장

3. EC2 인스턴스 생성

4. Putty에서 환경 설정

5. S3 버킷 생성

6. Github Actions secrets 추가

  • IAM Access key, Secret key 노출되지 않도록 등록

7. deploy.sh 생성

#!/bin/bash
BUILD_JAR=$(ls /home/ec2-user/action/build/libs/payment-system-0.0.1-SNAPSHOT.jar)
JAR_NAME=$(basename $BUILD_JAR)
echo "> build 파일명: $JAR_NAME" >> /home/ec2-user/action/deploy.log
 
echo "> build 파일 복사" >> /home/ec2-user/action/deploy.log
DEPLOY_PATH=/home/ec2-user/action/
cp $BUILD_JAR $DEPLOY_PATH
 
echo "> 현재 실행중인 애플리케이션 pid 확인" >> /home/ec2-user/action/deploy.log
CURRENT_PID=$(pgrep -f $JAR_NAME)
 
if [ -z $CURRENT_PID ]
then
  echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다." >> /home/ec2-user/action/deploy.log
else
  echo "> kill -15 $CURRENT_PID"
  kill -15 $CURRENT_PID
  sleep 5
fi
 
DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> $DEPLOY_JAR DEPLOY_JAR 배포"    >> /home/ec2-user/action/deploy.log
nohup java -jar $DEPLOY_JAR >> /home/ec2-user/deploy.log 2>/home/ec2-user/action/deploy_err.log &

8. Github Action - CD 설정

CD.yml 생성

# workflow의 이름
name: CD
 
# 해당 workflow가 언제 실행될 것인지에 대한 트리거를 지정
on:
  push:
    branches: [ main ] # main branch로 push 될 때 실행됩니다.
 
# 해당 yml 내에서 사용할 key - value
env:
  S3_BUCKET_NAME: payment-cicd-project-bucket
  PROJECT_NAME: PaymentSystem
  
# workflow는 한개 이상의 job을 가지며, 각 job은 여러 step에 따라 단계를 나눌 수 있습니다.
jobs:
  build:
    name: CD
    # 해당 jobs에서 아래의 steps들이 어떠한 환경에서 실행될 것인지를 지정합니다.
    runs-on: ubuntu-latest
 
    steps:
     # 작업에서 액세스할 수 있도록 $GITHUB_WORKSPACE에서 저장소를 체크아웃합니다.
      - uses: actions/checkout@v4
      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'corretto'
 
      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew
        shell: bash
      
      - name: Build with Gradle
        run: ./gradlew build
        shell: bash
        
      - name: Make zip file
        run: zip -r ./$GITHUB_SHA.zip .
        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: ${{ secrets.AWS_REGION }}
          
      # script files 복사
      - name: Copy script
        run: cp ./scripts/*.sh ./deploy
      
      # S3에 업로드
      - name: Upload to S3
        run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip

9. EC2와 CodeDeploy를 위한 IAM 역할 생성

  • EC2 인스턴스 IAM 역할

수정 후 EC2 인스턴스 재부팅

  • 재부팅 후 다음 명령어를 통해 codedeploy 설치
aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2
  • 성공 후 실행 권한 부여
chmod +x ./install
sudo ./install auto
  • install 할 때 /usr/bin/env: ruby: No such file or directory 뜨면 ruby 설치
  • 설치 확인을 위해 2번째 명령어 입력하면 아래 메시지 출력
    • The AWS CodeDeploy agent is running as PID ****
sudo yum install ruby
sudo service codedeploy-agent status

  • CodeDeploy IAM 역할 수정

10. CodeDeploy 어플리케이션 생성

11. Github appspec.yml 파일 생성

appspec.yml 생성

version: 0.0
os: linux
# S3에 있는 zip 파일이 EC2에 배포될 위치를 지정
files:
  - source: / # CodeDeploy에서 전달해 준 파일 중 destination으로 이동시킬 대상을 루트로 지정(전체파일)
    destination: /home/ec2-user/action/ # source에서 지정된 파일을 받을 위치, 이후 jar를 실행하는 등은 destination에서 옮긴 파일들로 진행
    overwrite: yes
 
permissions: # CodeDeploy에서 EC2서버로 넘겨준 파일들을 모두 ec2-user권한을 갖도록 합니다.
  - object: /
    pattern: "**"
    owner: ec2-user
    group: ec2-user
 
# ApplicationStart 단계에서 deploy.sh를 실행시키도록 합
hooks: # CodeDeploy배포 단계에서 실행할 명령어를 지정합니다.
  ApplicationStart: # deploy.sh를 ec2-user권한으로 실행합니다.
    - location: scripts/deploy.sh
      timeout: 60 # 스크립트 실행 60초 이상 수행되면 실패가 됩니다.
      runas: ec2-user

12. Github Action - CD Deploy 설정

  • 자신의 설정에 따라 아래 변수 변경
    • application-name
    • deployment-group-name
    • s3-location bucket
    • key
728x90
반응형