스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - Travis CI 배포 자동화

화나·2021년 2월 8일
0
post-thumbnail

1. CI/CD ?

  • CI(Continuous Integration, 지속적 통합) : VCS 시스템에 PUSH가 되면 자동으로 테스트와 빌드가 수행되어 안정적인 배포 파일을 만드는 과정
  • CD(Continuous Deployment, 지속적인 배포) : 빌드 결과를 자동으로 운영 서버에 무중단 배포까지 진행되는 과정

CI 도구를 도입했다고 해서 CI를 하고 있는 것은 아니다.

  • CI의 4가지 규칙
    1. 모든 소스코드가 현재 실행되고 누구든 현재의 소스에 접근 할 수 있는 단일 지점을 유지할 것
    2. 빌드 프로세스를 자동화해서 누구든 소스로부터 시스템을 빌드하는 단일 명령어를 사용할 수 있게 할 것
    3. 테스팅을 자동화해서 단일 명령어로 언제든지 시스템에 대한 건전한 테스트 수트를 실행 할 수 있게 할 것
    4. 누구나 현재 실행파일을 얻으면 지금까지 가장 완전한 실행 파일을 얻었다는 확실을 하게 할 것

    지속적으로 통합하기 위해서는 무엇보다 이 프로젝트가 완전한 상태임을 보장하기 위한 테스트 코드가 구현되어 있어야만 함

2. Travis CI와 프로젝트 연동하기

  • Travis CI : git hub에서 제공하는 무료 CI 서비스

2-1. Travis CI 웹 서비스 설정

  • Travis CI 접속 -> 로그인 -> 오른쪽 상단 프로필 -> settings 클릭
  • 내 프로젝트 활성화

2-2. 프로젝트 설정

.travis.yml : build.gradle과 같은 위치에 생성

yml? (YAML, 야믈)
쉽게 말해 JSON에서 괄호를 제거한것

#.Travis.yml
language: java
jdk:
  - openjdk8

branches:
  only:
    - master

# Travis CI 서버의 Home
cache:
  directories:
    - '$HOME/.m2/repository'
    - '$HOME/.gradle'

script: "./gradlew clean build'

#CI 실행 완료 시 메일로 알람
notifications:
  email:
    recipients:
      - 본인 메일 주소
  • branches : Travis CI를 어느 브랜치가 푸시될 때 수행할지 지정
  • cache : 같은 의존성은 다음 배포 때부터 다시 받지 않도록 설정
  • script : master 브랜치에 푸시 되었을 때 수행하는 명령어, 프로젝트 내부에 둔 gradlew를 통해 clean & build를 수행함
  • notifications : Travis CI 실행 완료 시 자동으로 알람이 가도록 설정

작성 후 마스터 브랜치에 커밋&푸시 -> Travis CI 저장소 확인

저장소에 아무런 반응이 없으면 .travis.yml파일에 오타가 있을 확률이 높다.
오타 확인 사이트에 들어가서 확인 후 다시 커밋 & 푸시하기

빌드가 성공하면 아래와 같은 결과를 볼 수 있다.

나는 한번에 성공하지 못하고 gradle assemble 에러가 났는데 gradlew에 대한 실행 권한이 없어서 난 에러였다. 그래서 branch 코드 밑에 chmod +x gradlew 코드를 추가했더니 빌드가 되었다.

3. Travis CI와 AWS S3 연동하기

S3 : AWS에서 제공하는 일종의 파일 서버, 이미지 파일을 비롯한 정적 파일들을 관리하거나 배포파일들을 관리하는 기능 지원

실제 배포는 AWS의 CodeDeploy라는 서비스를 이용하지만 S3 연동을 먼저 진행하는 이유는 jar 파일을 전달하기 위해서이다.

CodeDeploy는 저장 기능이 없어서 Travis CI가 빌드한 결과물을 S3에 보관한다.

3-1. AWS Key 발급하기

IAM(Identity and Access Management) : AWS에서 제공하는 서비스의 접근 방식과 권한을 관리함, Travis CI가 IAM을 통해 S3와 Code Deploy에 접근함

  • IAM 검색 -> 사용자 -> 사용자 추가

  • 사용자 이름 입력 -> 액세스 유형 선택

  • 권한 설정 방식 선택 -> 정책 필터 선택

  • 태그 이름 입력

  • 내가 설정한 항목 검토

  • 최종 생성 완료 후 키 생성

3-2. Travis CI에 키 등록하기

  • Travis CI 설정 화면으로 이동

  • Environment Variables 항목에 access키, secret키 등록
    여기에 등록된 값들은 이제 .travis.yml에서 $AWS_ACCESS_KEY, $AWS_SECRET_KEY란 이름으로 사용 가능

3-3. S3 버킷 생성

S3에 Travis CI에서 생성된 Build 파일을 저장하도록 구성함, S3에 저장된 Build 파일을 이후 Code Deploy에서 배포할 파일로 가져가도록 구성할 예정

  • S3 버킷 만들기

  • 버킷 이름 설정 -> 모든 퍼블릭 액섹스 차단으로 설정 후 생성

3-4. .travis.yml 코드 추가

before_deploy:
  - zip -r springboot-webservice-project
  - mkdir -p deploy
  - mv springboot-webservice-project.zip deploy/springboot-webservice-project.zip

deploy:
  - provider: s3
    access_key_id: $AWS_ACCESS_KEY
    secret_access_key: $AWS_SECRET_KEY
    bucket: springboot-webservice-build
    region: ap-northeast-2
    skip_cleanup: true
    acl: private
    local_dir: deploy
    wait-until-deployed: true
  • 수정 후 깃허브에 푸시
    아래 사진처럼 뜨면 성공!
  • S3 버킷에서 zip 파일 확인

