본문 바로가기

Infra

[우당탕탕 개발 일지] Github Action과 CodeDeploy로 SpringBoot CICD 세팅하기

반응형
SMALL

새로운 프로젝트를 슬슬 시작하는 과정에 있다. 편리함을 위해 이번 프로젝트에서는 CICD 도입을 맡게 되었다. 스프링 부트 기반의 프로젝트를 CICD 연결했던 과정을 기록해보겠다!

 

더보기

준비물

- 스프링부트 기반 프로젝트

- 깃허브 액션

- AWS Code Deploy

- AWS EC2

 

 

GitHub - prgrms-web-devcourse/Team-06-Final-BE

Contribute to prgrms-web-devcourse/Team-06-Final-BE development by creating an account on GitHub.

github.com

위 레포지토리를 CICD 연결했다!

 

CI (Continuous Integration)

지속적 통합은 새로운 코드의 변경 사항이 정기적으로 빌드 및 테스트 되어 한 레포지토리에서 통합되는 것을 의미한다. 협업을 진행할 때 코드  충돌을 방지할 수 있기 때문에 효율적으로 작업을 진행할 수 있도록 해준다.

 

CI는 깃허브 액션으로 빠르고 쉽게 세팅할 수 있다.

 

프로젝트의 루트에서 .github/workflows/deploy.yml 파일을 생성해준다.

name: deploy

on:
  push:
    branches: [ develop ]
  pull_request:
    branches: [ develop ]

jobs:
  build:
    runs-on: ubuntu-22.04

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

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

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

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

develop 브랜치로 push 또는 pull_request 할 때 위 deploy.yml 파일이 실행된다. CI 단계에서는 java 세팅, 권한 부여, 빌드 과정이 이루어진다.

 

파일을 생성했으면 commit하고, develop 브랜치로 push 하거나 push한 다른 브랜치에서 develop 브랜치로 PR을 날리면 CI가 정상적으로 진행되는 지 확인할 수 있다.

 

위와 같은 화면이 보이면 아주 잘 되고 있는 것이다!

 

CD (Continuous Deployment)

지속적 배포는 새로운 코드의 변경 사항이 레포지토리를 넘어서 프로덕션 환경까지 릴리즈 되는 것을 의미한다. 특정 브랜치에 PR 또는 push 하기만 하면 자동으로 배포해주니, 수동으로 배포해야하는 상황과 비교해서 훨씬 편리함을 제공한다.

 

CD는 다음과 같은 과정이 필요하다.

1. CodeDeploy 생성

2. EC2 작업 (java 및 codedeploy-agent) 설치

3. 관련 코드 추가

 

CodeDeploy 생성

AWS에서 CodeDeploy를 생성해야 한다. 이는 AWS에서 제공하는 배포 서비스로, CodeDeploy를 통해서 EC2에 자동 배포해준다.

 

CodeDeploy IAM 역할 생성

먼저 CodeDeploy 접근 권한이 있는 역할이 필요하다. IAM > 역할 > 역할 만들기 로 들어가 역할을 생성해주자.

 

1단계 신뢰할 수 있는 엔티티 선택. AWS 서비스와 사용 사례에서 CodeDeploy를 선택하고 다음으로 넘어간다.

 

2단계는 권한 정책을 확인하고 별다른 행위 없이 바로 3단계로 넘어가면 된다.

 

3단계 이름 지정, 검토 및 생성. 역할 이름을 부여해주고 세부 사항을 검토한 후 역할 생성을 클릭해준다.

 

정상적으로 생성되었다면, IAM > 역할에서 방금 생성한 역할을 확인할 수 있다.

 

 

CodeDeploy 애플리케이션 생성

다음으로 애플리케이션을 생성해주어야 한다. CodeDeploy > 애플리케이션 > 애플리케이션 생성 으로 들어가자.

 

애플리케이션 이름컴퓨팅 플랫폼을 EC2/온프레미스로 지정해주고 애플리케이션을 생성한다.

 

마찬가지로 잘 생성되었으면 CodeDeploy > 애플리케이션에서 생성된 애플리케이션을 확인할 수 있다.

 

배포 그룹 생성

이어서 배포 그룹이 필요하다. 생성한 애플리케이션에 들어가서 배포 그룹 생성을 클릭해주자.

 

배포 그룹 이름을 지정해주고, 서비스 역할에는 위에서 생성한 IAM codedeploy 역할을 선택해준다.

 

단일 인스턴스에 배포한다는 가정 하에, Amazon EC2 인스턴스를 선택하고, 태그 그룹에서 키와 값을 선택해준다. (여기서 키 값은 배포할 EC2이다.)

 

