개발에 집중 할 수 있는 환경 만들기

개발에 집중 할 수 있는 환경 만들기

이제 곧 있으면 러닝스푼즈 조직에 합류한지 2개월이 된다. 짧다면 짧은 시간이지만 이것저것 손댄 것이 제법 되는 것 같다. 그 중 오늘 정리한 따끈한 배포 자동화에 대해 정리해본다.

상황의 인지

처음 이 곳에 왔을때 어떤 문제들이 있고 이 문제들을 어떻게 처리해나갈지를 고민하고 계획하는 것이 0순위 과제였다. 어느 곳을 가나 레거시는 존재한다. 새로운 조직에서의 흔히 엔지니어는 레거시를 거둬들이고 새로운 기술을 도입하려는 기대와 열의를 보이기 시작한다. 이 지점을 가장 경계해야한다. 레거시를 없애기 위해 자칫 차세대라는 이름으로 새로운 레거시를 만들게 되고 그 결과 기존 레거시를 포함해 새로운(?) 레거시가 2개, 3개로 늘어나게 되는 것을 많이 봐왔다. 나 자신에게 중심 잡기를 바라는 셀프 가스라이팅이 필요했다.

바깥으로는 현업 담당자들과 기존 업무 이야기를 청취하고 내부적으로는 시스템의 개선점을 찾아 하나씩 이슈들을 모으기 시작했다. 그 결과 바로 개선할 수 있는 점과 중장기적으로 가져가야할 개선점, 그리고 기술적인 범위로는 해결이 어려운 전체적인 이슈들로 분류가 되기 시작했다.

여기서 바로 개선할 수 있는 과제들 사이에서 가장 생산성을 높일 수 있는 과제로는 배포 자동화를 꼽게 되었다. 여태까지의 배포 방법은 직접 인스턴스에 접속해서 “레포지토리에서 코드를 pull -> 정적리소스 캐시 초기화 -> nginx 재시작” 이라는 원초적인 방법을 사용해왔으며 사람의 손으로 여러 커맨드를 타이핑해야하는 상태였다.

해결할 과제를 한번 더 쪼개기

현재 이러한 배포 과정을 한번에 배포 자동화를 하는 것도 좋지만 내가 이 작업에만 집중을 할 수는 없기 때문에 중간 중간 잉여시간을 활용할 수 있도록 task 단위로 단계를 다시 분리해나가기로 했다.

  • 1단계: 커맨드를 쉘스크립트 파일로 묶어 수동 타이핑을 최소화
  • 2단계: 프로젝트를 Docker 컨테이너로 만들어 로컬 환경 구축하고 테스트
  • 3단계: ECS를 이용해 Docker 이미지 배포 방식으로 전환
  • 4단계: Gitlab CI/CD 기능을 이용해 자동 배포 프로세스 구축

이 과정 사이에도 몇 가지 바꾼 부분이 있었는데 형상관리 툴을 기존 Bitbucket에서 Gitlab으로 변경했다. Github와 Gitlab 사이에서 고민을 했고 Gitlab을 채택한 이유에 대해서는 주제가 다르니 따로 정리해봐야겠다.

1단계 – 쉘스크립트 배포

기존의 방식으로 SSH 터미널 접속 후 배포를 진행하면서 이 과정이 왜 필요한지 하나씩 분석해나갔다. 그리고 이것들은 고정된 명령어들이었다는 결론을 지었다. 바로 커맨드들을 정리해서 deploy.sh 이라는 쉘스크립트 파일을 만들어 커맨드를 순차적으로 작성했다. 이것으로 배포하는데 걸리는 시간이 드라마틱하게 줄지는 않았지만 휴먼 에러는 완벽히 제거할 수 있었다. 그리고 배포에 대한 부담이 상당부분 줄었다. 하지만 이 과정은 기존 배포의 번거로움을 피하기 위한 방법이고 미봉책에 불과하기에 바로 다음 단계로 넘어간다.

2단계 – 프로젝트 Docker 이미지화

프로젝트를 로컬에 세팅을 할 수 있지만 이 곳도 프로젝트가 하나만 존재하는 것은 아니었고 여러 프로젝트가 동시에 개발된 것이 아니기 때문에 사용되는 파이썬 버전이 달랐다. 또한 사용 중인 DB의 버전도 달랐기에 로컬에서 만큼은 Docker 환경이 불가피한 상황이었다. 여러 번의 삽질 끝에 프로젝트와 DB를 각각 Docker 이미지로 만들었고 로컬 개발 환경을 세팅하는데 성공했다. 가이드를 만들어 필요한 동료들에게 도커 환경을 세팅해줬다. 이제 오프라인 환경에서도 프로젝트를 띄우고 작업도 가능해졌다. 이 Docker 이미지를 가지고 서비스 배포에 적용할 차례가 왔다.

