Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- AccessToken
- 알고리즘
- Spring Cloud Gateway
- S3
- Invalid property 'principal.username' of bean class
- spring DI
- 백준
- RefreshToken
- spring aop
- 우아한 테크러닝
- kotest testcontainers
- multimodule testcontainers
- 소수찾기 java
- ObjectOptimisticLockingFailureException 처리
- redissonlock aop
- netty
- 형상관리
- springsecurity
- TestContainers
- ObjectOptimisticLockingFailureException
- DI
- 낙관적 락 재시도
- interface
- aop
- jpa
- java
- 낙관적 락 롤백
- 멀티모듈 테스트컨테이너
- @transactional
- OptimisticLock
Archives
- Today
- Total
조급하면 모래성이 될뿐
CodeDeploy 적용기 본문
Why?
- 처음 프런트팀과 협업을 하기 전 완료된 API를 실시간으로 공유하고 싶었다.
- 완료된 API를 프론트에서도 바로 호출해볼 수 있으면 문제도 더 빨리 잡을 수 있고, 서로 생산성도 높일 수 있다고 생각했다.
HOW?
- CI는 GithubActions를 사용했고, CD방식은 크게 2가지 중에 고민했다.
1. Docker 이미지를 만들고, EC2에서 이미지를 받아와서 실행.
2. S3에 Jar파일을 올리고, AWS의 CodeDeploy를 통해 배포한다.
- 결과적으로 2번을 선택했다. 두 방식의 장, 단점을 찾아보았을 때 모두 하지 마라!.. 또는 이건 쓰면 안 된다! 이런 내용은 딱히 못 찾았고, Docker에 익숙하지 않았기 때문에 2번을 선택했다.
- 간단하게 찾아보았을 때 1번 방식은 별도의 메모리 공간(S3)이 필요하지 않다는 장점이 있지만, 외부 시스템(Docker)을 사용하기 때문에 2번보다 속도적인 측면은 떨어진다고 한다.
- 참조
- 추가적으로 Beanstalk를 사용하지 않은 이유는, 팀원들과 논의하면서 좀 더 low 하게 배포 환경을 구성하자는 의견이 많았고, 지금 단계에서는 불편함을 경험해보는 것도 좋을 것 같았다.
적용 과정
- 큰 흐름은 아래와 같다.
- GithubActions에서 스크립트가 수행된다.
name: Tenwonmoa CI-CD with Gradle
on:
push:
branches: [ "main", "develop" ]
pull_request:
branches: [ "main", "develop" ]
# 변수 설정
env:
S3_BUCKET_NAME: tenwonmoa-cd
CODE_DEPLOY_APPLICATION_NAME: tenwonmoa-app
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: tenwonmoa-deploy-group
DEPLOY_ZIP_FILE: tenwonmoa-boot-service.zip
permissions:
contents: read
jobs:
tenwonmoa-ci-cd:
runs-on: ubuntu-latest
steps:
- name: Checkout repository and submodules
uses: actions/checkout@v2
with:
token: ${{ secrets.CI_ACCESS_TOKEN }}
submodules: true
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
- name: build docker-compose
run: docker-compose up -d
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
arguments: build
- name: Make zip file
run: |
mkdir -p before-deploy/
cp appspec.yml before-deploy/
cp scripts/*.sh before-deploy/
cp build/libs/*.jar before-deploy/
cp docker-compose-dev.yml before-deploy/
cd before-deploy && zip -r before-deploy *
cd ../ && mkdir -p deploy
mv before-deploy/before-deploy.zip deploy/$DEPLOY_ZIP_FILE
- 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_ID }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Upload to S3
run: aws s3 cp --region ${{ secrets.AWS_REGION }} ./deploy/$DEPLOY_ZIP_FILE s3://$S3_BUCKET_NAME/$DEPLOY_ZIP_FILE
- name: Code Deploy
run: |
aws deploy create-deployment \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
--s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$DEPLOY_ZIP_FILE
- submodule위해 checkout
- build
- jar파일과 배포를 위한 파일을 zip 파일로 묶는다
- deploy.sh: 애플리케이션 수행을 위한 스크립트
- appspec.yml: AWS CodeDeploy에서 읽고 처리하기 위한 파일, 크게 배포될 위치(destination)와 실행될 스크립트를 지정한다.
- zip 파일을 S3로 업로드한다.
- 이때, S3접속을 위한 IAM계정 정보는 github에서 Repository secrets에 등록해주어야 한다.
- IAM계정은 업로드될 S3에 접근할 수 있는 권한이 필요하다.
- CodeDeploy의 새로운 배포를 생성.
이후에는 CodeDeploy에서 appspec.yml 파일을 해석하여 배포를 진행한다. 배포가 진행되면서 deploy.sh 스크립트가 수행된다.
deploy.sh은 아래와 같다.
#!/bin/bash
REPOSITORY="/home/ubuntu/app"
PROJECT_NAME="tenwonmoa"
echo "> Build 파일 복사"
cp $REPOSITORY/zip/*.jar $REPOSITORY/
echo "> 현재 구동 중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -fl $PROJECT_NAME | grep java | awk '{print $1}')
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 실행권한 추가"
sudo chmod +x $JAR_NAME
echo "> $JAR_NAME 실행"
## docker 실행해야 함.
nohup java -jar -Dspring.profiles.active=dev $JAR_NAME --server.port=8080 \
$JAR_NAME > $REPOSITORY/nohup.out 2>&1 &
A~Z 설명보다는 큰 그림으로 기록했다.
CodeDeploy를 적용하면서 아래 블로그와 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 책을 많이 참조했다 !
반응형
'TroubleShooting > 데브코스' 카테고리의 다른 글
서브모듈 적용해서 DB접속정보 보호하기 ! (0) | 2022.08.07 |
---|---|
Restdocs와 Swagger UI 연동해서 EC2에 배포하기 (0) | 2022.08.04 |
Service에서 DataIntegrityViolationException을 Catch 못함 (0) | 2022.07.14 |
S3 파일 업로드 (0) | 2022.07.11 |
Service에서 다른 Service를 의존하게 된다면 ? (0) | 2022.07.06 |