[9장] 코드가 푸시되면 자동으로 배포해 보자

미천한 개발중생·2023년 10월 9일
0
post-thumbnail

앞 장에서는 스크립트를 작성하여 스프링 부트 프로젝트를 EC2에 배포하였습니다. 하지만 이 방식은 몇 가지 문제가 있습니다.

  1. 수동 실행되는 Test
    본인이 짠 코드가 다른 개발자의 코드에 영향을 끼치지 않는지 확인하기 위해 전체 테스트를 수행해야 합니다. 하지만 현재 상태에서는 작업을 진행할 때마다 수동으로 전체 테스트를 수행해야 합니다.

  2. 수동 Build
    다른 사람이 작성한 브랜치와 본인이 작성한 브랜치가 합쳐졌을 때 이상이 없는지 Build를 해야만 알 수 있습니다.

CI & CD

  • CI : 코드 버전 관리를 하는 VCS 시스템(Git, SVN 등)에 Push가 되면 자동으로 테스트와 빌드가 수행되어 안정적인 배포 파일을 만드는 과정
  • CD : CI의 빌드 결과를 자동으로 운영 서버에 무중단 배포까지 진행되는 과정

탄생배경

현대의 웹 서비스 개발에서는 하나의 프로젝트를 여러 개발자가 함께 개발을 진행합니다. 그러다 보니 각자의 코드를 합쳐야 하고 이런 수작업 때문에 생산성이 좋지 못해 개발자들은 CI를 구축하게 됬습니다.
CD의 경우도 마찬가지로, 한 두대의 서버는 괜찮지만 수십 대 수백 대의 서버에 배포를 하거나 긴박하게 당장 배포를 해야 하는 상황이 오면 더는 수동으로 배포할 수 없기때문에 이런 과정들을 자동화하게 되었습니다.

CI의 4가지 규칙

  • 모든 소스 코드가 살아 있고 누구든 현재의 소스에 접근할 수 있는 단일 지점을 유지할 것
  • 빌드 프로세스를 자동화해서 누구든 소스로부터 시스템을 빌드하는 단일 명령어를 사용할 수 있게 할 것
  • 테스팅을 자동화해서 단일 명령어로 언제든지 시스템에 대한 건전한 테스트 수트를 실행할 수 있게 할 것
  • 누구나 현재 실행 파일을 얻으면 지금까지 가장 완전한 실행 파일을 얻었다는 확신을 하게 할 것

여기서 중요한 것은 테스팅 자동화로, 지속적으로 통합하기 위해서는 이 프로젝트가 완전한 상태임을 보장하기 위해 테스트 코드가 구현되어 있어야만 합니다.


Github Action 연동

책에서 실습하는 Travis CI의 경우 현재는 유료화 되었습니다. 무료 계정으로도 사용할 수 있지만 신용카드를 등록해야 하는 번거로움과 1달 이후 유료로 전환이 되는 문제가 있어 Github Action을 연동하여 진행하겠습니다. 관련하여 자세한 내용은 여기에 잘 정리가 되어있습니다. 이 게시물은 책의 내용과 해당 글을 참고하여 재정리 하였습니다.

본인의 레포지토리에서 [Actions 탭] -> [Publish Java Package with Gradle] -> [Configure] 을 클릭합니다.

gradle-publish.yml 파일의 양식이 자동으로 생성되며, 다음과 같이 작성해 줍니다.

name: springboot-aws-Deploy

on:
  release:
    types: [push]
  push:
    branches: [master]
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
    - name: CheckOut
      uses: actions/checkout@v3
      
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'

    - name: Grant execute permission for gradlew
      run: chmod +x ./gradlew
      shell: bash

    - name: Build with Gradle
      run: ./gradlew clean build -x test
      shell: bash

name: springboot-aws-Deploy

  • Github Actions에서 보여질 이름을 지정합니다.

on: release: types: [push]

  • Action을 실행하게 할 방법을 지정합니다.

push:branches: [master]

  • 현재 만드는 Github Action의 브랜치를 지정합니다.

workflow_dispatch:

  • 수동으로도 실행이 가능합니다.

jobs: build: runs-on: ubuntu-latest

  • 해당 스크립트가 작동될 OS 환경을 지정합니다.

