Rookies - 2025.01.17

이주원·2025년 1월 19일

sk쉴더스 루키즈

목록 보기
2/36

워크플로우 자동화

오늘 배울 내용은 깃 엑션을 활용하여 프로젝트를 자동으로 배포하는 부분이였습니다.





실습전 필요한 사전지식

1. 깃허브 환경변수의 역할을 알아야합니다.

깃 액션에서 환경변수의 역할은 해당 워크플로우가 문제없이 진행되도록 필요한 환경을 만들어주며 보안성도 제공할 수 있습니다.



2. gitaction 에서 .yml파일의 역할


깃엑션이 trigger에의해 시작 되었을때
애플리케이션에서 어떤 작업(jobs)을 할것인지 정의하는 역할을 합니다.



3. gitcation 에서 checkout의 역할


체크아웃의 역할은 워크플로우가 실행되었을대 레파지토리에서 해당 코드를 불러오는 역할을 합니다.
코드를 불러오는이유는 해당 코드를 패키징하여 서비스를 받는 사용자들에게 배포하기 위해서입니다.




4. Rds란?

아마존 웹서비스에서 제공하는 관계형 데이터베이스 서비스로
RDS자체가 데이터베이스라는 것이 아니라

아마존에서 지원하는 다양한 데이터베이스 엔진을 쉽게 운영할 수 있도록 자동화된 환경을 제공해 줍니다.


자동화라는 특성을 깃 엑션과 접목시켜 손쉬운배포 , 보안성강화에서 이점을 얻을 수 있습니다.







우선 어제 사용했던 인스턴스를 다시 켜줍니다.





오늘 실습할 워크플로우 구성과 순서는 아래와 같았습니다.

1. 깃허브에 변수를 추가한다

2. 워크플로우를 작동시키는 트리거를 만든다.

3. 작업이 진행된다









.yml 트리거 작성

.yml 파일에서 트리거를 작성해줍니다.
로컬pc 에서 브랜치로 push가 일어났을경우가 작업이 실행되도록 하였습니다.

.yml jobs(해야할 일) 작성

우선 jobs 의 이름을 cicd-deploy라고 지어줬습니다.
작업이 이루어질 ec2환경이 ubuntu기때문에 os를 ubuntu로 지정했습니다.




실습에서 진행할 jobs는 총 6개의 파이프라인으로 구성되어 있습니다.


1. 체크아웃
2. jdk 설치
3. build
4. 이름길이 수정
5. ec2 로 업로드
6. ec2 서버 가동

요약하자면 체크아웃하여 코드를 불러와 build해서 배포하는 것입니다.



프로젝트를 push하고 git 에서 action을 확인해보면 아래와같이 진행되고 있는 것을 확인할 수 있었습니다.

앞서 설정한 cicd-deploy라는 jobs이 제대로 실행되고 있습니다.




빌드 작업을 추가 했습니다.

# build 준비
# chmod +x ./gradlew : 퍼미션 오류 발생시 처리
# ./gradlew clean build
  - name: 단위 테스트 및 빌드
    # 명령어가 여러개면 | 추가 .
    run:
      ./gradlew clean build

./gradlew는 쓰기 권한이없어 git action 도중 에러가 발생하기 때문에 권한을 추가 하였습니다.

띄어쓰기 이슈로인해 에러가 발생했습니다.

제대로 단위테스트까지 진행된 것을 확인했습니다.



gitaction이 끝나면 총 2개의 .jar 파일이 만들어지는걸 확인할 수 있었습니다.

.(plan)jar vs .(boot)jar

(plan)jar은 단순히 라이브러리로 사용되는 반면 bootjar은 자바로 실행시킬 수 있는 프로젝트파일 입니다.