나머지는 그래도 두고 배포 그룹을 생성해준다.

 

 

EC2 설정

이제 배포할 EC2에 권한을 부여하고, 접속하여 몇가지 설치를 진행해주어야 한다.

 

IAM 역할 생성

EC2에 부여할 역할을 생성하자.

 

다시 IAM > 역할 > 역할 만들기 로 들어가준다.

 

AWS 서비스EC2를 선택한다.

 

AWSCodeDeployFullAccess AmazonS3FullAccess 권한을 선택한다.

 

 

역할 이름을 지정하고 역할을 생성해준다.

 

EC2 > 인스턴스로 들어가자.

 

EC2 역할 수정

EC2에게 권한을 부여해주어야 한다. 배포할 EC2를 선택하고, 작업 > 보안 > IAM 역할 수정을 클릭해주자.

 

IAM 역할 수정에서 위에서 생성한 역할을 선택해준다. 선택 후, IAM 역할 업데이트 해준다.

 

이제 EC2로 접속하자. 우분투 22.04 기준이다.

 

Java 설치

sudo apt install openjdk-17-jdk

위 코드로 자바를 설치하자. JDK 17이 필요해서 17 버전으로 설치했다. 이미 설치되어 있어서 위 이미지처럼 나오지만, 대충 됐다는 로그가 뜨면 성공이다.

 

java --version

코드로 자바 버전을 확인해서, 버전이 출력되면 잘 설치된 것이다!

 

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

위 명령어를 입력하여 codedeploy-agent를 설치해준다.

 

$ sudo service codedeploy-agent status
$ sudo service codedeploy-agent restart

위 명령어로 codedeploy-agent가 제대로 설치되었는 지 확인한다. status로 상태를 확인하고, 실행 중이지 않으면 restart 명령어를 입력해주면 된다.

 

* 위 과정을 실패한다면 *

$ wget https://aws-codedeploy-ap-northeast-2.s3.amazonaws.com/latest/install

먼저 위 명령어에서 wget 명렁어를 다음과 같이 입력하고, 아래 과정을 그대로 다시 진행한다.

 

그래도 안돼면

일단 당시 배포 과정에서는 위 codedeploy-agent가 제대로 설치되지 않았었다. 그래서 구글링 끝에 한 포스팅을 따라 보고 입력했는데, codedeploy-agent를 성공적으로 설치할 수 있었다. 해당 글을 밑에서 공유하도록 하겠다.

https://stackoverflow.com/questions/73301858/aws-codedeploy-agent-not-installing-on-ubuntu-22-04

 

AWS CodeDeploy agent not installing on ubuntu 22.04