uses: actions/checkout@v3

  • 프로젝트 코드를 Check Out 합니다.

uses: actions/setup-java@v1

  • Github Action이 실행될 OS에 Java를 설치합니다.

run: chmod +x ./gradlew

  • gradle wrapper를 실행할 수 있도록 실행 권한을 줍니다.

run: ./gradlew clean -x test build

  • gradle wrapper를 통해 해당 프로젝트를 build 합니다.

작성이 끝났으면 commit 후 Action 탭에서 확인합니다.

당장은 Action을 사용하지 않기 때문에 사용하지 않는 Action은 바로 삭제합니다. 프리 요금제의 경우 1달에 2000시간을 초과시 사용이 제한됩니다.

AWS S3 연동

S3란 AWS에서 제공하는 일종의 파일 서버입니다. 이미지 파일을 비록한 정적 파일들을 관리하거나 지금 진행하는 것처럼 배포 파일들을 관리하는 등의 기능을 지원합니다.

실제 배포는 AWS CodeDeploy를 이용하지만 빌드없이 배포만 필요할 때 대응하기 어렵습니다. 빌드와 배포가 분리되어 있으면 예전에 빌드한 Jar를 재사용할 수 있습니다. 하지만 CodeDeploy가 모든 것을 하게 될 땐 항상 빌드를 하게 되니 확장성이 떨어집니다.

AWS Key 발급

AWS 서비스에는 외부 서비스가 접근할 수 없기때문에 접근 가능한 권한을 가진 Key를 생성해서 사용해야 합니다. AWS에는 이러한 인증과 관련된 기능을 제공하는 서비스인 IAM이 있습니다.

AWS 검색창에 IAM을 검색하여 이동 후 왼쪽 메뉴에서 [사용자] -> [사용자 생성]을 클릭합니다.

사용자 이름을 입력 후 다음을 클릭합니다.

직접 정책 연결을 선택하고 s3full과 CodeDeployFull 권한을 검색하여 추가합니다.

본인이 생성한 권한 설정 항목을 확인후, 태그는 본인이 인지할 수 있는 이름으로 생성합니다.

사용자 생성 후 생성한 사용자 이름을 클릭하여 세부정보로 이동합니다. 요약 부분에 액세스 키 만들기를 클릭합니다.

AWS 외부에서 실행되는 애플리케이션을 선택 후 [다음] -> [액세스 키 만들기]를 클릭합니다.

액세스 키가 생성된 것을 확인합니다.

액세스 키는 이 화면에서만 확인할 수 있기 때문에 다운로드를 받거나 메모장에 복사하여 잘 보관하도록 합니다.

Github Action에 키 등록

프로젝트 Repository에서 [Settings] -> [Secrets and Variables] -> [Actions]로 이동합니다.

New repository secret을 클릭하여 시크릿을 생성합니다.
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY 두가지를 생성합니다.
Secret 칸에는 아까 확인한 액세스 키를 각각 입력합니다.

생성 후 해당 Repository의 Code에서 .github/workflows 로 이동해 아까 생성한 yml 파일을 열어줍니다.

Action에서의 날짜는 실제 우리가 빌드한 날짜와 다르게 되어있기 때문에 이 부분을 추가합니다.

	...

    - name: Get current time
      uses: 1466587594/get-current-time@v2  # (9)
      id: current-time
      with:
        format: YYYY-MM-DDTHH-mm-ss 
        utcOffset: "+09:00"

    - name: Show Current Time
      run: echo "CurrentTime=${{steps.current-time.outputs.formattedTime}}" # (10)
      shell: bash

uses: 1466587594/get-current-time@v2

해당 action의 기준이 UTC이므로 한국 시간대인 KST로 진행하기 위해 offset에 +09:00을 해줍니다.

run: echo "CurrentTime=${{steps.current-time.outputs.formattedTime}}"

저장한 후 Action으로 이동해 확인합니다. 이후 Action을 삭제합니다.

S3 버킷 생성

AWS의 S3 서비스는 순수하게 파일들을 저장하고 접근 권한을 관리, 검색 등을 지원하는 파일 서버의 역할을 합니다. S3는 보통 게시글을 쓸 때 나오는 첨부파일 등록을 구현할 때 많이 이용합니다.