4. Travis CI와 AWS S3, CodeDeploy 연동하기

4-1. EC2에 IAM 역할 추가하기

배포 대상인 EC2가 CodeDeploy를 연동 받을 수 있게 IAM 역할 생성

  • IAM -> 역할 -> 역할 만들기

앞에서 만들었던 IAM의 사용자와 역할의 차이
- 사용자 : AWS 서비스 외에 사용할 수 있는 권한, 로컬PC 등
- 역할 : AWS 서비스에만 할당할 수 있는 권한, EC2 등
지금 만들 권한은 EC2에서 사용할 것이기 때문에 사용자가 아닌 역할로 처리

  • AWS서비스 -> EC2

  • 정책 : AmazonEC2RoleforAWSCodeDeploy선택

  • 태그 추가

  • 이름 작성

이렇게 만든 역할을 EC2 서비스에 등록

  • 인스턴스 목록 -> 오른쪽 마우스 클릭 -> 보안 -> IAM 역할 수정

  • 생성한 역할 선택 후 저장

  • 인스턴스 재부팅

4-2. CodeDeploy 에이전트 설치

EC2에 접속해서 명령어 입력
aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2

내려받기가 성공했다면 아래와 같은 메시지가 콘솔에 출력
download: s3://aws-codedeploy-ap-northeast-2/latest/install to ./install

install 파일에 실행 권한 추가
chmod +x ./install

install 파일로 설치 진행
sudo ./install auto

설치중 ruby:No such file or directory 와 같은 에러가 발생한다면 sudo yum install ruby로 루비를 설치하면 됨

설치가 끝났으면 Agent가 정상적으로 실행되고 있는지 상태 검사
sudo service codedeploy-agent status

아래와 같이 running 메시지가 출력되면 정상
The AWS CodeDeploy agent is running as PID ****

4-3. CodeDeploy를 위한 권한 생성

CodeDeploy에서 EC2에 접근하려면 마찬가지로 권한이 필요함
AWS 서비스 이므로 IAM 역할을 생성하면 된다.

  • IAM서비스 -> 역할 -> 역할 만들기 -> CodeDeploy 선택
  • CodeDeploy는 권한이 하나뿐이라서 권한 선택없이 바로 다음으로 넘어감
  • 태그 추가
  • 역할 이름 작성 -> 역할 만들기

4-4. CodeDeploy 생성

  • CodeDeploy -> 애플리케이션 -> 애플리케이션 생성 버튼 클릭
  • 애플리케이션 이름, 컴퓨팅 플랫폼 선탤 후 애플리케이션 생성
  • 배포 그룹 생성 클릭
  • 그룹 이름 작성, 서비스 역할 선택, 배포 유형 선택
  • 환경 구성 선택, 태그 작성
  • 배포 설정 선택, 로드 밸런서 체크해제 -> 배포 그룹 생성 버튼 클릭

4-5. Travis CI, S3, CodeDeploy 연동

  • S3에서 넘겨줄 zip파일을 저장할 디렉토리 EC2 서버에 생성
    mkdir ~/app/step2 && mkdir ~/app/step2/zip

Travis CI의 빌드가 끝나면 S3에 zip파일이 전송되고, 이 zip파일은 /home/ec2-user/app/step2/zip으로 복사되어 압축을 풀 예정

Travis CI의 설정은 .travis.yml으로 진행했음
AWS CodeDeploy의 설정은 appspec.yml으로 진행

  • appstec.yml 작성

    - version : 0.0 : CodeDeploy 버전을 이야기함, 프로젝트 버전이 아니므로 0.0 이외의 다른 버전을 사용하면 오류가 발생함
    - source : CodeDeploy에서 전달해준 파일 중 destination으로 이동 시킬 대상을 지정함, 루트 파일(/)을 지정하면 전체파일을 이야기함
    - destination : source에서 지정된 파일을 받을 위치, 이후 jar를 실행하는 등은 destination에서 옮긴 파을들로 진행됨
    - overwrite : 기존에 파일들이 있으면 덮어쓸지를 결정함
  • .travis.yml 코드 추가 후 커밋, 푸시
  • push하면 Travis CI가 자동으로 실행됨
  • AWS CodeDeploy 배포 수행 확인
  • cd /home/ec2-user/app/step2/zip 들어가서 파일 목록 확인

5. 배포 자동화 구성

5-1. deploy.sh 파일 추가

  • scripts 디렉토리 생성 후 deploy.sh 파일 생성
  • deploy.sh 파일 작성

5-2. .travis.yml 수정

.travis.yml 파일은 Travis CI 에서만 필요하고 CodeDeploy에서는 안 필요하다.

  • before-deploy 부분 수정

    - Travis CI는 S3로 특정 파일만 업로드가 안되기 때문에 before-deploy 디렉토리는 항상 생성해야 한다.
    - before-deploy에는 zip 파일에 포함 시킬 파일들을 저장함
    - zip -r 명령어를 통해서 before-deploy 디렉토리 전체 파일을 압축한다.

5-3. appspec.yml 수정

  • 수정 후 모든 수정 사항 커밋, 푸시
  • 배포 성공한 상태 확인

5-4. 실제 배포 과정 체험

  • build.gradle에 프로젝트 버전 변경 :version '1.0.1-SNAPSHOT'
  • index.mustache를 간단하게 수정 후 커밋, 푸시
  • 변경된 내용 확인하기

6.CodeDeploy 로그 확인

배포가 실패하면 /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log에서 확인 할 수 있다.

0개의 댓글