시작하기에 앞서

안녕하세요, 영훈입니다. 이번에는 Traivs CI, AWS CodeDeploy, Docker를 활용해 CI/CD 환경을 구축하는 글을 작성했습니다.

이 글을 작성하기전 제가 Travis CI와 Docker를 공부하면서 어떻게 배포 자동화 환경을 구축할 수 있을까 고민을 많이 했는데요 이번 튜토리얼을 진행하면서 저와 같은 고민을 가지신분들에게 확실히 도움이 될 거라고 생각합니다.

이번 튜토리얼은 node.js로 진행하며 진행하기 위해서는 꼭 AWS 계정이 있어야 합니다.
또한 Travis CI, Docker에 대해서 잘 모르시거나 기억이 안나신다면 아래 짧게 설명한 개념정리를 읽어주시고 특히 도커에 대해서 잘 알지 못하신다면 https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html 에서 도커에 대해서 학습하시길 추천드립니다.

그럼 시작하겠습니다.

개념 정리

Travis CI

Travis CI는 깃허브와 연동해서 사용하는 웹 서비스입니다. 깃에 push 이벤트가 일어나면 Travis CI는 해당 이벤트를 감지해 코드를 빌드 밑 테스트를 해줍니다. 하지만 아쉽게도 Travis CI는 이름과 같이 CI만 할 수 있는 툴이라서 직접 코드배포는 할 수 없습니다.

Docker

도커를 간단하게 설명하자면 원하는 os 환경을 이미지로 만들어 저장한 다음 저장한 이미지를 실행해 컨테이너로 만들어 하나의 os에서 여러개의 os를 실행할 수 있는 기술입니다. 자세한 이해는 https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html 해당 튜토리얼을 통해 이해하시면 될 것 같습니다.

구축할 배포 자동화 환경 구조

이 튜토리얼을 진행하면서 완성할 구조는 아래 그림과 같습니다. 아래 그림에 대해서 단계별로 설명하겠습니다.

스크린샷 2019-01-22 오후 10.30.27.png

1단계

일단, 제가 애용하는 툴은 vscode라서 vscode를 넣어놨습니다! 어떤 에디터에서든지 상관없이 코딩을 하고 깃허브에 push를 합니다.

2단계

깃헙 레파지토리에 푸쉬 이벤트가 일어나면 깃헙은 Travis CI에게 소스코드를 보냅니다. ( Travis CI에게 소스코드를 보내기 위해서는 Travis CI와 깃헙 레파지토리가 연동되어 있어야 합니다 )

3단계

Travis CI는 깃헙 레파지토리가 보내준 소스코드들을 테스트하고 빌드해줍니다.

4단계

4단계에서는 빌드된 파일들을 Travis CI가 AWS S3에 업로드를 합니다.

Travis CI는 이름대로 CI라서 코드 배포를 못합니다! 그렇기 때문에 코드를 배포할 수 있겠금 무언가가 도와줘야합니다. 그 무언가가 AWS 입니다! AWS에는 Code Deploy라는 훌륭한 기능들과 S3라는 저장소가 있습니다.

5단계

Travis CI가 S3에 빌드된 파일을 보내준후 이제 배포해~ 라는 명령어 스크립트를 CodeDeploy에게 전달합니다.

6단계

CodeDeploy는 Travis CI로 부터 온 배포해 라는 명령어 스크립트를 실행해 S3로 부터 파일을 가져온 후 배포 작업을 시작합니다.

7단계

CodeDeploy는 AWS거라서 EC2랑도 연동이 됩니다. CodeDeploy는 S3에서 받은 파일을 해당 인스턴스에 넣어준후 EC2 내부에 정의된 배포 스크립트를 실행해 줍니다.

8단계

CodeDeploy가 EC2 내부에 정의된 배포스크립트를 실행해 줌으로 EC2 내부적으로 배포를 진행합니다. EC2 내부에 정의된 배포스크립트는 무중단배포를 가능하게끔 스크립트가 작성되어 있습니다.

준비하기

일단, https://github.com/jeffchoi72/node-koa-server/tree/travis-ci-cd-start 에서 소스코드를 클론 받고 해당 소스코드로 자신의 깃헙 레파지토리를 생성합니다. ( 브랜치가 travis-ci-cd-start 인 소스코드로 깃헙 레파지토리를 만들어 생성하세요 )