3단계 – AWS ECS 배포 환경 구축

이제 로컬이 Docker 기반 환경으로 맞춰진 이상 AWS ECS 구축 환경을 쓰지 않을 이유가 없었다. 그리고 내가 합류하기 전부터 진행하려했던 미션이 스케일아웃과 CI/CD 적용이었다. 그럼 모든 퍼즐이 여기에서 맞춰지기 시작한다는 판단을 할 수 있었다. ECS 세팅을 하면서 자연스럽게 ELB를 앞단에 두게 될 것이고 ECS 서비스를 유연하게 늘리고 줄일 수 있게 되면서 스케일인/아웃 효과를 볼 수 있다. 개발 환경 구축을 시작했고 ECS를 EC2로 사용할지 서버리스인 Fargate를 사용할지 결정이 필요했다. 개발 환경은 크게 고민이 필요없었다. 업무 시간에 적은 빈도로 사용되는 환경인데 현재 EC2 인스턴스로 떠있는 것 자체가 낭비라고 생각을 했고 Fargate를 이용한다면 비용면에서도 이점을 가져갈 수 있다고 판단했다. 추후 운영 환경에서는 EC2와 Fargate 간에 비용 측정이 필요하다. 상시로 트래픽이 유지되는 서비스에서는 자칫 EC2보다 큰 비용이 발생할 수 있기 때문이다. 이제 예전처럼 직접 인스턴스에 접속하지 않고 로컬 터미널에서 AWS CLI를 이용해 배포가 가능해졌다.

4단계 – Gitlab CI/CD 구축

이제 마지막 단계. 이것까지 완료된다면 배포에 있어서는 신경쓸일이 획기적으로 줄어들고 개발에 집중할 수 있는 환경이 만들어진다. 더 이상 터미널에서 손으로 배포할 일이 없어진다는 것이다. 물론 개발 환경 기준으로 운영에서는 좀 더 제약이 설정될 필요가 있다. 하지만 이 마저도 브랜치 머지 정책을 활용한다면 제어가 가능한 부분이다. 도커 이미지를 빌드 후 태깅하고 배포 권한을 가진 IAM 계정을 통해 ECR에 이미지를 푸시한다. 그리고 ECS 서비스를 업데이트하는 과정을 포함해 gitlab-ci.yml 파일로 정의한다. 여기서 애를 좀 먹은 것이 구글링으로 검색해서 찾은 예시들이 비교적 최근 자료임에도 불구하고 에러가 발생했다. ChatGPT는 질문의 퀄리티가 적절하지 않았는지 정신을 못차린다. 틀렸는데 계속 맞다고 한다.. 에러 원인을 하나씩 조사해가면서 도장깨기를 했고 결국 성공했다. 이 내용은 따로 다뤄도 되겠지만 내가 겪은 에러 중 하나는 venv를 활성화하지 않고 바로 pip 명령으로 패키지를 설치하려고 한 경우였다. 이제 개발환경은 develop 머지를 했을때 gitlab ci/cd 기능의 트리거가 발동하면서 배포가 자동으로 진행된다. 단점이라면 배포를 할때마다 Docker 이미지를 빌드하는데 걸리는 시간이 소요된다는 점인데 PHP처럼 코드 수정하고 새로고침하는 수준의 극단적인 상황이 없을 것이니 문제는 없다.

마치며..

개발과 관련된 주제를 가지고 소스 코드 하나 없이 글로 풀어내어 보았다. 이 글의 요점은 어떤 기술로 문제를 해결했다가 아니다. 주어진 상황에서 어떤 도구나 기술을 적절하게 활용하는 것인가의 고민과 그걸 실행해서 결과를 만들어낸 과정을 정리해본 글이다. 조금은 재래식 같아도 어떤 상황에서는 최선이고 최적의 도구일 수 있다. ‘이건 왜 이렇게 한거야?’라는 생각보다는 ‘지금은 더 좋은 방법이 있으니 개선해보자’로 접근하는 습관을 연습해보도록 하자. 어떤 일을 하든 마찬가지겠지만 해결이 필요한 과제가 있기에 우리가 일을 하는 것이다. 반대로 모든게 완벽하고 문제가 없다면 우린 일을 할 필요가 없다. 다만 일을 무조건 처리하는 방식보다는 줄일 수 있는 일은 줄이고 더 가치있는 과제에 도전하는 것이 바람직해보인다.

%d 블로거가 이것을 좋아합니다: