230327 TIL #43 S3, CodeDeploy, EC2, CI/CD

김춘복·2023년 3월 27일
0

TIL : Today I Learned

목록 보기
43/571

230327 Today I Learned

클론코딩 3일차. 이미지 업로드 기능을 구현했다. 이 부분은 내일 정리하도록 하고 오늘 TIL에는 CI/CD에 대해 정리해보고자 한다.


CI/CD

참고 사이트

  • 저번 프로젝트때 Elastic BeanStalk로 구현에 성공만 했던 CI/CD를 이번 프로젝트때 위의 사이트를 참고해 AWS S3, CodeDeploy, EC2 를 이용하여 완벽하게 성공했다.

  • github secrets에 AWS_ACCESS_KEY_ID와 AWS_SECRET_ACCESS_KEY 설정 후

  • .github/workflows/gradle.yml

name: Java CI with Gradle

on:
  push:
    branches: [ "main" ]

env:
  AWS_REGION: AWS 지역
  S3_BUCKET_NAME: 버킷이름
  CODE_DEPLOY_APPLICATION_NAME: CodeDeploy 어플리케이션이름
  CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: CodeDeploy 배포그룹 이름

permissions:
  contents: read

jobs:
#  build:
#    runs-on: ubuntu-latest
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    environment: production

    steps:
    # (1) 기본 체크아웃
    - name: Checkout
      uses: actions/checkout@v3

    - uses: actions/checkout@v3 #H2말고 노출하면안되는 RDS정보를 쓸 때 이를 활용
#     - run: touch ./src/main/resources/application.properties
#     - run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties
#     - run: cat ./src/main/resources/application.properties

    - name: Run chmod to make gradlew executable
      run: chmod +x ./gradlew

    # (2) JDK 17 세팅
    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'

    # (3) Gradle build (Test 제외)
    #     - name: Grant execute permission for gradlew
    #       run: chmod +x gradlew
    - name: Build with Gradle
      uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
      with:
        arguments: clean build -x test

    # (4) AWS 인증 (IAM 사용자 Access Key, Secret Key 활용)
    - 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: ${{ env.AWS_REGION }}

    # (5) 빌드 결과물을 S3 버킷에 업로드
    - name: Upload to AWS S3
      run: |
        aws deploy push \
          --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
          --ignore-hidden-files \
          --s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \
          --source .
    # (6) S3 버킷에 있는 파일을 대상으로 CodeDeploy 실행
    - name: Deploy to AWS EC2 from S3
      run: |
        aws deploy create-deployment \
          --application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
          --deployment-config-name CodeDeployDefault.AllAtOnce \
          --deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
          --s3-location bucket=$S3_BUCKET_NAME,key=$GITHUB_SHA.zip,bundleType=zip
  • appspec.yml
version: 0.0
os: linux

files:
  - source:  /
    destination: /home/ubuntu/app
    overwrite: yes

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

hooks:
  AfterInstall:
    - location: scripts/stop.sh
      timeout: 60
      runas: ubuntu
  ApplicationStart:
    - location: scripts/start.sh
      timeout: 60
      runas: ubuntu
  • scripts/start.sh
#!/usr/bin/env bash

PROJECT_ROOT="/home/ubuntu/app"
JAR_FILE="$PROJECT_ROOT/프로젝트명.jar"

APP_LOG="$PROJECT_ROOT/application.log"
ERROR_LOG="$PROJECT_ROOT/error.log"
DEPLOY_LOG="$PROJECT_ROOT/deploy.log"

TIME_NOW=$(date +%c)

# build 파일 복사
echo "$TIME_NOW > $JAR_FILE 파일 복사" >> $DEPLOY_LOG
cp $PROJECT_ROOT/build/libs/*.jar $JAR_FILE

# jar 파일 nohup으로 실행
echo "$TIME_NOW > $JAR_FILE 파일 실행" >> $DEPLOY_LOG
nohup java -jar $JAR_FILE > $APP_LOG 2> $ERROR_LOG &

CURRENT_PID=$(pgrep -f $JAR_FILE)
echo "$TIME_NOW > 실행된 프로세스 아이디 $CURRENT_PID 입니다." >> $DEPLOY_LOG
  • scripts/stop.sh
#!/usr/bin/env bash

PROJECT_ROOT="/home/ubuntu/app"
JAR_FILE="$PROJECT_ROOT/프로젝트명.jar"

DEPLOY_LOG="$PROJECT_ROOT/deploy.log"

TIME_NOW=$(date +%c)

# 현재 구동 중인 애플리케이션 pid 확인
CURRENT_PID=$(pgrep -f $JAR_FILE)

# 프로세스가 켜져 있으면 종료
if [ -z $CURRENT_PID ]; then
  echo "$TIME_NOW > 현재 실행중인 애플리케이션이 없습니다" >> $DEPLOY_LOG
else
  echo "$TIME_NOW > 실행중인 $CURRENT_PID 애플리케이션 종료 " >> $DEPLOY_LOG
  kill -15 $CURRENT_PID
fi
  • 위의 파일들을 세팅하고 참고사이트에 있는 정보 설정을 토대로 S3, CodeDeploy, EC2를 설정하고 main에서 push하면 자동으로 ci/cd가 되도록 설계했다.

메모

  • 이미지 업로드 구현시 IntelliJ에서 Edit Configuration - Modify options - environment variables - AWS_ACCESS_KEY_ID=엑세스키값;AWS_SECRET_ACCESS_KEY=시크릿키값 넣어야 로컬에서도 잘 작동.

  • @RequestBody 어노테이션은 application/json, application/xml 등의 데이터 형식으로 전송된 HTTP 요청 본문을 자바 객체로 변환하는데 사용되며, multipart/form-data 인코딩 방식으로 전송된 파일을 처리하기 위해서는 @RequestParam 어노테이션을 사용해야 한다.

  • 일반적으로는 file과 json형식을 분리해서 보내지만 같이 보낼 수 있는 방법이 없는 것은 아니다.

profile
Backend Dev / Data Engineer

0개의 댓글