스크린샷 2019-01-27 오후 9.18.57.png

그 후 해당 프로젝트에서 yarn install && yarn dev 명령어를 실행하신 후 브라우저로 http://localhost:3000 주소에 접속해 주세요.

스크린샷 2019-01-21 오후 9.11.22.png

이런 화면이 뜬다면 성공입니다.

Travis CI 연동하기

이제 Travis CI를 깃헙과 연동하겠습니다. https://travis-ci.org/ 에 접속하셔서 회원가입을 해주세요

스크린샷 2019-01-22 오후 10.45.11.png

회원가입을 완료하시면 대시보드에서 오른쪽 상단 부분에 있는 자신의 프로필을 클릭한 다음 Settings를 눌러주세요

스크린샷 2019-01-21 오후 9.36.55.png

그 후 아까 만든 깃헙 레파지토리를 찾아 토글버튼을 활성화 시켜주세요

스크린샷 2019-01-21 오후 9.32.32.png

다시 대시보드로 돌아오셔서 위와 같은 화면이 뜬다면 Travis CI와 깃헙 레파지토리는 연동 되었습니다.

하지만 연동만 했을 뿐 깃헙에 push 이벤트가 발생하면 Travis CI가 어떤 행동을 해줄지 정의 해 주지 않았습니다. 정의 해 주도록 하겠습니다.

Travis CI 행동 정의하기

Travis CI의 행동을 정의해주는 역할은 바로 .travis.yml 이라는 파일인데요 이 파일에 적혀져있는데로 Travis CI는 행동을 합니다.

스크린샷 2019-01-23 오전 9.21.11.png

우선, 아까 깃헙에서 클론 받은 소스코드를 에디터로 열어주세요 저는 Vscode를 사용하니 vscode로 진행하겠습니다.

스크린샷 2019-01-23 오전 9.22.26.png

해당 프로젝트 루트 디렉터리에 .travis.yml 파일을 만들어주신 후 .travis.yml 파일에 다음과 같은 내용을 작성해주세요

language: node_js # 언어는 node_js
node_js:
  - "10.14" # node_js에 버전 10.14
before_install: # 패키지를 다운로드 받기 전
  - npm install -g yarn  # yarn을 글로벌로 설치
branches:
  only:
    - master
notifications: # 성공 실패 여부 알림 
  email:
    recipients:
      - dev.jeffchoi@gmail.com

.travis.yml 내용을 해석해 보자면 저희 프로젝트는 node.js를 사용하기 때문에 language에 node_js를 적어주었습니다. ( 버전은 10.14 ) 또한 패키지 매니저를 yarn을 사용하기 때문에 before_install에 따로 yarn을 설치해 주어야 합니다. 그리고 깃헙 브랜치는 master만 사용하기 때문에 다음과 같이 작성해 주었습니다. 그리고 빌드 성공 및 실패 결과를 어떤 메일로 보내줄지도 적어주었습니다.

이제 깃헙 레파지토리에 커밋 후 푸쉬를 해주세요

스크린샷 2019-01-24 오전 8.44.09.png

빌드가 되고 있습니다.

스크린샷 2019-01-24 오전 8.45.29.png

하지만 실패했네요

스크린샷 2019-01-24 오전 8.46.13.png

실패 원인을 살펴보니 yarn test 라는 스크립트 명령어가 없어서 그랬습니다.

Travis CI는 테스트와 빌드를 하는 툴입니다. 그렇기 때문에 Travis CI는 테스트를 시도했고 yarn test라는 테스트 스크립트가 없어서 에러가 나는 것 입니다. 테스트 코드를 작성해도 되지만 이 글은 테스트코드를 중점으로 다루지 않기 때문에 테스트를 생략하겠습니다.

package.json을 열어 scripts에 다음과 같이 "test": "exit"을 추가해 주세요

스크린샷 2019-01-24 오전 8.53.35.png

다시 깃헙에 코드를 푸쉬해줍니다.

스크린샷 2019-01-24 오전 8.56.38.png

성공했습니다.

코드 배포를 위한 AWS 설정하기

깃헙 레파지토리와 Travis CI를 연동했습니다. 하지만 Travis CI에서는 테스트가 끝난 코드들을 서버로 직접 배포해주는 기능이 없습니다.

