본문 바로가기

개발

[CI/CD] S3 + CodeDeploy

CI(Continuous Integration) → 여러 개발자들의 코드베이스를 계속해서 통합하는 것

CD(Continuous Delivery) → 코드베이스가 항상 배포가능한 상태를 유지하는 것

내 application.yml 파일은 보안상 git에 올리면안돼서 .gitignore에 추가한다.

deploy.yml에 코드를 추가해 git action이 진행되는 동안 application.yml에서 생성되게한다.

 

Git Action과 S3연결

[사용자 생성]

 

[해당 사용자의 권한 설정]

 

 [사용자의 액세스 키 생성] → git action 내 프로젝트 키로 사용 됨

 

[github] 내 프로젝트 → Settings → Secrets and variables → Actions

(APPLICATION에는 내 프로젝트의 application.yml에 사용되는 key들이 들어간다.)

(AWS_~는 AWS에 접근할 때 사용되는 키들이다.)

git action에서 빌드된 파일을 둘 s3 생성

 

github → Actions → deploy.yml 

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

name: Java CI with Gradle

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

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Generate application.yml
        run: |
          mkdir ./src/main/resources # resources 폴더 생성
          cd ./src/main/resources # resources 폴더로 이동
          touch ./application.yml # application.yml 생성
          echo "${{ secrets.APPLICATION }}" > ./application.yml # github actions에서 설정한 값을 application.yml 파일에 쓰기
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin' 
      - name: Build with Gradle
        uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
        with:
          arguments: build
#      - name: Rename file
#        run: mv ./build/libs ./build/lolonoa-build
      - name: Make zip file
        run: zip -r ./lolonoa-zip .
        shell: bash
        # AWS Login 
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        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: Run Script
        run: ls
      - name: Upload to S3
        run: aws s3 cp --region ap-northeast-2 ./lolonoa-zip.zip s3://lolonoa-deploy-s3/lolonoa.zip #S3에 업로드하는 명령어

 

 

정상적으로 build

 

s3에 deploy.yml에서 생성한 zip파일이 생성됨!

 

Code Deploy

IAM → 역할 생성 ec2-codedeploy-role

 

EC2 → 작업 → 보안 → IAM 역할 수정

 

역할생성: IAM → 역할 생성 lolonoa-for-codedeploy

 

CodeDeploy 생성

당시에는 이름을 lolonoa-codedeploy로 만들었는데, 이후에 lolonoa로 변경함

 

 

+EC2의 태그 설정

 

값은 EC2에서 설정한 것 처럼 키 = Name, 값 = lolonoa로 한다(해당 사진은 lolonoa-deploy지만..)

 

 

내가 생성한 애플리케이션의 배포그룹설정

 

내 EC2에도 CodeDeploy를 설치해줘야한다.

 

git action의 deploy.yml 코드 추가

: 배포그룹으로 애플리케이션 전송

   - name: Code deploy
     run: aws deploy create-deployment --application-name lolonoa --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name lolonoa-group --s3-location bucket=lolonoa-deploy-s3,bundleType=zip,key=lolonoa.zip

 

appspec.yml 추가

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

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

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

 

프로젝트에 scripts 폴더 생성 후 deploy.sh 생성

#!/bin/bash

REPOSITORY=/home/ubuntu/lolonoa
BUILD_JAR=$(ls /home/ubuntu/lolonoa/build/libs/*.jar)
JAR_NAME=$(basename $BUILD_JAR)

#echo "> Build 파일 복사"

cp $REPOSITORY/build/libs/*.jar $REPOSITORY/

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

# 수행 중인 애플리케이션 프로세스 ID => 구동 중이면 종료하기 위함
#CURRENT_PID=$(pgrep -fl $PROJECT_NAME | grep jar | awk '{print $1}')
CURRENT_PID=$(pgrep -f $JAR_NAME)
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 $REPOSITORY/$JAR_NAME # Jar 파일은 실행 권한이 없는 상태이므로 권한 부여

echo "> $JAR_NAME 실행"

nohup java -jar $REPOSITORY/$JAR_NAME > $REPOSITORY/nohup.out 2>&1 &
# nohup 실행 시 CodeDeploy는 무한 대기한다. 이를 해결하기 위해 nohup.out 파일을 표준 입출력용으로 별도로 사용한다.
# 이렇게 하지 않으면 nohup.out 파일이 생성되지 않고 CodeDeploy 로그에 표준 입출력이 출력된다.

 

실행

[git action]

 

[CodeDeploy]

 

새로 만든 api 테스트하니 잘 작동함!