개요
실제 운영 환경 인프라를 구축하기 위해 설계를 팀에 공유해보기로 하였다. 사실 3달 정도 전에 Github Actions + Elastic Beanstalk으로 실습을 해보았으나, 실패했던 경험이 있기에 다시 돌아와서 설계 과정을 세세히 기록해본다.
또한, 이전에는 사용해보고 싶었던 기술(Jenkins)과 추천 받은 기술로 구성하였다면, 이번엔 온전히 내 논리와 지식을 활용하여, 배포를 하자마자 사용자가 생길 우리 서버..🤗의 아키텍처를 구상해보려고 한다.
1) 이전 시도 복기와 현재 상황
나에게 가장 까다롭게 다가오는 것은 멀티 모듈 설계와 AWS 사용이다. 이 까다로운 문제를 하나씩 풀어 나가는 과정을 작성해보자..!
1-1) 모듈 구조 파악하기
- core(공통 라이브러리)
- admin(관리자 모듈)
- user(사용자 모듈
1-2) 인턴십에 수행했던 PoC를 떠올려 보자.
나는 이미 멀티 모듈 구조의 CI/CD를 설계 및 구축, 운영한 경험이 있다.
멀티 모듈을 자동으로 빌드 및 배포하기 위해서는 다음과 같은 동작 순서를 따른다.
- 공통 라이브러리 모듈을 빌드 및 저장소에 push
- 하위 모듈들이 저장소에 있는 공통 라이브러리를 의존하여 빌드 및 실행
GCP에서는 이 과정을 Cloud Build와 Artifact Registry로 수행이 가능하다. 정확히 말하자면 70% 정도만 가능하다. 그 이유는 Instance Group으로 생성되는 인스턴스들이 Registry의 파일을 가져와 자동으로 배포하려면, Terraform이나 엔서블 등과 같은 도구를 통해 컨트롤 해야한다. 당시 나에게 주어진 시간이 많이 없었기에 빌드만 자동화하였다.
- 해당 레포에서 필자가 수행한 PoC를 확인할 수 있다. MVN, NPM, Docker에 대한 자료가 있으니, 참고하길 바란다.
1-3) 현재 프로젝트는 AWS를 사용
나의 경험을 살려서 멀티 모듈 CI/CD 구조를 어림잡아 생각해보면 ① 빌드 자동화 도구 ② 공통 라이브러리 저장소 ③ 배포 자동화 도구 이 세 가지가 필요하다. 이에 상응하는 AWS 기술은 codebuild, s3, code deploy 등이 있다.
현재 진행하는 CS 스터디에서 스터디원이 위 세 가지 조합 비교하여 github actions + elastic beanstalk 구조에 대해 발표한 적이 있다. 이를 참고하여 해당 구조를 적용해보자! 팀원의 블로그 🤗
2) 멀티모듈 CI/CD를 컨트롤할 github actions 기술 이해
2-1) 기존에 사용했을 때 실패했던 이유
개요에서 밝혔듯, 이 기술을 이미 써본 적이 있지만, 당시에 제대로 구축을 못 했었다. 실패했던 이유는 회사에서 PoC를 진행했을 땐 이미 서버, 인프라 구조가 이미 설계 및 구축되어 있었기에 이에 맞춰서 CI/CD에만 집중할 수 있었다. 그런데 지금 프로젝트에서는 인프라 자체를 스스로 설계 및 구상해야 해서 혼동한 점이 많았다. (멀티 모듈 인프라는 직접 설계 및 구축 해보는 것이 이번 프로젝트에서 처음이었다.. 😂) 그래서 공통 라이브러리를 의존하는 부분이나 개별 인스턴스에 github actions와 EB를 세팅해야 하는 부분 등을 놓쳤었다.
결론적으로 기술 이해도 부족/약간의 조급함ㅎ이 문제였고 백엔드 팀장님과 날밤까며 계속 시도를 했지만 원인 파악도 제대로 하지 못하고 실패를 했었다.. 😂 다시 돌아간다면 나의 경험을 떠올리면서 이 프로젝트에 적용을 어떻게 할지 침착하게 구상 및 설계했을 것같다..!
2-2) github actions 조건문 분기로 변동사항이 있는 모듈만 빌드하기!
아무튼, 위 사고의 과정을 따라 프로젝트에 적용해야할 사항들을 작성해보자.
멀티 모듈 CI/CD를 위해 요구되는 사항과 해결 방법은 다음과 같다.
1. 한 모듈이 수정되면 해당 모듈만 빌드 및 배포되어야 한다.
- 한 모듈이 수정될 때 모든 모듈이 같이 빌드 및 배포한다면 아무리 자동화가 되어있다하더라도 비효율적이다. 변동 사항 없이 잘 돌아가고 있는 모듈까지 재빌드 및 재실행하기보다, 변동사항이 생긴 모듈만 빌드 및 배포되도록 설정하자.
- github actions는 yaml 파일처럼 동작 과정을 작성할 수 있다.
예시 코드
name: CI/CD Pipeline
on:
push:
branches:
- main
paths:
- 'common/**' # common 모듈에 대한 변경
- 'admin/**' # admin 모듈에 대한 변경
- 'user/**' # user 모듈에 대한 변경
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v2
with:
java-version: '11' # 필요한 Java 버전으로 변경
- name: Build and test
run: |
if [[ $(git diff --name-only HEAD^ HEAD) =~ ^common/ ]]; then
cd common
./gradlew build
cd ..
fi
if [[ $(git diff --name-only HEAD^ HEAD) =~ ^admin/ ]]; then
cd admin
./gradlew build
cd ..
fi
if [[ $(git diff --name-only HEAD^ HEAD) =~ ^user/ ]]; then
cd user
./gradlew build
cd ..
fi
- name: Deploy to Elastic Beanstalk
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: 'your-aws-region'
run: |
if [[ $(git diff --name-only HEAD^ HEAD) =~ ^common/ ]]; then
cd common
./gradlew assemble
zip -r application.zip build/libs/*.jar
eb init your-app-name --region $AWS_REGION
eb deploy
cd ..
fi
if [[ $(git diff --name-only HEAD^ HEAD) =~ ^admin/ ]]; then
cd admin
./gradlew assemble
zip -r application.zip build/libs/*.jar
eb init your-app-name --region $AWS_REGION
eb deploy
cd ..
fi
if [[ $(git diff --name-only HEAD^ HEAD) =~ ^user/ ]]; then
cd user
./gradlew assemble
zip -r application.zip build/libs/*.jar
eb init your-app-name --region $AWS_REGION
eb deploy
cd ..
fi
2. 하위 모듈들은 각각의 EB를 가지면서 이 공통 라이브러리를 항상 의존해야한다.
- 이는 EB의 .ebextensions 파일로 컨트롤 한다.
3) 결론 및 정리
3-1) Github Actions
하나의 github actions가 여러 EB를 포인팅하고 있는 구조를 갖는다. 이 구조에서 하위 모듈들이 독립적으로 빌드될 수 있도록 조건분기를 실행파일에 설정한다.
* 여기서는 빌드 과정만 신경 쓴다!
- 이벤트 기반 트리거
- 특정 이벤트(나의 경우 merge)에 반응하여 자동으로 워크플로우를 실행한다.
- on 키워드를 사용하여 어떤 이벤트가 발생할 때 워크플로우가 실행될지를 정의한다. ➡️ 설계에서 정의
- 워크플로우 정의:
- YAML 형식으로 워크플로우를 정의합니다. 각 워크플로우는 여러 개의 작업(Job)으로 구성될 수 있다.
- 각 작업은 특정 환경에서 실행되며, 다양한 명령어와 스크립트를 실행할 수 있다.
- 작업 및 단계:
- 각 작업은 여러 단계를 포함 (예를 들어 코드 체크아웃, 의존성 설치, 테스트 실행, 빌드 생성 등)을 포함할 수 있다.
- 하위 모듈들은 저장소에 저장된
공통 라이브러리의 의존성을 설치하고빌드를 생성한다. - 하위 모듈들은 이 과정을 통해 각각의 모듈을 자신의 변경사항이 바뀌었을 때만 빌드하는 것에 집중한다.
- 하위 모듈이 공통 라이브러리를 의존하는 것은 EB의 .ebextensions에서 진행한다.
- 하위 모듈들은 저장소에 저장된
- 각 작업은 여러 단계를 포함 (예를 들어 코드 체크아웃, 의존성 설치, 테스트 실행, 빌드 생성 등)을 포함할 수 있다.
3-2) Elastic Beanstalk
- 배포 패키지
- Elastic Beanstalk에 배포할 애플리케이션은 ZIP 파일 형식의 배포 패키지로 준비되어야 한다.
- EB 배포를 커스텀하기 위해 .ebextensions/ 에 옵션을 작성한다.
- ebextenstions: EB를 실행할 때 최초로 실행되는 파일
- 하위 모듈은 저장소에 저장된 공통 라이브러리 의존
- 공통 모듈은 빌드된 파일을 저장소에 push
다음 편에서는 직접 설계한 것과 설정 파일들을 다뤄보겠다. 쉽지 않은 길이 예상된다... 그래도 아자아자 🤗
'DevOps > DevOps' 카테고리의 다른 글
[DevOps] AWS에서 cloudtype으로 DB 마이그레이션하기 (0) | 2024.08.10 |
---|---|
[DevOps] cloudtype으로 DB 호스팅 비용 줄이기 (0) | 2024.08.09 |
[DevOps] AWS 하나의 LB로 여러 서비스 운영하기 (0) | 2024.05.22 |
[DevOps] GCP 하나의 LB로 여러 서비스 운영하기 (1) | 2024.05.13 |
[AWS] public & private subnet 분리로 서버 운영하기 (2) | 2024.04.07 |