AWS 검색창에 S3를 검색하여 이동합니다.

왼쪽 메뉴바에서 [버킷] -> [버킷 만들기] 를 클릭합니다.

버킷 이름을 작성 후 다른 설정은 변경하지 않고 하단의 [버킷 만들기] 를 클릭합니다.

yml에 추가

yml 파일에 다음 코드를 추가합니다.

최상단 부분
---------- 추가된 부분 ----------
env:  
  S3_BUCKET_NAME: 내가 설정한 S3 버킷명
  PROJECT_NAME: 내 Github 프로젝트 이름
  
  ...(중간 생략)
  
최하단 부분

    - name: Show Current Time
      run: echo "CurrentTime=${{steps.current-time.outputs.formattedTime}}"
      shell: bash
      
   ---------- 추가된 부분 ----------
   - name: Make zip file
      run: zip -r ./$PROJECT_NAME.zip .
      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 ./$PROJECT_NAME.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$PROJECT_NAME.zip

env

환경 변수를 이름 : 값 으로 지정합니다. 자주 사용되거나, 변경될 수 있는 부분은 환경 변수로 지정하면 편하게 사용할 수 있습니다.

run: zip -r ./$PROJECT_NAME.zip .

프로젝트 이름으로 해당 폴더를 모두 압축 시킵니다.

uses: aws-actions/configure-aws-credentials@v1

aws에 해당 키 값으로 접속을 진행합니다.

run: aws s3 cp --region ap-northeast-2 ...

s3에 프로젝트 이름에 해당하는 폴더에 zip파일을 저장합니다.

추가한 뒤 Action에서 정상적으로 빌드된 것을 확인 후 S3에 해당 압축 파일이 들어있는 것을 확인할 수 있습니다.


GitHub Action과 AWS S3, CodeDeploy 연동하기

CodeDeploy를 이용하기 전에 배포 대상인 EC2가 CodeDeploy를 연동 받을 수 있게 IAM 역할을 생성하겠습니다.

IAM 사용자와 역할의 차이

  • 역할
    • AWS 서비스에서만 할당할 수 있는 권한
    • EC2, CodeDeploy, SQS 등
  • 사용자
    • AWS 서비스 외에 사용할 수 있는 권한
    • 로컬 PC, IDC 서버 등

지금 생성하는 권한은 EC2에서 사용할 것이기 때문에 사용자가 아닌 역할로 처리합니다.

EC2에 IAM 역할 추가하기

AWS 에서 IAM -> [역할 탭] -> [역할 만들기] 를 클릭합니다.

엔터티 유형은 AWS 서비스, 사용사례는 EC2를 선택합니다.

권한 정책 검색에 Ec2RoleForA 를 검색하여 AmazonEC2RoleforAWSCodeDeploy 를 선택합니다.

역할 이름과 태그를 입력하고 역할을 생성합니다.

생성한 역할을 EC2 서비스에 등록하겠습니다. EC2 인스턴스 목록에서 본인의 인스턴스 마우스 우클릭 후 [보안] -> [IAM 역할 수정]을 클릭합니다.

방금 생성한 역할을 선택하고 업데이트 한 뒤, EC2 인스턴스를 재부팅합니다.

CodeDeploy 에이전트 설치

EC2에 접속하여 다음 명령어를 입력합니다.

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

내려받기가 성공했다면 다음과 같은 메세지가 콘솔에 출력됩니다.

download: s3://aws-codedeploy-ap-northeast-2/latest/install to ./install

install 파일에 실행 권한을 추가 후 설치를 진행합니다.

chmod +x ./install
sudo ./install auto

혹시 다음과 같은 메세지가 나온다면

/usr/bin/env: ruby: No such file or directory

루비가 설치되있지 않아서 나오는 오류이니 다음 명령어로 루비를 설치 후 다시 install 합니다.

sudo yum install ruby

설치가 끝났으면 Agent가 정상적으로 실행되는지 상태 검사를 합니다.

sudo service codedeploy-agent status

다음과 같이 running 메세지가 출력되면 정상입니다.

The AWS CodeDeploy agent is running as PID xxx

