회사 기술블로그에 제가 올린 글을 다시 가져왔습니다. 출처: https://madup-inc.github.io/2018/05/29/travis2.html

안녕하세요 1년차 개발자 윌리입니다, 배포자동화 경험담을 포스팅합니다. 전편이 실패담이면 이번에는 어떻게 적용했는지 가 주요 내용입니다. —

1편 TL; DR

Jenkins CI -> Circle CI -> AWS Pipeline 순으로 한 번씩 사용했습니다.

‘고등학교 때 리눅스 잘할껄’ 하고 눈물 흘리며 Travis CI를 사용하기로 했습니다.


Travis CI

캐시, 빌드, 배포

sbt 사이트에 Travis CI 매뉴얼이 있어 캐싱과 빌드까지는 별다른 어려움이 없었습니다. 캐시를 위한 디렉토리만 지정해주면 됩니다.

[https://www.scala-sbt.org/1.0/docs/Travis-CI-with-sbt.html]

cache:
  directories:
    - $HOME/.ivy2/cache
    - $HOME/.sbt

계속 겪어온 AWS Elastic Beanstalk과 연동하는 문제 역시 Travis에서 지원해주는 배포 툴 중 하나이기에 딱 배포하는 것 까지는 문제가 없었습니다. 도중에 배포는 잘되지만 엉뚱한 S3 경로에 들어가는 실수를 하긴 했지만 bucket_path를 지정해서 해결했습니다.

[https://docs.travis-ci.com/user/deployment/elasticbeanstalk/]

  deploy:
    skip_cleanup: true
    provider: elasticbeanstalk
    access_key_id: $ACESS_KEY_ID #aws access key
    secret_access_key:
      secure: $SECRET_ACESS_KEY #aws secret key
    region: "ap-northeast-2"
    app: $APP_NAME # eb 앱이름
    env: $ENV_NAME # eb 환경이 여러개일때 지정
    bucket_name: $EB_BUCKET # S3 버킷이름 '/'가 들어가면 에러
    zip_file: $TARGET #산출물
    bucket_path: $BUCKET #버킷안에서 경로
    on:
      repo: $REPOSITORY # GitHub 저장소
      branch: $BRANCH #브랜치

몇 가지 헷갈렸던 옵션들만 주석으로 기재합니다.

이렇게 하면 일단 배포는 되지만 문제가 생겼습니다. S3에 앱 이름이 이상하게 되어있는 걸 발견했습니다.

travis-e797dccf4be4d459b110c7585ebc83860a2f4f6f-1524574195.zip

결국 제가 앱 이름을 지정하는 방법을 찾다가 간단한? 쉘 코드를 짜서 앱 이름으로 쓰는 환경변수를 바꾸기로 했습니다.

before_deploy:
  - export ARTIFACT_PRE=$(echo $TRAVIS_REPO_SLUG | sed  s_^.*/__)
  - export ARTIFACT_NAME=app-$(git describe --tags)
  - export ELASTIC_BEANSTALK_LABEL=$(echo $ARTIFACT_NAME)

슬랙연동

슬랙연동은해줄 일이 정말 없습니다. 슬랙에서 APP을 추가해서 토큰을 받아온 후 그 토큰을 yml에 기재하면 끝입니다.

notifications:
  slack:
    rooms:
      - 슬랙팀:토큰#tech_dev_travis

만약에 여러가지 방에 연동하거나 다른 슬랙메세지를 직접 고치고 싶다면 다음 링크를 참조하세요

[https://docs.travis-ci.com/user/notifications/]

테스트

아직도 해결이 안된 부분이고 가장 힘든 부분입니다. revenue 백앤드 코드의 대부분은 DB 작업인데 (가장 복잡하고 최근에 리팩토링한 부분도 DB 작업을 대신해주는 인터페이스) DB는 몇몇 EC2만 접속이 가능해서 SSH 터널링을해야 API 테스트가 가능했습니다.

이 과정에서 왜 문제가 일어나는지도 몰랐고 해결방법도 모르고 결국 알아냈지만 또 문제가 생겨 쉘만 잔뜩 만들었습니다.

대략적으로 겪었던 과정은 다음과 같습니다.

  1. db 접속 확인을 위해 테스트 후 결과를 저장하고 DB 커넥션 관련 에러만 보여주는 쉘을 작성
  2. 제이슨이 SSH로 접속하는 방법을 알려줌
  3. 신디와 같이 터널링에 사용할 Key 저장
  4. 터널링 적용
  5. 터널링을 백그라운드에서 돌려야 된다는 것을 깨달음
  6. 로컬과 다르게 Travis에서는 ‘&’를 이용해 백그라운드에서 프로세스를 돌리기가 어려움
  7. screen, tmux 등의 명령어로 백그라운드 실행을 하려 했으나 화면 전환은 키보드로만 가능하여 테스트는 보류됨

후기

  1. 프론트 개발자 신디의 선호
  2. 테스트 적용 중에 Travis가 다른 CI에 비해 커스텀하기 불편한 점을 느낌
  3. S3에 파일이 .war가 아니라 .zip으로 들어가게 찜찜함

위 3가지 때문에 제이슨은 저에게 다시 한 번 Circle CI로 자동화를 해보는것을 제의했습니다.

Travis는 비교적 쉽고 문서와 지원되는 기술이 정말 잘 되어있습니다. 단점으로는 리눅스처럼 쓰는 데는 약간의 무리가 따릅니다. 구관이 명관이라더니… Jenkins CI가 더 좋은 점도 있었습니다.


다시 Circle CI

yml 작성

이미 한 번 해본거니 1,2일안에 끝날줄 알았지만 실수를 많이 해서 제이슨의 캐리를 받았습니다.

version: 2
jobs:
  build:
    docker:
      - image: circleci/openjdk:8-jdk

    steps:
      - run:
          name: Installing Deployment Dependencies
          command: |
            sudo apt-get -y -qq update
            sudo apt-get -y install python-pip python-dev build-essential
            sudo pip install awscli awsebcli --upgrade

      - checkout

      - run:
          name: Build Package
          command: sbt package

      - run:
          name: Package Deployment
          command: eb deploy

workflows:
  version: 2
  build_and_deploy:
    jobs:
      - build

몇몇 부분들과 잘안된 캐시 부분은 제외한 config.yml 입니다.

실수들

굉장히 간단한 yml이지만 엄청 많이 실수를 남발했습니다. 반성하는 의미에서 적습니다.

  1. awscli가 아니라 awseb 만 설치해 버림
  2. 1번을 모른 상태에서 HOME 디렉토리에 .aws 디렉토리와 파일이 없는걸 깨닫고 고민함
  3. 환경변수로 aws 키를 넣어두고 쉘로 .aws 디렉토리와 파일 만듬
  4. 제이슨의 지적으로 awscli를 설치하고 설정에 넣어둔 키가 잘들어가는 것을 확인함

후기

확실히 Circle CI가 빠르긴 빨랐습니다.

테스트도 없고 여러가지 언어나 환경에서 빌드할 일도 없는 프로젝트를 굳이 Circle CI로 해야 되냐는 고민이 생겼습니다. Circle CI에 장점은 도커환경 위에 리눅스처럼 여러가지를 커스텀 할 수 있고 다양한 workflow를 쓸 수 있다 입니다. 단점은 리눅스를 잘해야 되는데 이럴거면 굳이 안써도 된다는 생각이 들었습니다.


Travis CI VS Circle CI

현기증나니깐 뭐 하나 정해 써요

두 가지 CI 사용해 매번 푸쉬할 때 마다 두 중 하나를 수동으로 정지시키는 고생을 하다가 제이슨과 신디에게 빨리 하나만 정해서 쓰자고 재촉해서 결국 Travis CI를 사용하기로 했습니다. 저희 프로젝트가 복잡하지 않은 점과 Travis를 이미 결제한게 큰 영향을 끼친 것 같습니다.

그 후에는 master 브랜치 설정을 추가해서 배포자동화를 완료했습니다.

branches:
  only:
    - develop
    - master

어떤 CI를 어떻게 쓰고 싶은가?

이번에 4가지 CI로 5번의 배포자동화를 해보면서 각 CI를 어떻게 쓰고 싶냐고 물어보면 이렇게 쓰고 싶습니다.

Jenkins CI : 정부과제, 대기업 외주, 개인 프로젝트

Travis CI : 오픈소스, 여럿이서 프로젝트 할 때

AWS Pipeline : 고객이 AWS를 고집할 때

Circle CI : 개인 프로젝트, 무료로 쓰고 싶을 때

- 이건 회사 의견과 상관없는 개인적 생각입니다.


후기

배포자동화를 거의 2달을 하면서 제일 많이 한 생각은 ‘고등학교 때 소장님 수업(리눅스)좀 많이 물어볼 걸’ 입니다. 서버 운영과 배포 자동화, 임베디드에서는 리눅스를 정말 잘 해야한다고 느꼈습니다.

그 다음으로 드는 생각은 제이슨에게 감사함을 느낍니다. 아마 제이슨이 없었면 제 리눅스 실력으로 2달은 더 걸렸을 것 입니다.