[TIL] (3) Travis CI와 AWS S3, CodeDeploy 연동

woonie·2022년 3월 27일
0

TIL

목록 보기
55/64
post-thumbnail

항해 74일차

Travis CI와 AWS S3, CodeDeploy 연동

앞에서 S3연동까지 되었다. AWS의 배포 시스템인 CodeDeploy를 이용하기 전에 배포 대상인 EC2가 CodeDeploy를 연동 받을 수 있게 설정해보자.

EC2에 IAM 역할 추가

S3 버킷을 생성하면서 IAM에서 사용자 추가를 하였다. 이번에는 사용자 추가가 아닌 역할 추가를 해야한다.

IAM의 사용자와 역할의 차이

  • 역할
    - AWS 서비스에서만 할당할 수 있는 권한
    - EC2, CodeDeploy, SQS 등
  • 사용자
    - AWS 서비스 외에 사용할 수 있는 권한
    - 로컬 PC, IDC 서버 등

이번에 만들 권한은 EC2에서 사용해야 하기 때문에 사용자가 아닌 역할을 설정해준다.

  • IAM에서 [역할]탭에서 역할 만들기 클릭

  • AWS서비스 / EC2선택

  • 권한 추가에서 "EC2Role"로 검색 후 "AmazonEC2RoleforAWSCodeDeploy" 선택 후 다음 클릭

  • 마지막으로 역할 이름 등록 후 나머지 등록 정보를 확인하고 역할 생성 클릭
    (역할 이름은 보통 "서비스명-EC2CodeDeployRole"로 입력한다고 한다.)

EC2서비스 등록

위에서 만든 역할을 EC2 서비스에 등록해야한다.

  • EC2의 인스턴스 목록으로 이동한 뒤 본인의 인스턴스에 마우스 오른쪽 버튼으로 "보안 -> IAM 역할 수정" 클릭

  • 위에서 생성한 역할을 선택하고 저장해준다.
  • 저장 EC2 재부팅을 해줘야 역할이 정상적으로 적용되니 재부팅을 반드시 해주어야한다.

CodeDeploy Agent 설치

  • AWS CodeDeploy를 AWS EC2 인스턴스에서 활용하기 위해서는 CodeDeploy Agent를 설치 해줘야한다.
  • 터미널에서 EC2에 접속하여 아래 명령어를 입력해준다.

-터미널에서 jdk를 설치해주자

sudo apt-get update
sudo apt-get install openjdk-8-jdk

  • AWS CLI 를 설치

    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install awscli

  • AWS Code Deploy CLI 를 설치

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

  • install 파일에 실행 권한이 없으므로 실행 권한 추가

    chmod +x ./install

  • install 파일로 설치

    sudo ./install auto

  • /usr/bin/env: ruby: No such file or directory 라는 오류가 나온다면 루비 설치 후 다시 install파일을 설치해준다.

    sudo apt-get install ruby;

  • 설치가 완료되면 Agent가 정상적으로 실행되고 있는지 상태 검사
    (아래 이미지와 같이 active(running) 이면 정상 실행)

    sudo service codedeploy-agent status

CodeDeploy 권한 생성

CodeDeploy에서 EC2에 접근하려면 권한이 필요하다. AWS의 서비스이니 IAM 역할을 생성한다.

  • [AWS서비스], "다른 AWS서비스의 사용 사례"에서 CodeDeploy 검색 후 선택

  • CodeDeploy의 권한은 하나뿐이라서 별도 선택 없이 바로 다음으로 넘어간다.

  • 권한 생성 완료