그렇기 때문에 부가 기능을 사용해야 하는데요 바로 AWS S3와 AWS CodeDeploy 라는 기능을 사용해야 합니다 ( 왜 사용하는지 궁금하다면 위에 있는 구축할 CI/CD 구조를 읽어 주세요).

하지만 AWS S3와 AWS CodeDeploy를 사용하려면 여러가지 설정 작업들을 해야합니다.

그럼 설정 작업들을 시작하겠습니다.

EC2 만들기

우선, 저희가 배포할 서버를 만들어 줍시다!

AWS 대시보드에 있는 인스턴스를 클릭 후 인스턴스 시작하기로 원하는 os와 옵션들을 선택해 주세요

다음과 같이 만들어 졌다면 성공입니다.

스크린샷 2019-01-24 오전 9.14.17.png

그 후 보안그룹을 클릭 하신 후 인바운드에 들어가셔서 편집을 누르신 후 다음과 같이 HTTP 80번 포트를 허용해 주세요

스크린샷 2019-01-24 오전 9.12.52.png

AWS S3 버킷 만들기

Travis CI에서 빌드한 코드들을 보관할 저장소가 바로 AWS S3입니다. AWS S3에 코드들을 저장할 버킷을 만들어 줍시다.

AWS 대시보드 기준으로 최상단 위에 있는 서비스를 클릭하신 후 S3를 검색하신 후 다음과 같은 페이지로 접속해 주세요

스크린샷 2019-01-24 오전 9.19.48.png

버킷만들기를 클릭하신 후 버킷 이름을 입력하신 후 끝날때까지 다음을 눌러주세요

스크린샷 2019-01-24 오전 9.21.22.png

그럼 다음과 같이 버킷이 만들어진 모습을 볼 수 있습니다.

스크린샷 2019-01-24 오전 9.21.48.png

Travis CI 배포 전용 계정 만들기

Travis CI가 코드를 배포하기 위해서는 AWS 계정이 필요합니다. 그렇기 때문에 Travis CI가 쓸 수 있는 배포 전용 계정을 만들겠습니다.

똑같이 서비스에서 IAM 을 검색하신 후 다음과 같은 페이지로 들어와 주세요

스크린샷 2019-01-24 오전 9.34.06.png

IAM 이란

권한 및 서브 계정들을 관리하는게 IAM 입니다.

스크린샷 2019-01-24 오후 10.55.36.png

사용자를 클릭 하신 후 사용자 추가를 눌러주세요, 그 후 다음과 같이 사용자 이름을 적어주고 AWS 액세스 유형에 프로그래밍 방식 액세스를 체크해 주세요

스크린샷 2019-01-24 오후 10.56.21.png

그런 다음 권한 설정에서 기존 정책 직접 연결을 누르시고 AmazonS3FullAccess와 CodeDeployFullAccess를 검색 하신 후 체크해 주세요 왜냐하면 저희는 이 계정으로 S3와 AWs CodeDeploy를 이용하려고 하기 때문입니다.

스크린샷 2019-01-24 오후 10.58.03.png

아래와 같은 화면이 나오면 성공입니다.

스크린샷 2019-01-24 오후 11.01.08.png

그 후 csv를 다운로드 해주세요 아주아주 중요합니다.

스크린샷 2019-01-24 오후 11.02.19.png

AWS 역할 생성하기

앞에서 Travis CI가 배포할 수 있는 계정을 만들었습니다. 이번에는 저희가 배포에 사용할 EC2와 CodeDeploy에게 신뢰할 수 있는 권한을 설정해야 Travis CI가 정상적으로 배포할 수 있습니디.
권한을 설정해주는게 바로 IAM 역할 입니다.

EC2 CodeDeploy IAM role 생성

역할과 role은 같은 말입니다.

우선, EC2 IAM 역할을 생성하겠습니다.

IAM 대시보드 왼쪽 부분에 역할을 누르신 후 역할만들기를 눌러주세요

스크린샷 2019-01-25 오전 9.08.56.png

역할 만들기에서 AWS 서비스를 누르신 후 밑에 있는 EC2를 눌러주세요

스크린샷 2019-01-25 오전 9.11.51.png

그 후 밑으로 내리신 후 EC2와 사용 사례에서 EC2를 클릭하고 다음으로 넘어가주세요

스크린샷 2019-01-25 오전 9.12.30.png

권한 정책에 AmazonEC2RoleforAWSCodeDeploy을 검색해서 클릭하시 후 다음을 눌러주세요