*SNAPSHOT.jar 이라는 이름은 길어서 짧게 수정 해줬습니다.

  	    # 이름이 너무 길어 적당하게 수정 -> 리눅스 명령어
        # 파일 위치를 변경하면서 이름도 변경 -> mv
        - name: 관리상 빌드된 결과물의 이름을 변경 처리
          run: |
            mv ./build/libs/*SNAPSHOT.jar ./run.jar
            ls

파일위치를 옮기면서 파일명을 수정하고 해당 파일을 ls명령을통해 제대로 수정되었는지 확인합니다.

제대로 수행된 것을 확인할 수 있었습니다.



단위테스트의 print문은 보이지않음

페키지의 단위테스트 파일

>> package com.example.demodeploy;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoDeployApplicationTests {

    @Test
    void contextLoads() {
        // 단위 테스트
        // MVC 테스트 -> 목업통해서 가상 처리 가능
        // RestAPI 테스트 가능
        // 메시지가 보이지는 않지만, 차후 코드로 확인
        System.out.println("단위 테스트 호출!! echo");
    }

}

spring boot의 단위테스트 파일입니다.
git action에서 제대로 수행됬는지 확인하기위해 System.out.println을 추가했습니다.

그러나 git action에서는 메시지가 출력되지 않는 것을 확인했습니다.

키추가

EC2인스턴스와 연동하기위하여 환경변수를 추가하였습니다.

EC2 확인

 # EC2 로 업로드
  # 호스트정보(IP), 접속자명(ubuntu), 키파일(pem) -> 시크릿!!
  # SSH를 통해서 파일등을 복사(업로드)
  # 업로드 대상(run.jar)
  # 타겟(EC2)의 특정 경로(복사될 위치), /home/ubuntu/server/demo
  - name: EC2에 jar파일 업로드
    uses: appleboy/scp-action@v0.1.7
    # 위의 액션을 위한 파라미터
    # SSH의 포트를 보안상 이유로 22-> 다른번호로 변경 했다면
    # PORT 설정 필요
    # 파일이 여러개면 "파일, 파일, ... "
    # 원격 서버에 폴더도 자동 생성되는지 검토
    with:
      host: ${{ secrets.EC2_HOST }}
      username: ${{ secrets.EC2_USER }}
      key: ${{ secrets.EC2_KEY }}
      source: run.jar
      target: /home/ubuntu/server/demo

성공적으로 EC2에 JAR파일이 업로드 되었습니다.






EC2에서 수행할 작업

프로젝트가 실행되면 나오는 html 파일을 수정했습니다.

 # ec2 접속,서버가동!!
  # https://github.com/appleboy/ssh-action
  - name: SSH로 ec2에 접속후 서버가동
    uses: appleboy/ssh-action@v1.2.0
    # script_stop : true -> 오류나면 중단
    # 처리할 반복적 작업
    # 1. 기존 jar 파일 삭제 처리 (업로드 위치, 구동 위치 구분)
    #    구동 위치 : /home/ubuntu/server/demo/web <- 설정(가정)
    #     rm -rm 대상 => 대상의 폴더 및 하위 파일까지 모두다 삭제
    # 2. 새롭게 폴더 생성 /home/ubuntu/server/demo/web
    #    mkdir /home/ubuntu/server/demo/web
    # 3. jar 파일 이동(~/demo/*.jar => ~/web/*.jar)
    #    mv
    # 4. jar 파일이 존재하는 위치로 이동
    #    cd /home/ubuntu/server/web
    # 5. 서버 중단 -> 8080포트를 사용하는 프로세스 중단
    #    sudo fuser -k -n tcp 8080 || true
    #    무조건 다음 단계로 넘어가 처리 (|| true)
    # 6. 서버구동
    #    엑세스, 에러로그등 전체 로그를 output.log으로 출력
    #    nohup java -jar run.jar > ./output.log 2>&1 &
    # 7. 뒷정리
    with:
      host: ${{ secrets.EC2_HOST }}
      username: ${{ secrets.EC2_USER }}
      key: ${{ secrets.EC2_KEY }}
      script_stop: true
      script: |
        rm -rf /home/ubuntu/server/web
        mkdir /home/ubuntu/server/web
        mv /home/ubuntu/server/demo/run.jar /home/ubuntu/server/web/run.jar
        cd /home/ubuntu/server/web
        sudo fuser -k -n tcp 8080
        nohup java -jar run.jar > ./output.log 2>&1 &
        rm -rf /home/ubuntu/server/demo

요약하자면 기존에 사용하던 애플리케이션을 삭제하고 새로받은 에플리케이션을 실행한다는 것 입니다.

+ script_stop: true 는 에러발생시 즉시 작업중단을 하겠다는 말 입니다.


작업이 정상적으로 진행된경우

ec2 ip주소:8080 포트를 열어보니 수정한대로 잘출력됩니다.



오류발생시


작업이 진행되다멈춘 것을 확인할 수 있습니다.






RDS 생성

아마존웹서비스 RDS 콘솔로 이동하여 데이터베이스를 생성해줍니다.

mysql 데이터베이스엔진을 선택하여 데이터베이스를 생성합니다.





RDS를 활용하면 아마존웹서비스에서 지원하는 EC2 인스턴스에 연결하는 옵션이 있습니다. 자동화 서비스를 만드는데 아주 유용할 것 같습니다.

다양한 옵션들을 모두 선택하면 데이터베이스가 생성됩니다.






RDS의 엔드포인트는 RDS인트턴스에 접속할수 있는 URL정보이며 보안적인 측면에서 엔드포인트는 !!!절대로!!! 노출되면안됩니다.

인텔리제이 편집기에서 스프링부트 프로젝트에 rds인스턴스를 연동해줍니다.


정보를 입력했는데도 해당 rds인스턴스와 연동되지 않는 문제가 발생했습니다. 원인은 포트가 허용되어있지않아있었기 때문입니다. 인바운드 규칙에들어가3306 포트를 열어줍니다.

연동이 완료됬습니다.

편집기에서도 연동이 완료된것을 확인할 수 있었습니다.





엔드포인트 정보를 노출하지 않는 깃엑션 실습을 할 예정입니다.

우선 build.gradle에서 jpc,mysql관련 의존성을 추가해줍니다.

의존성을 추가했으면 간단한 api를 생성해줍니다.





.gitignore 파일에 특정 파일이나 폴더를 추가하면, 해당 항목들은 Git에서 추적하지 않기 때문에 GitHub에 푸시되지 않습니다.

gitignore에 엔드포인트정보가 들어있는 application.poperties을 추가하여 깃허브에 반영되지 않도록 합니다.





application.properties가 깃허브에 반영되지 않았기때문에 따로 환경변수를 추가해 해당 정보(application.properties)를 넣어줍니다. 이름은 아래와같이 만들었습니다.

.yml 파일로 이동하여 환경변수에 추가한 정보를 해당 url 경로에 추가해줍니다. 이러한 구조로 배포하면 깃허브에 엔드포인트 정보가 올라가지않고도 rds와 연동되도록 프로젝트를 배포할 수 있습니다.

인스턴스에서 추가한 데이터베이스 더미들이 정상적으로 출력되는 것을 확인 하였습니다.

오늘도 좋은 교육을 제공해주신 sk쉴더스루키즈 감사합니다!

profile
뭐가될지 모름

0개의 댓글