CodeDeploy 생성

  • AWS의 배포 서비스다.
  • 배포를 하는데 아래와 같은 3가지 기능이 필요하다.
    • Code Commit
      • 코드 저장소(깃허브와 같은 저장소)
      • 해당 역할은 깃허브가 해준다.
    • Code Build
      • 빌드용 서비스
      • 해당 역할은 Travis CIrk gownsek.
    • CodeDeploy
      • AWS의 배포 서비스
  • AWS에서 CodeDeploy 검색 하여 들어가보면 [애플리케이션]탭에 [애플리케이션 생성]이 있다.

  • 애플리케이션을 생성해주고 [배포 그룹 생성]이 보인다. 클릭

  • 배포 그룹 이름을 작성해주고 서비스 역할은 위에서 생성한 CodeDeploy용 IAM 역할을 선택해준다.

  • 환경 구성은 Amazon EC2 인스턴스 선택해주고 태그 그룹에서는 배포할 EC2인스턴스를 선택해준다.

  • 마지막으로 배포 구성을 선택하고 로드밸런싱 체크를 해제 후 배포 그룹 생성 클릭

  • 배포 그룹까지 생성하였다면 CodeDeploy 설정은 끝이다. 거의 다 왔다.

CodeDeploy 연동

  • 많은 블로그를 보며 따라 했었지만 여기서 많은 시간을 쏟아부었다... 삽질을 많이 했다.
    다른 블로그들은 EC2인스턴스를 [Amazon Linux 2 AMI (HVM)] 로 생성하였고..
    우리는 [Ubuntu Server 18.04 LTS (HVM)]로 하였다... 두개의 다른점과 장단점은 추후에 알아봐야겠다.
    그래서 그런지 블로그에 나와있는 명령어들이 잘 먹지 않았다. 정말 시간을 많이 쏟았다.
    나와 같이 헤매며 열심히 삽질하고 계신 초보 개발자분들에게 조금이나마 도움이 되었으면 한다 :)

  • S3에서 넘겨줄 zip 파일을 저장할 디렉토리를 하나 생성해야 한다.
    터미널에서 EC2를 연결하고 아래 명령어로 생성

    mkdir ~/app
    mkdir ~/app/test && mkdir ~/app/test/zip

  • Travis CI의 Build가 끝나면 S3에 zip 파일이 전송되고, 이 zip 파일은 /home/ubuntu/app/test/zip 으로 복사되어 압축을 풀게된다.

  • Travis CI의 설정은 .travis.yml로 하였고 CodeDeploy는 appspec.yml로 한다.

  • appspec.yml 설정

# 1
version: 0.0
os: linux
files:
  # 2
  - source:  /
    # 3
    destination: /home/ubuntu/app/test/zip
    # 4
    overwrite: yes
  1. version: 0.0
    • CodeDeploy 버전
    • 프로젝트 버전이 아니므로 0.0 외에 다른 버전을 사용하면 오류 발생
  2. source
    • CodeDeploy에서 전달해 준 파일 중 destination으로 이동시킬 대상을 지정
    • 루트 경로(/)를 지정하면 전체 파일을 의미한다.
  3. destination
    • source에서 지정된 파일을 받을 위치
    • 이후 Jar를 실행하는 등은 destination에서 옮긴 파일들로 진행
  4. overwrite
    • 기존에 파일들이 있으면 덮어쓸지를 결정
    • yes면 파일을들 덮어쓰게된다.
  • .trvis.yml에도 CodeDeploy 내용 추가
 - provider: codedeploy
    access_key_id: $AWS_ACCESS_KEY 
    secret_access_key: $AWS_SECRET_KEY
    bucket: hanghae8-final-project-travis # S3 버킷명
    key: hanghae8-final-project.zip # 빌드 파일을 압축해서 전달
    bundle_type: zip
    application: hanghae8-admin # CodeDeploy 어플리케이션명
    deployment_group: hanghae8-admin-group # CodeDeploy 배포 그룹명
    region: ap-northeast-2
    wait-until-deployed: true
  • .travis.yml 전체 코드
language: java
jdk:
  - openjdk8

branches:
  only:
    - master

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

before_install:
  - chmod +x gradlew

script: "./gradlew clean build"

before_deploy:
  - zip -r hanghae8-final-project *
  - mkdir -p deploy
  - mv hanghae8-final-project.zip deploy/hanghae8-final-project.zip

