지난번에 'Springboot 프로젝트 Github Action을 이용해서 배포 자동화하기' 를 했었는데, ec2 정보가 변경되어서 다른 ec2로 옮기는 작업을 해보려고 한다.
이전에 정리해둔 글은
https://velog.io/@vector13/Springboot-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-Github-Action%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%B4%EC%84%9C-%EB%B0%B0%ED%8F%AC-%EC%9E%90%EB%8F%99%ED%99%94%ED%95%98%EA%B8%B0 여기서 보면 된다.
사용하는 s3 bucket은 동일하고, EC2 instance 만
기존의 jenkins-ec2(aka 인스턴스1) 라는 이름에서 chaebbi-backend(aka 인스턴스2) 로 옮기려고 한다.
인스턴스 2는 s3 에 대한 fullaccess를 준다
인스턴스 > 작업 > 보안 > IAM 역할 수정에 이전에 만들어둔 s3fullaccess 를 가진 IAM 역할을 부여 (연결)
일단 codeploy가 있어야하므로 인스턴스2에 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
sudo service codedeploy-agent status
정상 설치가 되어 active 응답이 온다
기존에 만들어둔 배포그룹이 인스턴스1 삭제에 따라 실패가 되어있는 것을 확인 가능 하다
배포그룹 편집을 눌러
환경구성에 인스턴스 1 이 있는것을 변경해준다
이 부분이 어떤 인스턴스에서 동작할 지 선택하는 부분이다
나머지는 그대로 두고 저장하고 나온다.
기존 인스턴스1에서는 배포스크립트가 실행할 곳이 app/step1이었던 것에서 /var/www/html/spring으로 변경되기 때문에 스크립트도 수정해준다.
기존에 사용하던 배포스크립트
#!/bin/bash
REPOSITORY=/var/www/html/spring
PROJECT_NAME=chaebbiSpring
cd $REPOSITORY/$PROJECT_NAME/
echo "> GIT PULL"
git pull
echo "> 프로젝트 빌드 시즈악"
./gradlew build -x check --parallel
echo ">step1 디렉 이도옹"
cd $REPOSITORY
echo "> Build 파일 복사"
cp $REPOSITORY/$PROJECT_NAME/build/libs/*.jar $REPOSITORY/
echo "> 현재 구동중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -f ${PROJECT_NAME}-0.0.1-SNAPSHOT.jar)
echo "현재 구동중인 어플리케이션 pid: $CURRENT_PID"
if [ -z "$CURRENT_PID" ]; then
echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
echo "> kill -9 $CURRENT_PID"
kill -9 $CURRENT_PID
sleep 5
fi
echo "> 새 어플리케이션 배포"
#JAR_NAME=$(ls -tr $REPOSITORY/ | grep *.jar | tail -n 1)
JAR_NAME=$(ls -tr $REPOSITORY/*.jar | tail -n 1)
echo "> JAR Name: $JAR_NAME"
echo "> $JAR_NAME 에 실행권한 추가"
chmod +x $JAR_NAME
echo "> $JAR_NAME 실행"
nohup java -jar \
-Dspring.config.location=/var/www/html/spring/application-real-db.properties,/var/www/html/spring/application.yml \
-Dspring.profiles.active=real \
$JAR_NAME 2>&1 &
처럼
AppSpec Hooks 에서 실행할 스크립트 stop.sh 와 start.sh 를 설정해주기
#!/usr/bin/env bash
PROJECT_ROOT="/var/www/html/spring"
JAR_FILE="$PROJECT_ROOT/chaebbiSpring.jar"
APP_LOG="$PROJECT_ROOT/application.log"
ERROR_LOG="$PROJECT_ROOT/error.log"
DEPLOY_LOG="$PROJECT_ROOT/deploy.log"
TIME_NOW=$(date +%c)
# build 파일 복사
echo "$TIME_NOW > $JAR_FILE 파일 복사" >> $DEPLOY_LOG
cp $PROJECT_ROOT/build/libs/*.jar $JAR_FILE
# jar 파일 실행
echo "$TIME_NOW > $JAR_FILE 파일 실행" >> $DEPLOY_LOG
nohup java -jar $JAR_FILE > $APP_LOG 2> $ERROR_LOG &
CURRENT_PID=$(pgrep -f $JAR_FILE)
echo "$TIME_NOW > 실행된 프로세스 아이디 $CURRENT_PID 입니다." >> $DEPLOY_LOG
#!/usr/bin/env bash
PROJECT_ROOT="/var/www/html/spring"
JAR_FILE="$PROJECT_ROOT/chaebbiSpring.jar"
DEPLOY_LOG="$PROJECT_ROOT/deploy.log"
TIME_NOW=$(date +%c)
# 현재 구동 중인 애플리케이션 pid 확인
CURRENT_PID=$(pgrep -f $JAR_FILE)
# 프로세스가 켜져 있으면 종료
if [ -z $CURRENT_PID ]; then
echo "$TIME_NOW > 현재 실행중인 애플리케이션이 없습니다" >> $DEPLOY_LOG
else
echo "$TIME_NOW > 실행중인 $CURRENT_PID 애플리케이션 종료 " >> $DEPLOY_LOG
kill -9 $CURRENT_PID
fi
github repository에 scripts 폴더 생성해서 저 두 스크립트 넣어주고 commit 해보면
듀근두근
완료 되었다!
인스턴스 2에서 app log를 보기위해서 application.log를 vim으로 열었지만 내용이 없었고
error.log를 여니까
jar 에 실행권한이 없었다. 그리고 jar 파일이 있는 파일의 위치도 /var/www/html/sprinng/build/libs 안에 있는 곳으로 변경해주었고, plain 과 snapshot 중 하나의 jar 만 지정해주기
일단 appspec.yml에 destination이 잘못되어있는 것 (home/ubuntu/app으로 되어있는 부분)을 수정
있어야할 /var/www/html에는 scripts가 안생기고
home/ubuntu/app에 생겨있음
그러니까 deploy 과정에서 에러가 난다
--> 아직 이전 작업이 안끝난 상태에서 급하게 돌려서 그럼 다시 re do 해보니까 된다
우하하 됐다!
그렇지만 에러가 있었다
기존에 ec2에 있는 applicaiton.properties 파일과 application.yml 파일을 못읽어서 sql에러와 s3에러가 나는 것이었다.
github action에는 설정 파일을 어떻게 주는 걸까 ?
프로젝트 서비스 실행에 필요한 설정파일이 두개다
application.properties & application.yml
이 둘을 github action이 알아들을 수 있게 해보겠다
properties 같은 경우는 저렇게 새 비밀을 해서 다 넣어버리면 되고
gradle.yml에 application.properties를 만드는부분을 넣어준다
# (+++) application.properties 생성
- name: make application.properties
run:
mkdir ./src/main/resources |
touch ./src/main/resources/application.properties
shell: bash
- name: deliver application.properties
run: echo "${{ secrets.PROPERTIES }}" > ./src/main/resources/application.properties
shell: bash
ec2에도 잘 생겼는지 파악해보겠다.
생겼다!
yml도 secret에 생성해주고
gradle.yml을 수정해줌
github action 과정에서 수행되는것 확인
ec2에도 생겼다
그러므로 결과적으로 맨 위의 그림에서 단계별로 적용되는 파일의 그림은 다음과 같다.
자 이제 적용된 최종적인 파일을 봐보자!
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Spring Boot & Gradle CI/CD
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
AWS_REGION: ap-northeast-2
S3_BUCKET_NAME: chaebbi-deploy-bucket
CODE_DEPLOY_APPLICATION_NAME: chaebbi-codedeploy-app
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: chaebbi-codedeploy-deployment-group
permissions:
contents: read
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
steps:
# (1) 기본 체크아웃
- name: Checkout
uses: actions/checkout@v3
# (2) JDK 11 세팅
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
# (+++) application.properties 생성
- name: make application.properties
run:
mkdir ./src/main/resources |
touch ./src/main/resources/application.properties
shell: bash
- name: deliver application.properties
run: echo "${{ secrets.PROPERTIES }}" > ./src/main/resources/application.properties
shell: bash
# (+++) application.yml 생성
- name: make application.yml
run: touch ./src/main/resources/application.yml
shell: bash
- name: deliver application.yml
run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml
shell: bash
# (++++)
- uses: actions/upload-artifact@v2
with:
name: application.properties
path: ./src/main/resources/application.properties
# (3) gradlew 실행 권한부여
- name: Grant execute permission for gradlew
run: chmod +x gradlew
# (3) Gradle build (Test 제외)
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
arguments: clean build -x test
#run : ./gradlew clean build --exclude-task test
# (4) AWS 인증 (IAM 사용자 Access Key, Secret Key 활용)
- 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 }}
aws-region: ${{ env.AWS_REGION }}
# (5) 빌드 결과물을 S3 버킷에 업로드
- name: Upload to AWS S3
run: |
aws deploy push \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--ignore-hidden-files \
--s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \
--source .
# (6) S3 버킷에 있는 파일을 대상으로 CodeDeploy 실행
- name: Deploy to AWS EC2 from S3
run: |
aws deploy create-deployment \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
--s3-location bucket=$S3_BUCKET_NAME,key=$GITHUB_SHA.zip,bundleType=zip
#!/usr/bin/env bash
PROJECT_ROOT="/var/www/html/spring"
PROJECT_NAME="chaebbiSpring"
JAR_FILE="$PROJECT_ROOT/${PROJECT_NAME}-0.0.1-SNAPSHOT.jar"
APP_LOG="$PROJECT_ROOT/application.log"
ERROR_LOG="$PROJECT_ROOT/error.log"
DEPLOY_LOG="$PROJECT_ROOT/deploy.log"
TIME_NOW=$(date +%c)
# build 파일 복사
echo "$TIME_NOW > $JAR_FILE 파일 복사" >> $DEPLOY_LOG
cp $PROJECT_ROOT/build/libs/*.jar $JAR_FILE
# jar 파일에 실행권한 추가
echo "> $JAR_FILE 에 실행권한 추가"
chmod +x $JAR_FILE
# jar 파일 실행
echo "$TIME_NOW > $JAR_FILE 파일 실행" >> $DEPLOY_LOG
nohup java -jar \
-Dspring.config.location=/var/www/html/spring/src/main/resources/application.properties,/var/www/html/spring/src/main/resources/application.yml \
-Dspring.profiles.active=real \
$JAR_FILE > $APP_LOG 2> $ERROR_LOG &
CURRENT_PID=$(pgrep -f $JAR_FILE)
echo "$TIME_NOW > 실행된 프로세스 아이디 $CURRENT_PID 입니다." >> $DEPLOY_LOG
여기서 nohup java -jar 에서 뒤에 설정파일 저장된 경로를 지정해주어야 설정파일이 적용되어서 파일이 실행된다!
#!/usr/bin/env bash
PROJECT_ROOT="/var/www/html/spring"
JAR_FILE="$PROJECT_ROOT/${PROJECT_NAME}-0.0.1-SNAPSHOT.jar"
PROJECT_NAME="chaebbiSpring"
DEPLOY_LOG="$PROJECT_ROOT/deploy.log"
TIME_NOW=$(date +%c)
# 현재 구동 중인 애플리케이션 pid 확인
CURRENT_PID=$(pgrep -f $JAR_FILE)
# 프로세스가 켜져 있으면 종료
if [ -z $CURRENT_PID ]; then
echo "$TIME_NOW > 현재 실행중인 애플리케이션이 없습니다" >> $DEPLOY_LOG
else
echo "$TIME_NOW > 실행중인 $CURRENT_PID 애플리케이션 종료 " >> $DEPLOY_LOG
kill -9 $CURRENT_PID
fi
적용된 폴더와 코드들은 아래 깃허브에서 확인 가능 !
https://github.com/Chaebbi/chaebbiSpring