aws instance 배포 자동화

sangwoo noh·2022년 6월 15일
0

슬기로운 회사생활

목록 보기
25/26

왜?

  • 매번 회사 프로젝트의 api server를 instance에 배포 할때마다 압축하고...scp쏘고 압축파일 로컬에서 지우고 클라우드에서 압축풀고 이름 변경하고 패키지 설치... 서버실행... 등등등 절차가 너무 많아서 일단 급한대로 자동화를 진행해주었다

설명

#!/bin/bash

# json파일 파싱을 위한 jq설치 확인 및 설치가 안됐다면 설치를 진행해 주는 코드
JQ_CONST="jq"
CHECK_JQ=$(brew list | grep $JQ_CONST)
echo $CHECK_JQ

if [ "$CHECK_JQ" != "$JQ_CONST" ]; then
  echo "jq is not installed \n"
  echo "install jq with brew \n"
  brew install jq
fi
echo "jq is already installed"
# end of installing "jq" package

# 프로젝트 이름을 package.json에서 파싱한다, 뒤에 정규식은 쌍따옴표를 제거해주는 작업
GET_PROJECT_NAME=$(cat package.json | jq '.name' | sed 's/\"//g')

# 프로젝트 버젼을 package.json에서 파싱한다, 뒤에 정규식은 쌍따옴표를 제거해주는 작업
GET_VERSION=$(cat package.json | jq '.version' | sed 's/\"//g')

# instance에서 돌아가는 screen 세션명을 종료 및 시작을 위해 package.json에서 파싱한다, 뒤에 정규식은 쌍따옴표를 제거해주는 작업
SCREEN_NAME=$(cat package.json | jq '.contributors[0].screen_name' | sed 's/\"//g')

# 압축할 파일명을 지정하기 위해 jq로 파싱한 내용을 조합한다
CREATED_TAR_FILE_NAME=$GET_PROJECT_NAME"-"$GET_VERSION".tar.gz"

# instance에 프로젝트가 위치하기위한 경로의 폴더명을 지정하기위해 jq로 파싱한 내용을 조합한다
CREATED_DIR_NAME=$GET_PROJECT_NAME-$GET_VERSION

# 먼저 프로젝트가 올라갈 위치에 동일한 버젼의 프로젝트가 존재하는지 유효성 검사를 위해 ssh로 원격 제어하여 cli로 경로 존재여부를 확인한다.
# 
IS_EXIST=$(ssh instance.server "if [ -d ~/$SCREEN_NAME/$CREATED_DIR_NAME ]; then echo "exist"; fi")
echo "파일 존재 여부: "$IS_EXIST

TAB_LENGTH="  "

# 문자열의 길이가 0이 아니면 참
# 현재 배포 버젼과 클라우드에 서비스되고있는 버젼이 같다면 배포중지
if [ $IS_EXIST ]; then
  echo "The $GET_VERSION version is exist. \n"
  echo "You must update version on package.json file (that form looks like \"version\": \"$GET_VERSION\") \n"
  echo "(that form is looks like \n$TAB_LENGTH{\n$TAB_LENGTH$TAB_LENGTH...\n\n$TAB_LENGTH$TAB_LENGTH$TAB_LENGTH\"version\": \"$GET_VERSION\"   <== update this \n\n$TAB_LENGTH$TAB_LENGTH...\n$TAB_LENGTH} \n) \n"
  exit
fi


# --exclude 옵션은 해당 파일이나 디렉토리는 제외한다는 옵션
# scp로 파일을 전송하기위해서 파일을 모아서 압축한다.
tar -zcvf $CREATED_TAR_FILE_NAME --exclude ./node_modules --exclude dist --exclude build --exclude ./.git ./

# 압축한 파일을 scp를 사용하여 전송
scp $CREATED_TAR_FILE_NAME instance.server:~/dir_path

# 전송이 끝나면 로컬의 압축파일을 삭제한다.
rm $CREATED_TAR_FILE_NAME

# ssh로 원격제어하여 cli로 배포과정을 순차적으로 진행시킨다.
# 해당 instance에서 실행되는 명령어라고 생각하면됨
# 특정경로가서 폴더 만들고, 파일명 변경하고 파일 이동하고 압축풀고, 압축풀기 끝나면 압축파일 제거하고 대충 이런식
ssh instance.server "cd ~/dir_path ; mkdir $CREATED_DIR_NAME ; mv $CREATED_TAR_FILE_NAME ./$CREATED_DIR_NAME ; cd ./$CREATED_DIR_NAME ; tar -zxf ./$CREATED_TAR_FILE_NAME ; rm ./$CREATED_TAR_FILE_NAME"


# 필요한 경우 스크린 삭제
# 이전에 돌아가고있는 previous version session을 종료한다.
# 세션종료하는 방법이 가장 간단해보여서 이렇게 진행함
ssh instance.server -C "screen -X -S $SCREEN_NAME kill"

# detach모드로 세션 실행
# 전송된 새로운 프로젝트를 실행하기위해 위해 새로운 screen 세션을 생성
ssh instance.server -C "screen -S $SCREEN_NAME -d -m"

# 새 프로젝트가 구동되기 위해 위치한 절대 경로
ABSOLUTE_PATH="~/$SCREEN_NAME/$CREATED_DIR_NAME"

# 실행중인 세션에 stuff로 명령어 전달. 마지막에 개행(\n)전달
# 세션 안에서 실행 시키는 cli
ssh instance.server -C "screen -r $SCREEN_NAME -X stuff $'cd $ABSOLUTE_PATH\n'"

# package.json의특정 sciprt를 실행시키는 명령어
# 이것은 내부적인 솔루션이므로 다른사람들에겐 의미없음
ssh instance.server -C "screen -r $SCREEN_NAME -X stuff $'npm run deployment\n'"


#----- 간단 설명 ----
# 스크린 세션 종료
# $screen -X -S www.videohelpme-server__www-server kill

# 스크린 세션 생성
# $screen -S www.videohelpme-server__www-server

# deployment
# $npm run deployment

# 원격 다중 명령어 실행
# ssh gotalk.server "cd ~/www.videohelpme-server ; ls -al"
profile
하기로 했으면 하자

0개의 댓글