CodeDeploy 이해하고 푸쉬 서버와 API 서버 분리하기

Server The SOPT·2022년 7월 18일
9

✏️ 작성자: 김혜정
📌 작성자의 한마디: 서버 분리했는데 배포 자동화를 실패했다면? 공식문서를 탐구하자ㅠ

해당 글에서는 AWS CodeDeploy와 팀 하우스 서버들이 CICD를 푸쉬 알림 서버와 연결하면서 발생했던 문제를 다룹니다.


👊 AWS CodeDeploy가 대체 뭔데?

AWS CodeDeploy는 Amazon EC2 인스턴스, 온프레미스 인스턴스, 서버리스 Lambda 함수 또는 Amazon ECS 서비스로 애플리케이션 배포를 자동화하는 배포 서비스입니다.

AWS CodeDeploy를 통해 Amazon EC2, AWS Lambda 또는 Amazon ECS에 코드를 배포하는 데는 추가 비용이 부과되지 않는다고 합니다.

CodeDeploy는 서버에서 실행되고 Amazon S3 버킷, GitHub 리포지토리 또는 Bitbucket 리포지토리에 저장되는 애플리케이션 콘텐츠를 배포할 수 있습니다.

CodeDeploy는 S3에서 빌드 산출물을 압축 파일로 가져와서 Deploy 해준다.
CodeDeploy에는 빌드 기능이 없기 때문에 별도의 빌드 과정이 필요하다.
CodeDeploy가 시행되기 위해서는 EC2에 CodeDeploy Agent가 반드시 실행 중이어야 한다.
CodeDeploy는 배포를 진행하다가 어떤 문제가 발생하면 이전 상태로 롤백시켜준다.
애플리케이션 사양 파일(AppSpec.ymal)은 CodeDeploy에서 배포를 관리하는 데 사용한다.

팀 하우스의 CICD 동작 방식

CodeDeploy와 GitHub 액션과 S3버킷을 이용하여 CICD를 적용하였습니다.
저희가 원래는 이 좋은 블로그를 보고 적용을 했다가 엇? 빌드 에러가 나는 코드여도 자동 배포가 되는거 아닌가?! 싶었습니다. 그래서 git action을 적용하여 빌드 후 배포하는 형태로 변경하였습니다.

관련 구현 방법은 하우스 서팟원 혁준이가 아주 상세하게 작성한 1편과 2편을 보고 오셔요!

  • EC2에 설치된 aws cli를 이용하여 Git action에서 CodeDeploy를 이용하여 디플로이를 진행할 수 있도록 합니다.

Application, Deployment Group, Deployment 이해하기

Application

  • 배포할 소프트웨어

Deployment Group

  • 어느 인스턴스에 배포하여 실행하는지
  • 어떤 방식으로 배포할 것인지

Deployment

  • 소프트웨어의 어떤 리비전을 어느 Deployment Groupd에게 배포하고 실행할 것인지

1개의 Application은 여러 개의 Deployment Group을 가질 수 있습니다.
각 리비전과 DeploymentGroup을 조합하여 하나의 Deployment가 만들어지고 배포가 완성됩니다.
여기서 리비전은 각 소프트웨어의 버전(1.0.0 같은)이고, aws 리전이랑 다른 거 아시죠오?

예를 들어 현재 하우스 API 서버에 개발 서버 / 테스트 서버 / 프로덕션 서버 환경에 따른 배포 그룹을 만든다면? 이 하나의 API 서버를 경우에 따라 배포할 수 있겠네요!

동일한 리비전과 동일한 Deployment Group을 지정하여 여러 번 배포가 가능하며 각 Deployment는 새롭게 생성되고 실행됩니다.


😂 우리가 만난 문제 상황

현재 팀 하우스에서는 API서버(port: 8000)와 푸쉬알림서버(port: 8001)가 있습니다.

서버 분리를 한 이유는 스케줄러를 이용해서 매번 같은 시간에 알림을 보내줘야 하는데 그 때 유저가 Api 요청을 보냈다면, 지연될 수 있지 않을까? 싶었고 이를 방지하고자 분리하였습니다.

푸쉬알림 서버에도 기존에 있던 Api 서버의 CICD yaml과 관련 설정 파일을 그대로 가져와 사용하였고 CodeDeploy에서 별도의 설정을 바꾸지 않았습니다.

그랬더니 api 서버 머지 후 push 서버 머지하면 파일이 덮히는 문제가 발생했습니다.

👋 우리의 해결 방법

동일한 리비전과 동일한 Deployment Group을 지정하여 여러 번 배포가 가능하며 각 Deployment는 새롭게 생성되고 실행됩니다.