CodeDeploy를 위한 권한 생성

마찬가지로 CodeDeploy에서 EC2에 접근하기위해 권한이 필요합니다. IAM을 생성하고 서비스는 [AWS 서비스] -> [CodeDeploy] 를 선택합니다.

권한 추가는 따로 하지않고 넘어갑니다. 이름과 태그를 설정 후 역할을 생성합니다.

CodeDeploy 생성

CodeDeploy는 AWS의 배포 서비스중 하나입니다.

  • Code Commit
    • 깃허브와 같은 코드 저장소의 역할을 합니다.
    • 프라이빗 기능을 지원한다는 강점이 있지만, 현재 깃허브에서 무료로 프라이빗 지원을 하고 있어서 거의 사용되지 않습니다.
  • Code Build
    • Travis CI와 마찬가지로 빌드용 서비스입니다.
    • 멀티 모듈을 배포해야 하는 경우 사용해볼만하지만, 규모가 있는 서비스에서는 대부분 젠킨스/팀시티 들을 이용하니 사용할 일이 거의 없습니다.
  • Code Deploy
    • AWS의 배포 서비스이며 다른 서비스들과 달리 대체제가 없습니다.
    • 오토 스케일링 그룹 배포, 블루 그린 배포, 롤링 배포, EC2 단독 배포 등 많은 기능을 지원합니다.

현재 진행중인 프로젝트에서는 Code Commit의 역할은 깃허브가, Code Build의 역할은 GitHub Action이 하고있습니다. 마지막 단계인 CodeDeploy를 사용하도록 하겠습니다.

AWS 검색창에 CodeDeploy를 검색하여 이동 후 [애플리케이션] -> [애플리케이션 생성] 을 클릭합니다.

이름과 플랫폼을 설정합니다. 컴퓨팅 플랫폼은 [EC2/온프레미스] 를 선택합니다.

애플리케이션을 생성하면 배포 그룹을 설정하라는 메세지가 나옵니다. 배포 그룹 생성 버튼을 클릭합니다.

그룹 이름과 서비스 역할을 등록합니다. 서비스 역할은 아까 생성한 CodeDeploy용 역할을 선택합니다. 배포유형은 본인이 배포할 서비스가 2대 이상일 때만 블루/그린을 선택하면 됩니다. 여기선 1대의 EC2만 배포하므로 현재 위치를 선택합니다.

환경 구성은 Amazon EC2 인스턴스를 선택합니다. 키와 값은 클릭 시 EC2의 태그를 선택하면 됩니다.

배포 구성은 기본값으로 두고 로드 밸런서의 체크를 해제합니다.

배포 구성이란

배포 구성이란 한번 배포할 때 몇 대의 서버에 배포할지를 결정합니다. 2대 이상이라면 1대씩 배포할지, 30% 혹은 50%로 나눠서 배포할지 등등 옵션을 선택합니다.

GithubAction, S3, CodeDeploy 연동

EC2에 접속하여 S3에서 넘겨줄 zip 파일을 저장할 디렉토리를 생성합니다.

mkdir ~/app/step2 && mkdir ~/app/step2/zip

GitHub Action의 빌드가 끝나면 S3에 zip 파일이 전송되고, 이 파일은 해당 경로에 복사되어 압축을 풉니다.

CodeDeploy의 설정을 위해 appspec.yml 파일을 프로젝트 최상단에 생성 후 다음 코드를 추가합니다.

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/app/step2/zip/ 
file_exists_behavior: OVERWRITE

version: 0.0

  • CodeDeploy 버전을 뜻합니다.
  • 프로젝트 버전이 아니므로 0.0외에 다른 버전을 사용하면 오류가 발생합니다.

source

  • CodeDeploy에서 전달해 준 파일 중 destination으로 이동시킬 대상을 지정합니다.
  • 루트 경로를 지정하면 전체 파일을 뜻합니다.

destination

  • source에서 지정된 파일을 받을 위치입니다.
  • 이후 Jar을 실행하는 등은 destination에서 옮긴 파일들로 진행됩니다.

