본문 바로가기
Spring boot

AWS EC2 & S3 & Code Deploy를 활용한 CD

by 리버🐦‍🔥 2024. 5. 8.

지난 포스팅 “AWS EC2인스턴스에 Spring Boot 서버 배포하기”에 연결되어 CD(Code Deploy, 자동 배포)를 하기 위한 포스팅이다. 이번에도 마찬가지로 실습 위주로 진행된다.

서버 배포 순서

  1. AWS에서 EC2 인스턴스 생성
  2. 탄력적 IP 설정
  3. 보안 그룹 설정
  4. SSH 클라이언트(iterm)으로 서버 접속
  5. SSH를 통해 EC2 인스턴스에 Spring Boot 서버 띄우기

CD(Code Deploy) 순서

  1. AWS EC2에 Tag 설정
  2. AWS EC2에 IAM 설정
  3. 서버에 CodeDeploy Agent 설치
  4. AWS S3 생성
  5. AWS CodeDeploy 전용 IAM 역할 생성
  6. AWS CodeDeploy Application 생성 및 배포 설정
  7. Github Actions의 사용자 권한 추가
  8. App Spec 작성
  9. 배포 스크립트(start.sh, stop.sh) 작성 & build.gradle 파일 수정
  10. Github Actions Workflow 작성
  11. Github에서 push로 배포 확인

자동 배포 방법

  1. Code Deploy를 활용해서 EC2에 배포 → S3 빌드파일 압축해서 업로드
  2. Task Definition을 활용해서 ECS에 배포 → ECR에 도커 이미지 업로드

본 포스팅에서는 AWS의 Code Deploy를 활용하는 방법을 통해 CD를 진행할 예정입니다.


1. AWS EC2에 Tag 설정

1. EC2 인스턴스 정보에서 태그 관리를 선택

2. 키 값을 입력하고 저장을 누른다.

3. 태그 설정 확인

 

2. AWS EC2에 IAM 설정

1. IAM 서비스 검색 및 이동

2. IAM 역할 관리 페이지에서 역할 생성

3. AWS 서비스, EC2 엔티티 선택

4. S3 접근 권한 추가

5. 역할 이름 설정 및 권한 확인 후 역할 생성

6. EC2 인스턴스에서 IAM 역할 수정

7. AWS 인스턴스 Ubuntu에 CodeDeploy Agent 설치

$ 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

(설치 완료)

4. AWS S3 생성 및 설정

1. S3 버킷 생성

2. 버킷 설정(버킷 이름, AWS 리전, ACL, 퍼블릭 액세스 차단, 버킷 버전 관리, 기본 암호화) 

3. 버킷 생성 완료

5. AWS CodeDeploy 전용 IAM 역할 생성

1. IAM으로 이동

2. IAM 역할 생성

3. AWS 서비스 → CodeDeploy 선택

4. 권한 정책 확인

5. 역할 이름 및 권한 정책 확인 후 역할 생성

6. IAM 역할 생성 성공

6. AWS CodeDeploy Application 생성 및 배포 설정

1. CodeDeploy로 이동

2. CodeDeploy 애플리케이션 생성

3. 애플리케이션 생성

4. CodeDeploy 배포 그룹 생성

5. 배포 그룹 설정

    a. 이름, 서비스 역할(IAM)

    b. 배포 유형, 환경 구성(인스턴스, 태그 그룹)

    c. 에이전트 구성, 배포 설정, 로드 밸런서

    d. 배포 그룹 생성 확인

7. Github Actions에서 사용할 IAM 사용자 권한 추가

1. IAM으로 이동

2. 사용자 생성

3. 사용자 이름 설정

4. 정책 추가(AWSCodeDeployFullAccess / AmazonS3FullAccess)

5. 정보 검토 후 사용자 생성

6. 사용자 생성 완료

7. 액세스 키 만들기

8. 액세스키 생성 성공

9. Github Repository의 Secrets access key 추가

8. App Spec 작성

Spring boot 프로젝트의 루트 디렉토리에 AppSpec 파일을 작성한다.

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

9. 배포 스크립트(start.sh, stop.sh) 작성 & build.gradle 파일 수정

1. start.sh

#!/usr/bin/env bash

PROJECT_ROOT="/home/ubuntu/app"
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

2. stop.sh

#!/usr/bin/env bash

PROJECT_ROOT="/home/ubuntu/app"
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

3. 루트 디렉토리/scripts 디렉토리에 start.sh와 stop.sh 쉘 스크립트를 작성

(appspec.yml파일 안에 hooks의 location과 동일한 위치에 스크립트를 작성해야한다.)

4. build.gradle 파일 수정
jar { 
	enabled = false 
}

10. Github Actions Workflow 작성

1. Github 레포지토리 → Actions에서 New Workflow 작성

2. Simple workflow 선택 후 수정

 name: Deploy to Amazon EC2

 on:
   push:
     branches:
       - main

 # 본인이 설정한 값을 여기서 채워넣습니다.
 # 리전, 버킷 이름, CodeDeploy 앱 이름, CodeDeploy 배포 그룹 이름
 env:
   AWS_REGION: ap-northeast-2
   S3_BUCKET_NAME: liver-github-actions-s3-bucket
   CODE_DEPLOY_APPLICATION_NAME: soongies-codedeploy-application
   CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: soongies-codedeploy-deployment-group

 permissions:
   contents: read

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

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

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

     # (3) Gradle build (Test 제외)
     - name: Build with Gradle
       uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
       with:
         arguments: clean build -x test # 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

여기서 중요한 부분은 

CODE_DEPLOY_APPLICATION_NAME: soongies-codedeploy-application
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: soongies-codedeploy-deployment-group

꼭 본인의 CodeDeploy의 설정에 맞춰서 작성해야 한다.

💡 자세한 내용은 “https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/application-revisions-push.html” 공식문서 참조

11. Github에서 push로 배포 확인

CI/CD 성공