Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

공hannah부

CI & CD 본문

공부/백엔드

CI & CD

Hannah0226 2023. 6. 2. 02:01

이론

CI(Continuous Integratrion)란?

개발을 하면서 코드에 대한 통합을 지속적으로 진행함으로써 코드 품질을 유지하는 것

 

CD(Continous Delivery/Deploy)란?

배포를 자동화하여 지속적으로 배포하는 것

 

Github Actions + AWS CodeDeploy 아키텍쳐


구현

  • EC2 인스턴스 시작
  • EC2 tag 추가
  • IAM 역할 추가 - EC2 인스턴스에서 S3에 올려놓은 파일에 접근할 수 있도록
    • IAM(Identity and Access Management)는 AWS 리소스에 대해 엑세스를 안전하세 제어할 수 있는 웹 서비스이다.
    • 이를 사용해 리소스를 사용하도록  인증 및 권한 부여된 대상을 제어한다.
  • EC2에 IAM 역할 추가
  • EC2에 CodeDeploy Agent 설치(Putty를 이용해 EC2 서버에 원격 접속 후 명령어 입력)
$ sudo apt update
$ sudo apt install ruby-full
$ sudo apt install wget
$ cd /home/ubuntu
$ wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto > /tmp/logfile
$ sudo service codedeploy-agent status
  • EC2 서버에 루트 디렉토리 만들기(프로젝트를 빌드하고 실행할 루트 디렉토리)
  • AWS S3 생성
  • CodeDeploy를 위한 IAM 만들기
  • CodeDeploy 애플리케이션 생성
  • CodeDeploy 배포 그룹 생성
  • GitHub Actions를 위한 IAM 사용자 추가
    • 추가시 마지막 단계에서 [완료]를 누르기 전 [.csv 파일 다운로드] 눌러 다운 받기!!
  • Github Secrets에 IAM User 엑세스 키 정보 / Application 정보 추가
    • Settings -> New repository secret
  • appspec.yml 작성(Code Deploy에서 배포하 위해 참조 파일 루트 디렉토리에 작성한다)
version: 0.0
os: linux

files:
  - source:  /
    destination: /home/ubuntu/{내 루트 디렉토리 이름}
    overwrite: yes
file_exists_behavior: OVERWRITE
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 디렉토리 생성후 그 자리에)
  • scripts/start.sh
#!/usr/bin/env bash

PROJECT_ROOT="/home/ubuntu/{내 루트 디렉토리 이름}"
JAR_FILE="$PROJECT_ROOT/spring-webapp.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 파일 실행
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/{내 루트 디렉토리 이름}"
JAR_FILE="$PROJECT_ROOT/spring-webapp.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
  • build.gradle 파일 수정(아래 코드 추가)
    • 빌드시 -plain.jar 파일이 생기지 않도록
jar{
		enable = false
}
  • Github Actions Workflow 작성
    • Simple workflow -> configure
    • deploy.yml 작성
# This is a basic workflow to help you get started with Actions

name: Deploy to Amazon EC2
# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "main" branch
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

env:
  AWS_REGION: ap-northeast-2
  S3_BUCKET_NAME: {내가 설정한 버킷명 이름}
  CODE_DEPLOY_APPLICATION_NAME: {내가 설정한 앱 이름}
  CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: {내가 설정한 그룹 이름}
  APPLICATION: ${{ secrets.APPLICATION }}

permissions:
  contents: read

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

    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        distribution: 'temurin'
        java-version: '11'
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew

    - uses: actions/checkout@v2
    - run: touch ./src/main/resources/application.yml
    - run: echo "${{env.APPLICATION}}" > ./src/main/resources/application.yml
    - uses: actions/upload-artifact@v2
      with:
        name: application.yml
        path: ./src/main/resources/application.yml

    - name: Build with Gradle
      uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
      with:
        arguments: clean build -x test

    - 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 }}

    - 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 .

    - 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
  • Commit, push 후 actions, codedeploy에서 배포 내역 확인하기

build Gradlew에서 execute permission 에러시

터미널에서

git update-index --chmod=+x./gradlew

하고 commit, push 하기