file_exists_behavior

  • CodeDeploy가 배포 대상 위치에 이미 존재하지만 이전에 성공한 배포의 일부가 아닌 파일을 처리하는 방식을 지정합니다.
  • 책에서 사용한 overwrite: yes 옵션이 오류가 발생하여 대신 사용합니다. 자세한 내용은 AWS 공식문서를 참고하세요.

gradle-publish.yml 파일에도 CodeDeploy 내용을 추가합니다.

env: 
  S3_BUCKET_NAME: ward-build
  PROJECT_NAME: aws-web-service
  CODE_DEPLOY_APP_NAME: CodeDeploy 애플리케이션 이름 
  CODE_DEPLOY_GROUP_NAME: CodeDeploy 배포그룹 이름

name: deploy

	...

    - 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 ./deploy/$PROJECT_NAME.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$PROJECT_NAME.zip

    - name: Code Deploy
      run: aws deploy create-deployment --application-name $CODE_DEPLOY_APP_NAME --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name $CODE_DEPLOY_GROUP_NAME --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$PROJECT_NAME.zip

코드를 추가했으면 커밋 앤 푸시합니다.

깃허브의 Action에서 빌드가 성공한 것을 확인합니다.

AWS의 CodeDeploy에서 [배포] 를 클릭하여 이동하면 배포가 성공한 것을 확인할 수 있습니다.

EC2로 접속해 파일을 확인합니다.

cd /home/ec2-user/app/step2/zip
ll

다음과 같이 프로젝트 파일이 있는것을 확인할 수 있습니다.


배포 자동화 구성

배포 자동화 구성 전, 새로운 파일이 commit되면 이전 버전은 중단시킨 후 업데이트 된 jar을 실행하기 위해 먼저 pid commend값을 설정해야합니다.

application.properties에 다음 코드를 추가합니다.

spring.pid.file=/home/ec2-user/app/step2/본인 프로젝트 명.pid 

Application 클래스를 다음과 같이 수정합니다.

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application.class);
        application.addListeners(new ApplicationPidFileWriter());
        application.run(args);
    }
}

step2 환경에서 실행될 deploy.sh를 생성합니다. 프로젝트 최상단에 scripts 디렉토리를 생성 후 그 안에 deploy.sh를 생성 후 다음 코드를 추가합니다.

#!/bin/bash

REPOSITORY=/home/ec2-user/app/step2
PROJECT_NAME=내 프로젝트 명