스크린샷 2019-01-25 오전 9.14.51.png

태그는 그냥 다음을 눌러주세요 이제 역할 이름을 설정해주는데 알아보기 쉽게만 해주시면 됩니다.

스크린샷 2019-01-25 오전 9.17.12.png

자 생성되었습니다. 지금 만든 역할을 아까만든 EC2에 IAM 역할로 설정 할 것 입니다.

AWS CodeDeploy role 생성

EC2 CodeDeploy IAM 역할과 마찬가지로 CodeDeploy 도 역할을 생성하겠습니다.

아까처럼 역할만들기를 누른 다음 CodeDeploy를 다음과 같이 선택해 주세요 그 후 다음을 누릅니다.

스크린샷 2019-01-25 오전 9.26.53.png

AWSCodeDeployRole 밖에 없어서 자동으로 선택됩니다. 다음을 눌러주세요

스크린샷 2019-01-25 오전 9.28.31.png

태그 추가도 다음으로 눌러주세요

이제 아까와 마찬가지로 알아보기 쉽게만 역할이름을 적어주세요 이름을 정하셨다면 역할을 만들어 주시면 됩니다.

스크린샷 2019-01-25 오전 9.30.13.png

EC2에 AWS 역할 적용하기

아까 만든 EC2 Deploy Role을 사용할 인스턴스에 적용해야 합니다. 인스턴스 대시보드로 가셔서 사용할 인스턴스를 마우스 오른쪽 클릭하신 후 다음과 같이 IAM 역할 연결/바꾸기를 눌러주세요

스크린샷 2019-01-25 오전 9.35.23.png

다음과 같이 아까만든 EC2 Deploy Role을 적용해 주세요

스크린샷 2019-01-25 오전 9.36.59.png

EC2 AWS CodeDeploy Agent 설치 및 설정

사용할 인스턴스에 AWS CodeDeploy 이벤트를 처리할 에이전트를 설치해야 합니다. 터미널로 해당 인스턴스에 접속해 주세요

스크린샷 2019-01-25 오전 9.40.11.png

그 후 다음과 같은 명령어를 입력해 AWS CodeDeploy 에이전트를 설치해 주세요

sudo apt-get install awscli

스크린샷 2019-01-25 오전 9.40.56.png

에이전트를 설치한 후 sudo aws configure 명령어를 터미널에 입력해 주세요 그 후 아까 받은 csv 파일에 있는 Access Key ID와 Secret Acecess Key를 적어주세요 그리고 기타 정보는 아래 스크린샷과 같이 적어주세요

스크린샷 2019-01-26 오후 7.40.12.png

설정을 잘 하셨다면 다음 명령어를 터미널에 입력해 주세요

aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2

스크린샷 2019-01-26 오후 7.43.01.png

그 후 디렉터리를 보면 install 파일이 생성되어있는 것을 볼 수 있습니다. 해당 install 파일을 실행할 수 있게 실행할 수 있는 권한으로 바꿔주세요

스크린샷 2019-01-26 오후 7.43.55.png

그 후 sudo ./install auto 명령어를 터미널에 입력해 AWS CodeDeploy 에이전트를 설치해 주세요 만약 아래와 같이 /usr/bin/env: 'ruby': No such file or directory가 나온다면 sudo apt-get install ruby 를 해주시고난 후 다시 시도해 주세요

스크린샷 2019-01-26 오후 7.45.51.png

이제 sudo service codedeploy-agent start로 AWS CodeDeploy 에이전트를 실행해 주세요 그리고 잘 실행되고 있는지 sudo service codedeploy-agent status 명령어로 확인합니다.

스크린샷 2019-01-26 오후 7.49.11.png

다음 시리즈로

자 이제 모든 AWS 설정을 다했습니다. 다음 편에서는 Travis CI로 AWS와 연동해 배포 자동화와 더 나아가서 도커를 사용해 무중단 배포를 진행하겠습니다.

다음 시리즈가 준비되어있습니다. 아래 링크를 클릭해 주세요

https://velog.io/@jeff0720/Travis-CI-AWS-CodeDeploy-Docker-%EB%A1%9C-%EB%B0%B0%ED%8F%AC-%EC%9E%90%EB%8F%99%ED%99%94-%EB%B0%8F-%EB%AC%B4%EC%A4%91%EB%8B%A8-%EB%B0%B0%ED%8F%AC-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0-2