... 저희는 삽질을 야무지게 하고, 공식문서를 본 후에야 문제를 확인했습니다 ...
오늘의 교훈... 공식문서를 잘 읽자 ...

같은 ec2에다가 배포하는 거니까 git action yaml / appspec.yml / after-deploy.sh를 모두 동일하게 가져가도 되지않을까?! 했는데요..
다른 application이지만 같은 deployment group을 갖고 있기 대문에 각 서버가 매 배포마다 새롭게 생성되어 덮히는 문제였습니다.

이를 해결하고자 다음과 같이 수정하였습니다.
1. CodeDeploy에 새 배포 그룹 추가하기

  1. 각 파일 수정
  • 빌드 파일을 push / server 라는 zip 파일로 다르게 이름을 지어 S3에 올라갈 때 겹치지 않도록 하였습니다.

2-1. git action yaml

  • api 서버
# server라는 이름으로 빌드 파일 및 deploy 시 필요한 파일 zip
- name: zip file
  run: zip -r server.zip ./dist ./scripts ./appspec.yml ./.env ./serviceAccountKey.json ./package.json
  ...
  
# 빌드 파일 S3에 업로드
- name: upload to S3
  run: aws s3 cp --region ap-northeast-2 ./server.zip s3://hous-build/deploy/

# codeDeploy agent를 통해 배포 진행, 배포그룹은 GROUP
- name: deploy with AWS codeDeploy
  un: aws deploy create-deployment
      --application-name hous-codedeploy
      --deployment-config-name CodeDeployDefault.OneAtATime
      --deployment-group-name GROUP
      --s3-location bucket=hous-build,bundleType=zip,key=deploy/server.zip 
  • push 서버
# push 이름으로 빌드 파일 및 deploy 시 필요한 파일 zip
- name: zip file
  run: zip -r push.zip ./dist ./scripts ./appspec.yml ./.env ./serviceAccountKey.json ./package.json

# 빌드 파일 S3에 업로드
- name: upload to S3
  run: aws s3 cp --region ap-northeast-2 ./push.zip s3://hous-build/deploy/

# codeDeploy agent를 통해 배포 진행, 배포그룹은 GROUP
- name: deploy with AWS codeDeploy
  un: aws deploy create-deployment
      --application-name hous-codedeploy
      --deployment-config-name CodeDeployDefault.OneAtATime
      --deployment-group-name PUSH
      --s3-location bucket=hous-build,bundleType=zip,key=deploy/push.zip 

2-2. appspec.yml

  • api 서버
# ec2에 /home/ubuntu/server위치에 server.zip 파일 압축 풀어서 넣기
version: 0.0
os: linux
files:
  - source: /
    destination: /home/ubuntu/server
    overwrite: yes
  • push 서버
# ec2에 /home/ubuntu/push push.zip 파일 압축 풀어서 넣기
version: 0.0
os: linux
files:
  - source: /
    destination: /home/ubuntu/push
    overwrite: yes

2-3. after-deploy.sh

  • api 서버
#!/bin/bash
REPOSITORY=/home/ubuntu/server 

cd $REPOSITORY #/home/ubuntu/server 위치로 가서

sudo /usr/bin/yarn #yarn 실행하여 라이브러리 추가 설치

sudo /usr/bin/pm2 start dist #dist 파일 실행
  • push 서버
#!/bin/bash
REPOSITORY=/home/ubuntu/push

cd $REPOSITORY #/home/ubuntu/push 위치로 가서

sudo /usr/bin/yarn  #yarn 실행하여 라이브러리 추가 설치

sudo mv dist push #기존에 API 서버가 dist로 돌고 있으니까 파일명 변경

sudo /usr/bin/pm2 start push #빌드 파일 실행
  • pm2 옵션 중 하나인 --name을 이용하여 실행할 서버명을 변경하려고 시도했지만, 파일이 덮혀서 mv 명령어로 빌드 파일명을 변경하였습니다.

이렇게 파일을 변경하고 git action이 돌면 !!!!!!

이렇게 디렉토리가 생겨서 푸쉬 서버와 api 서버가 합쳐지지 않고!!!!

pm2 list를 실행해보면,

잘 실행되는 것을 볼 수 있답니다..!

저희처럼 혹시 서버를 분리했는데 둘 다 CICD를 적용하고 싶다면!!!!
먼저 CodeDeploy를 이해하고 적용하면 좋을 것 같아 기본 개념과 저희의 삽질 과정을 글로 녹여보았습니다.
삽질에 3시간을 쏟는 것을 아껴요 우리 모두!~~!


참고자료

AWS CodeDeploy 공식 문서
기술 블로그

profile
대학생연합 IT벤처창업 동아리 SOPT 30기 SERVER 파트 기술 블로그입니다.

0개의 댓글