이번에는 간단한 프로젝트를 Github Actions를 통해 CI/CD 파이프라인을 구성하고 테스트해보도록 한다.
초기 세팅
먼저, 테스트에 사용할 Repository를 하나 생성해준다.
이 Repository를 clone해주고, 내용을 추가한다.
이번에는 따로 코드를 작성하지 않고, Spring 프로젝트를 하나 가져와서 추가해주었다.
가져온 프로젝트를 방금 만든 Repo에 push까지 해준 다음, 실제 서버에 배포까지 하면 Github Actions CI/CD 파이프라인을 테스트하기 위한 초기 세팅이 완료된다.
이 프로젝트는 Azure의 인스턴스를 대상으로 배포해보도록 한다.
CI 파트
먼저 CI 파트에서는 배포된 프로젝트에서 내용을 수정해, 그 수정점이 적용된 빌드파일을 생성하는 과정까지 Github Actions를 통해 자동화하는 것을 알아본다.
Clone 받은 프로젝트 Repo에서 내용을 수정했다.
프로젝트 코드를 추가한 후, Github Actions 워크플로우 파일을 작성한다.
name: test-cicd
on:
push:
branches: [main] # Event 트리거 : main 브랜치에 push
jobs:
Build_Project:
runs-on: ubuntu-latest
steps:
- name: Repo download
uses: actions/checkout@v3 # Job 실행환경에 이 Repo를 다운받기
- name: File Check
run: cat README.md # 정상적으로 Repo를 받았는지 확인
- name: setup JDK
uses: actions/setup-java@v4 # Job 실행환경에 Java 프로젝트 빌드를 위한 JDK 설치
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: Build Project # 프로젝트 빌드
run: mvn -B package
working-directory: ./spring-demo
이렇게 로컬에서 작업이 모두 완료되면, main 브랜치에 push해준다.
push 작업을 하게되면, 앞서 작성한 Github Actions에 따라 Event가 트리거되고 Job이 실행된다.
여기까지 Github Actions로 Spring 프로젝트를 자동 빌드하는 과정이였다.
다음으로 자동 배포단계를 알아본다.
CD 파트
앞선 CI 파트에서 새롭게 push된 내용을 바탕으로 Runner에서 프로젝트를 빌드하는데까지 확인했다.
이제는 웹 프로젝트가 배포된 서버에 새롭게 빌드한 내용이 적용되도록 배포하는 과정을 알아본다.
앞서 워크플로우 파일에서 빌드하는 job까지만 작성했다. 그 뒤로 이어서 Deploy하는 Job을 작성한다.
빌드하는 Job과 배포하는 Job을 분리해서 작성하게 되면, Job의 특성에 따라 배포 Job이 실행되는 환경에서는 빌드된 파일을 볼 수 없다. 파일을 Job들 간에 공유할 수 있는 기능이 필요하기에, Artifact라는 개념이 등장하게 된다.
Artifact는 Workflow 중에 생성된 파일을 동일 Workflow 내의 다른 Job들에서 Access할 수 있도록 하는 개념의 파일이다.
upload_artifact와 download_artifact Action을 통해서 Job 내에서 Artifact에 Access할 수 있다.
jobs:
Build_Project:
runs-on: ubuntu-latest
steps:
...
# 빌드한 파일을 Artifact로 업로드
- name: Upload Artifact
uses: actions/upload_artifact@v3
with:
name: jar_file
path: ./spring-demo/*/spring-petclinic-?.jar
Deploy:
runs-on: ubuntu-latest
needs: Build_Project
steps:
# Artifact 다운로드
- name: Get Artifact
uses: actions/download_artifact@v3
with:
name: jar_file
이후, Deploy Job을 계속 작성한다.
배포 서버에 SSH로 접근해서 빌드된 파일을 넣어주고, 빌드된 파일로 다시 서비스를 올려야한다. 이런 동작도 미리 정의된 Action이 존재한다.
ssh-action을 사용하기 위해 접속할 host와 userrname, password/key, port 정보를 넘겨주어야한다.
이와 같은 민감정보들은 Github Actions의 Secrets를 통해 관리한다.
프로젝트 Repository의 Settings > Security > Secrets and variables에서 Secret을 추가할 수 있다.
이를 통해 SSH 접속에 필요한 정보들을 Secret으로 모두 넣어 준 뒤, Action 사용예시와 같이 Jobs에서 사용할 수 있다.
jobs:
...
Deploy:
runs-on: ubuntu-latest
needs: Build_Project
steps:
# Artifact 다운로드
- name: Get Artifact
uses: actions/download-artifact@v3
with:
name: jar_file
# 배포 서버에 SCP 파일 전송
- name: Send file with SCP
uses: appleboy/scp-action@master
with:
host: ${{ secrets.REMOTE_SSH_IP }}
port: 22
username: ${{ secrets.REMOTE_SSH_USERNAME }}
key: ${{ secrets.REMOTE_SSH_PRIVKEY }}
source: "./spring-petclinic-*.jar"
target: ${{ secrets.TARGET_PATH }}
# 전송받은 빌드파일 Deploy
- name: Deploy with New Version
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.REMOTE_SSH_IP }}
port: 22
username: ${{ secrets.REMOTE_SSH_USERNAME }}
key: ${{ secrets.REMOTE_SSH_PRIVKEY }}
script: ${{ secrets.TARGET_PATH }}/action-deploy.sh
이제 다시 코드 수정을 한 후, main 브랜치에 push해준다.
Workflow가 빌드 Job을 먼저 수행한 뒤, 배포 Job을 이어서 수행하게 되며 최종적으로는 배포서버에 배포되는 것까지 되는 것을 볼 수 있다.
+) 배포 서버에 SSH 접근 대상을 제한해둔 경우, SSH 접근하기 전에 CI/CD 서버에서 IP에 대해 접근을 허용해주어야한다. 이는 Github Actions의 Docs에서 관련 API를 확인할 수 있다.