deploy:
  - provider: s3
    access_key_id: $AWS_ACCESS_KEY 
    secret_access_key: $AWS_SECRET_KEY 
    bucket: hanghae8-final-project-travis # S3 버킷
    region: ap-northeast-2
    skip_cleanup: true
    acl: private # zip 파일 접근을 private으로
    local_dir: deploy # before_deploy에서 생성한 디렉토리
    wait-until-deployed: true

  - provider: codedeploy
    access_key_id: $AWS_ACCESS_KEY 
    secret_access_key: $AWS_SECRET_KEY 
    bucket: hanghae8-final-project-travis # S3 버킷명
    key: hanghae8-final-project.zip # 빌드 파일을 압축해서 전달
    bundle_type: zip
    application: hanghae8-admin # CodeDeploy 어플리케이션명
    deployment_group: hanghae8-admin-group #CodeDeploy 배포 그룹명
    region: ap-northeast-2
    wait-until-deployed: true

# CI 실행 완료 시 메일로 알람
notifications:
  email:
    recipients:
      - 본인 이메일
  • 이제 모든 설정이 끝나고 내용을 다 작성 하였다면 깃헙에 커밋하고 푸시한다.

  • Travis CI가 끝나면 CodeDeploy 화면 아래에서 배포 성공 여부 확인이 가능하다.

  • 터미널에서 다음 명령어로 파일들이 잘 들어와있는지 확인한다.

    cd /home/ubuntu/app/test/zip
    ls -al

  • 위의 화면과 같이 파일들이 잘 들어왔다면 Travis CI와 S3, CodeDeploy가 정상적으로 연동이 되었다.
    정말 이제 다 왔다.

배포 자동화 구성

이제 실제로 Jar파일을 배포하여 실행까지 해보겠다.

  • deploy.sh 파일 추가

  • scripts 디렉토리를 생성 후 deploy.sh를 생성해준다.
    (처음 이것또한 어디에 만들어야 하는지 헷갈렸다...인텔리제이에서 아래 처럼 만들어주면 된다..)

  • deploy.sh 스크립트 작성
#!/bin/bash
REPOSITORY=/home/ubuntu/app/test
PROJECT_NAME=hanghae8-admin

echo "> Build 파일 복사"
cp $REPOSITORY/zip/*.jar $REPOSITORY/

echo "> 현재 구동중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -fl hanghae8-admin| grep jar | awk '{print $1}')

echo "현재 구동중인 어플리케이션 pid: $CURRENT_PID"
if [ -z "$CURRENT_PID" ]; then
    echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
    echo "> kill -15 $CURRENT_PID"
    kill -15 $CURRENT_PID
    sleep 5
fi

echo "> 새 어플리케이션 배포"
JAR_NAME=$(ls -tr $REPOSITORY/*.jar | tail -n 1)

echo "> JAR Name: $JAR_NAME"
echo "> $JAR_NAME 에 실행권한 추가"
chmod +x $JAR_NAME

echo "> $JAR_NAME 실행"

nohup java -jar \
  -Dspring.config.location=classpath:/application.properties \
  -Dspring.profiles.active=real \
  $JAR_NAME > $REPOSITORY/nohup.out 2>&1 &
  • .travis.yml 파일 수정
before_deploy:
  - mkdir -p before-deploy
  - cp scripts/*.sh before-deploy/
  - cp appspec.yml before-deploy/
  - cp build/libs/*.jar before-deploy/
  - cd before-deploy && zip -r before-deploy *
  - cd ../ && mkdir -p deploy
  - mv before-deploy/before-deploy.zip deploy/hanghae8-final-project.zip
  • appspec.yml 추가
    들여쓰기 주의
# 파일 권한 추가
permission:
  - object: /
    pattern: "**"
    owner: ubuntu
    group: ubuntu
hooks:
  ApplicationStart:
    - location: deploy.sh
      timeout: 60
      runas: ubuntu
  • 이제 모든 설정이 끝났다. 깃허브 커밋과 푸시를 한다.
  • Travis CI 정말 많은 삽질과 많은 테스트를 하였다. 정말 오래 안걸리고 쉽게할 수 있을거라 생각했었는데 예상하지 못한 오류와 많은 시행착오가 있었다...
profile
동료들과 함께하는 개발의 중요성에 관심이 많습니다. 언제나 호기심을 갖고 꾸준히 노력하는 개발자로서 성장하고 있습니다.

0개의 댓글