Computer Science/Spring boot

Spring boot CI/CD git action으로 aws ec2에 올리기.

imygnam 2022. 7. 9. 00:27

우선 바로 배포를 진행할 것이기 때문에 의존성을 모두 포함한 BootJar로만 Build를 진행합니다.

따라서 의존성을 제거하여 build하는 Jar는 skip해줍니다.(snapshot-plain.jar)

jar{
   enabled = false
}

build.gradle에 추가하여 진행합니다.


s3에 대한 접근 권한을 받아오기 위해 AWS IAM을 생성해줍니다.

사용자를 생성해주고, 액서스 키 -> 기존 정책 직접 연결 ->

AmazonEC2FullAccess, AmazonS3FullAccess, AWSCodeDeployFullAccess ->

키 생성 -> 액세스 키 ID, 비밀 액세스 키 secrets-actions에 등록

(EC2와 CodeDeploy는 S3에 파일을 저장하고 이 파일을 EC2에서 가져와 실행할 때 사용할 권한들)

 

github action을 통해 내 spring boot를 build후 s3에 zip으로 옮깁니다.

aws deploy는 tar, zip, tgz만 지원한다. 해당 압축 파일을 ec2로 전송하여 압축을 알아서 푼다.

name: aws CI/CD

on:
 
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]



env:
  S3_BUCKET_NAME: lof-deploy
  
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
      - name: Build with Gradlew
        run: ./gradlew clean build
        
      - name: Make Directory
        run: mkdir deploy
        
      - name: Copy Jar
        run: cp ./build/libs/*.jar ./deploy

      - name: Make zip file
        run: zip -r ./lof.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 ./lof.zip s3://$S3_BUCKET_NAME/

 

 

https://github.com/marketplace/actions/s3-cp

참고하기 


ec2가 s3에 대해 접근 권한 및 deploycode권한을 가지기 위해 역할을 부여해줍니다.

IAM -> 역할 -> 역할 만들기

->aws 서비스 -> ec2 -> AmazonS3FullAccess, AWSCodeDeployFullAccess

-> 인스턴스 -> 보안 - IAM 역할 수정


ec2에서 CodeDeploy 설치.

sudo yum install ruby

wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install

chmod +x ./install

sudo ./install auto

 

확인하기

sudo service codedeploy-agent status


외부에서 작동시킬 CodeDeploy 생성

IAM -> 역할 -> 역할 만들기

-> aws 서비스 -> 다른 aws 서비스 -> CodeDeploy -> 생성

CodeDeploy -> 애플리케이션 -> 애플리케이션 생성 -> EC2/온프레미스

->배포 그룹 -> 배포 그룹 생성 -> 서비스 역할 ( 위에 생성한 역할 ) -> Amazon EC2 인스턴스 -> 배포할 EC2 인스턴스 선택


CodeDeploy가 자동으로 실행할 파일 생성

codedeploy는 appspec.yml 을 읽고 실행한다.

https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/reference-appspec-file-structure.html

참고하기

 

version: 0.0
os: linux
files:
  - source: /
    destination: /home/app
permissions:
  - object: /home/app
    pattern: "**"
    owner: root
    mode: 777
hooks:
  ApplicationStart:
    - location: deploy.sh
      timeout: 300
      runas: root


appspec 으로 실행할 sh 파일 생성.

#!/bin/bash

REPOSITORY=/home/app
echo "> 현재 구동 중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -fla java | awk '{print $1}')
echo "현재 구동 중인 애플리케이션 pid: $CURRENT_PID"
if [ -z "$CURRENT_PID" ]; then
  echo "현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다."
else
  echo "> kill -9 $CURRENT_PID"
  kill -9 $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 /opt/jdk-17/bin/java -jar $JAR_NAME > $REPOSITORY/nohup.out &


마지막으로 해당 appspec 과 sh 파일을 묶어서 zip으로 보내준다.

name: aws CI/CD

on:
 
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

env:
  S3_BUCKET_NAME: lof-deploy
  
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
      - name: Build with Gradlew
        run: ./gradlew clean build
        
      - name: Make Directory
        run: mkdir 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 ./lof.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 ./lof.zip s3://$S3_BUCKET_NAME/
         
      - 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 lof-application --deployment-group-name lof-group --file-exists-behavior OVERWRITE --s3-location bucket=lof-deploy,bundleType=zip,key=lof.zip --region ap-northeast-2