GitHub Actions CI/CD

sanggyu·2023년 3월 20일
0

Spring Boot + GitHub Actions + AWS CodeDeploy를 활용한 CI/CD

Ec2 생성 부분은 없습니다.(이미 생성된 인스턴스가 존재해서)

New workflow 클릭 후

파란색 글씨의 set up a workflow yourself를 클릭합니다.

Main.yml 파일을 생성

#workflow의 이름
name: test
#해당 workflow가 언제 실행될 것인지에 대한 트리거를 지정
on:
  push:
    branches: [ main ]  #main branch로 push될 때 실행된다.
  pull_request:
    branches: [ main ]  #main branch로 pull될 때 실행된다.

env:
  S3_BUCKET_NAME: test-deploy

# workflow는 한개 이상의 job을 가지며, 각 job은 여러 step에 따라 단계를 나눌 수 있습니다.
jobs:
  build:
# 해당 jobs에서 아래의 steps들이 어떠한 환경에서 실행될 것인지를 지정합니다.
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    
    - name: Set up JDK 17
      uses: actions/setup-java@v2
      with:
        java-version: '17'
        distribution: 'zulu'
        
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    
    - name: Build with Gradle
      run: ./gradlew clean build

위 main.yml 내용을 작성 후 Start commit를 눌러줍니다.

Actions에서 성공적으로 build 한 것을 확인 할 수 있다.

github actions를 이용한 자동빌드 성공!

우측 상단에 사용자 추가 클릭!

IAM 사용자를 생성하고 싶음 , 사용자 지정암호를 설정 후 다음 버튼 클릭

기존 정책 직접 연결을 체크하고

AmazonEC2FullAccess

AmazonS3FullAccess

AWSCodeDeployFullAccess

세가지를 추가

방금 생성한 사용자를 클릭하여 들어오면 액세스 키가 활성화되지 않았다고 되어있을 것이다.
(나는 엑세스키를 발급받은 상태이다)

보안 자격 증명에 들어가 엑세스키 만들기를 클릭

이중 나는 로컬코드를 선택하고 진행 하였다.

발급을 완료한 후 액세스 키 ID와 비밀 액세스 키를 얻을 수 있다.

그 후 깃허브 - 리파지토리 - Settings - Secrets - Actions

New repository secret을 눌러

아래와 같이 추가

AWS_ACCESS_KEY_ID : 위에서 얻은 액세스 키 ID

AWS_SECRET_ACCESS_KEY : 위에서 얻은 비밀 액세스 키

완료를 한 후
AWS -> S3 생성

버킷 이름을 적고
우리는 IAM에서 만든 사용자로 S3의 FullAccess를 얻을 수 있기 때문에
보안을 위해 모든 퍼블릭 액세스를 차단한 후 생성

그 후 main.yml을 수정

name: test

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

env:
  S3_BUCKET_NAME: tset-deploy

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    
    - name: Set up JDK 17
      uses: actions/setup-java@v2
      with:
        java-version: '17'
        distribution: 'zulu'
        
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    
    - name: Build with Gradle
      run: ./gradlew clean build
      
    # 디렉토리 생성
    - name: Make Directory
      run: mkdir -p deploy
        
    # Jar 파일 복사
    - name: Copy Jar
      run: cp ./build/libs/*.jar ./deploy

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

파일을 압축하고, s3에 업로드 하는 내용을 추가 및 커밋

조금 기다리면 S3에 zip파일이 잘 올라간 것을 확인 할 수 있다.

Deploy를 위해 IAM 역할을 만들어 준다.

IAM로 들어가서 역할 - 역할만들기를 클릭

aws 서비스 - EC2 선택

권한 정책에서 아래 2가지를 검색해 체크해서 추가

AmazonS3FullAccess

AWSCodeDeployFullAccess

역할 이름을 부여해주고, 권한이 추가된 것을 확인 한 후 역할을 생성

사용사례를 CodeDeploy로 선택해 준 후

다른 부분은 건드리지 않고,

역할 이름을 정한 후 역할을 생성

EC2 접속 후 셋팅

ssh -i 키페어.pem ubuntu@퍼블릭 IP주소

git bash 에 작성 후 ec2에 잘 접속했다면
cd /home/ubuntu
mkdir app
cd app/

명령어를 입력 후 app폴더에 들어와
순서대로 명령어를 입력

sudo apt update
sudo apt install ruby-full
sudo apt install wget

cd /home/ubuntu

sudo apt install awscli
aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2

chmod +x ./install
sudo ./install auto

#아래 코드로 설치 확인
sudo service codedeploy-agent status

설치가 잘된 경우

다음과 같은 코드를 볼수있다.

다음
jdk 17버전 설치
sudo apt-get install openjdk-17-jdk

java 버전 확인
java -version

프로젝트에 맞는 jdk를 설치해주면 됨

완료가 된 후
aws -> Codedeploy로 들어와서

생성 후 배포 그륩 생성

서비스 역할에서 위에서 생성한 애플리케이션 그륩용 역할을 클릭

환경구성에서 EC2 인스턴스 클릭 후
배포할 EC2 선택 후
그룹을 생성 (로드 밸런서는 체크해제)

자동 배포를 위한 스크립트 추가
appspec.yml 설정

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ubuntu/app/
    overwrite: yes

permissions:
  - object: /
    pattern: "**"
    owner: ubuntu
    group: ubuntu

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

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

deploy.sh 생성

#!/usr/bin/env bash

REPOSITORY=/home/ubuntu/app

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

CURRENT_PID=$(pgrep -fla java | grep hayan | 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/*SNAPSHOT.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 &

(root 바로 아래 (build.gradle과 같은 위치)에 scripts/deploy.sh를 생성하고 위의 코드를 작성)

main.yml 수정

name: test

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

env:
  S3_BUCKET_NAME: test-deploy

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    
    - name: Set up JDK 17
      uses: actions/setup-java@v2
      with:
        java-version: '17'
        distribution: 'zulu'
        
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    
    - name: Build with Gradle
      run: ./gradlew clean build
      
    # 디렉토리 생성
    - name: Make Directory
      run: mkdir -p deploy
        
    # Jar 파일 복사
    - name: Copy Jar
      run: cp ./build/libs/*.jar ./deploy
      
    # appspec.yml 파일 복사
    - name: Copy appspec.yml
      run: cp appspec.yml ./deploy


    # script files 복사
    - name: Copy script
      run: cp ./scripts/*.sh ./deploy

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



    # 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 test[만든 애플리케이션 이름] \
        --deployment-group-name test-group[만든 애플리케이션 그룹 이름] \
        --file-exists-behavior OVERWRITE \
        --s3-location bucket=test-deploy[S3버킷이름],bundleType=zip,key=test.zip[S3버킷 속 압축파일] \ 
        --region ap-northeast-2

위와 같이 수정하고 커밋

그다음
외부에서 EC2로 접근할 수 있도록 인스턴스 보안 포트를 열어줘야 한다.
인바운드 규칙 - 인바운드 규칙 편집

저장 후

깃에 test commit을 해주고 난 뒤

EC2 -> 인스턴스 클릭 -> 퍼블릭 IPv4:port 로 접속하면

0개의 댓글