echo "> Build 파일 복사"
cp $REPOSITORY/zip/*.jar $REPOSITORY/

echo "> 현재 구동 중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -f $PROJECT_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 $JAR_NAME

echo "> $JAR_NAME 실행"
nohup java -jar \
  -Dspring.config.location=classpath:/application.properties,/home/ec2-user/app/application-oauth.properties,/home/ec2-user/app/application-real-db.properties \
  -Dspring.profile.active=real \
  $JAR_NAME > $REPOSITORY/nohup.out 2>&1 &

CURRENT_PID

  • 현재 수행중인 스프링 부트 애플리케이션의 프로세스 ID를 찾습니다.

chmod +x $JAR_NAME

  • Jar 파일은 실행 권한이 없는 상태이기 때문에 nohup으로 실행할 수 있게 권한을 부여합니다.

$JAR_NAME > $REPOSITORY/nohup.out 2>&1 &

  • nohup 실행 시 CodeDeploy는 무한 대기합니다.
  • 이 이슈를 해결하기 위해 nohup.out을 표준 입출력용으로 별도로 사용합니다.
  • 이렇게 하지 않으면 nohup.out 파일이 생기지 않고, CodeDeploy 로그에 표준 입출력이 출력됩니다.

appspec.yml 에도 코드를 추가합니다.

permissions:
  - object: /
    pattern: "**"
    owner: ec2-user
    group: ec2-user

hooks:
  ApplicationStart:
    - location: deploy.sh
      timeout: 60
      runas: ec2-user

permissions

  • CodeDeploy에서 EC2 서버로 넘겨준 파일들을 모두 ec2-user 권한을 갖도록 합니다.

hooks

  • CodeDeploy 배포 단계에서 실행할 명령어를 지정합니다.
  • ApplicationStart라는 단계에서 deploy.sh를 ec2-user 권한으로 실행하게 합니다.
  • time-out : 60으로 스크립트 실행 60초 이상 수행되면 실패가 됩니다.(무한정 기다릴 수 없으니 시간 제한을 둬야합니다.)

gradle-publish.yml도 수정합니다.

env:
  S3_BUCKET_NAME: springboot-aws-build
  PROJECT_NAME: springboot-aws
  CODE_DEPLOY_APP_NAME: springboot-aws
  CODE_DEPLOY_GROUP_NAME: springboot-aws-group

name: springboot-aws-Deploy

on:
  release:
    types: [ push ]
  push:
    branches: [ master ]
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

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

      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'temurin'

      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew
        shell: bash

      - name: Build with Gradle
        run: ./gradlew clean -x test build
        shell: bash

      - name: Get current time
        uses: 1466587594/get-current-time@v3
        id: current-time
        with:
          format: YYYY-MM-DDTHH-mm-ss
          utcOffset: "+09:00"

      - name: Show Current Time
        run: echo "CurrentTime=${{steps.current-time.outputs.formattedTime}}"
        shell: bash

      - name: Generate deployment package
        run: |
          mkdir -p before-deploy
          cp scripts/*.sh before-deploy/
          cp appspec.yml before-deploy/
          cp build/libs/*.jar before-deploy/
          cd before-deploy && zip -r before-deploy *
          cd ../ && mkdir -p deploy
          mv before-deploy/before-deploy.zip deploy/$PROJECT_NAME.zip
        shell: bash

      - name: Make zip file
        run: zip -r ./$PROJECT_NAME.zip .
        shell: bash

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v3
        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 ./deploy/$PROJECT_NAME.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$PROJECT_NAME.zip  #(14)

      - name: Code Deploy
        run: aws deploy create-deployment --application-name $CODE_DEPLOY_APP_NAME --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name $CODE_DEPLOY_GROUP_NAME --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$PROJECT_NAME.zip

모든 설정이 완료되었다면 깃허브에 커밋과 푸시를 진행합니다.

EC2에 접속하여 pid를 조회합니다.

pgrep -f 프로젝트 명

kill pid 명령어로 해당 프로세스를 종료합니다.

기존의 깃허브 Action을 모두 삭제하고 수동으로 Action을 실행합니다.

정상적으로 빌드가 된 것을 확인합니다.

웹 브라우저에 EC2 도메인 입력 후 확인합니다.

index.mustache에서 Ver. 의 숫자를 바꿉니다.

<h1>스프링 부트로 시작하는 웹 서비스 Ver.final</h1>

IndexControllerTest의 코드도 수정합니다.

	...
    
 @Test
    public void 메인페이지_로딩() {
        //when
        String body = this.restTemplate.getForObject("/", String.class);

        //then
        assertThat(body).contains("스프링 부트로 시작하는 웹 서비스 Ver.final");
    }

변경 후 커밋과 푸시를 진행하고 Action에서 빌드가 완료된 후 브라우저에서 재접속 하면 변경된 사항이 반영된 것을 확인할 수 있습니다.


CodeDeploy 로그 확인

CodeDeploy에 관한 대부분의 내용은 /opt/codedeploy-agent/deployment-root에 있습니다. 해당 디렉토리로 이동한 뒤 목록을 확인하면 다음과 같은 내용을 확인할 수 있습니다.

  • 최상단의 영문과 - 가 있는 디렉토리 명은 CodeDeploy ID 입니다.
    • 사용자마다 고유한 ID가 생성되어 각자 다른 ID가 발급되니 본인의 서버에는 다른 코드로 되어있습니다.
    • 해당 디렉토리로 들어가 보면 배포한 단위별로 배포 파일들이 있습니다.
    • 본인의 배포 파일이 정상적으로 왔는지 확인해 볼 수 있습니다.
  • deployment-logs
    • CodeDeploy 로그 파일입니다.
    • CodeDeploy로 이루어지는 배포 내용 중 표준 입/출력 내용은 모두 여기에 담겨있습니다.
    • 작성한 echo 내용도 모두 표기됩니다.
profile
공부 목적의 블로그 입니다. 부족한 점이 많으니 잘못된 정보가 있다면 지적부탁드려요!

0개의 댓글