I tried installing codedeploy agent on ubuntu 22.04 but not working. I have installed ruby 2.6.0 via rbenv. ubuntu@ip-172-31-37-7:~$ sudo ./install --sanity-check deb I, [2022-08-10T06:26:28.905059 #

stackoverflow.com

 

여기까지 왔으면 CodeDeploy 및 EC2 설정은 끝났다!!

 

CD 설정

이제 진짜진짜 CD 과정을 세팅해보도록 하자.

 

사용자 추가

배포 자동화를 위해서 S3부터 CodeDeploy 까지 접근 가능한 사용자가 필요하자. IAM > 사용자 > 사용자 추가로 들어가자. (이미 접근 가능한 사용자가 있으면 생략해도 좋다)

 

 

사용자 이름을 지정한다.

 

다음으로 넘어가 직접 정책 연결을 선택하고, AWSCodeDeployFullAccess와 AmazonS3FullAccess 권한을 추가해준다.

 

이후로는 정책 검토 후 계속 넘어가서 사용자 추가를 클릭해주면 된다. 사용자를 추가하면 최초로 Access Key Id와 Secret Access Key를 받을 수 있다. 해당 페이지를 넘어가면 다시는 재발급 받을 수 없으니 복붙 해놓거나 CSV를 저장해두자. 꼭!!

 

정상적으로 추가된 것은 사용자 리스트에서 확인할 수 있다.

 

발급 받은 Access Key를 깃허브 시크릿 키에 등록시킨다.

 

Settings > Security > Secrets and variables > Actions 탭으로 접속하면 된다. New repository secret 버튼을 클릭하여 2개의 access key를 등록해주면 된다.

 

S3 생성

CodeDeploy에서 배포하기 위해서는 빌드한 압축파일을 S3에 업로드 후 배포할 수 있다. 때문에 S3가 필요하다.

 

S3 > 버킷 > 버킷 만들기로 접속하자.

 

버킷 이름을 지정하고 리전만 확인하고 바로 버킷을 생성해주자.

 

 

코드 추가

마지막 단계이다. 이제 배포를 실행할 명령어가 담긴 파일을 생성해준다.

 

.github/workflows/deploy.yml

name: deploy

on:
  push:
    branches: [ develop ]
  pull_request:
    branches: [ develop ]

jobs:
  build:
    runs-on: ubuntu-22.04

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

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

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

      - name: Build with Gradle
        run: ./gradlew build
        shell: bash
      
     ## 추가 ##

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

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1-node16
        with:
          aws-access-key-id: ${{ secrets.ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.ACCESS_KEY_SECRET }}
          aws-region: ap-northeast-2

      - name: Upload to AWS S3
        run: |
          aws deploy push \
            --application-name {애플리케이션_이름} \
            --ignore-hidden-files \
            --s3-location s3://{버킷_이름}/$GITHUB_SHA.zip \
            --source .

      - name: Code Deploy
        run: aws deploy create-deployment --application-name {애플리케이션_이름}
          --deployment-config-name CodeDeployDefault.AllAtOnce
          --deployment-group-name {배포그룹_이름}
          --s3-location bucket={버킷_이름},bundleType=zip,key=$GITHUB_SHA.zip

앞서 생성한 deploy.yml 파일에 deploy 관련 코드를 추가해준다.

Make zip file: 빌드한 파일을 압축한다. $GITHUB_SHA로 랜덤한 이름을 생성한다.

Configure AWS credentials: AWS에 인증하는 과정이다. 깃허브 시크릿 키에 등록한 값인 access key 정보 값을 들고온다.

Upload to AWS S3: 압축한 빌드 파일을 S3 버킷에 업로드 한다.

Code Deploy: CodeDeploy를 실행한다.

 

 

appspec.yml

version: 0.0
os: linux

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

permissions:
  - object: /home/ubuntu
    pattern: '**'
    owner: ubuntu
    group: ubuntu

hooks:
  AfterInstall:
    - location: scripts/deploy.sh
      timeout: 1000
      runas: ubuntu

배포 후 배포 과정 명령어가 포함된 파일을 실행하도록 하는 파일이다.

/hom/ubuntu/build 위치에 파일 생성, 권한 부여, 배포 파일 실행 과정이 포함되어 있다.

 

 

scripts/deploy.sh

REPOSITORY=/home/ubuntu/build
cd $REPOSITORY

APP_NAME=pearls
JAR_NAME=$(ls $REPOSITORY/build/libs/ | grep '.jar' | tail -n 1)
JAR_PATH=$REPOSITORY/build/libs/$JAR_NAME

CURRENT_PID=$(pgrep -f $APP_NAME)

if [ -z $CURRENT_PID ]
then
  echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
  echo "> kill -15 $CURRENT_PID"
  sudo kill -15 $CURRENT_PID
  sleep 5
fi

echo "> $JAR_PATH 배포"
nohup java -jar /home/ubuntu/build/build/libs/pearls-1.0.jar > /dev/null 2> /dev/null < /dev/null &

배포 명령어 파일을 생성해준다. pearls-1.0.jar 파일로 빌드되기 때문에, 앱 이름과 jar 이름은 위와 같이 지정해주었다.

 

 

이제 develop으로 push 하거나 pull_request를 날려보자!!

 

 

위에서 CI 과정을 확인한 방식과 같은 방식으로 확인하면 된다. 정상적으로 실행되었으면 초록색 체크가 이쁘게 보일 것이다 :D

 

다음으로 AWS의 CodeDeploy > 배포에 들어가면 배포 내역을 확인할 수 있다. 최상단에 배포 내역이 성공 상태이면 잘 배포된 것이다.

 

 

혹시 배포까지 완료됐는데 EC2 IP 접속이 안된다면?

EC2의 보안 그룹에서 인바인드 규칙에서 접근하려는 포트 번호와 ip주소가 허용되어있는지 확인하해보자. 아마 접속이 안돼면 이 경우일 확률이 매우 높다. 허용되어 있지 않다면 인바인드 규칙 편집으로 들어가서 접속 허용하려는 ip 주소를 추가해주자.

 

 

처음 설정은 어렵게 느껴지고 변수도 많은 CICD 설정 과정이지만,, 설정해두고 개발을 시작하면 삶의 질이 매우 올라가는 것을 느낄 수 있고, 설정 과정에서 인프라도 경험해볼 수 있으므로 꼭 추천한다!

 

 

References

https://shinsunyoung.tistory.com/120

https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/codedeploy-agent-operations-install-ubuntu.html

https://stackoverflow.com/questions/73301858/aws-codedeploy-agent-not-installing-on-ubuntu-22-04

https://soso-hyeon.tistory.com/51

https://languagestory.tistory.com/154

반응형
LIST