[DevOps] Spring boot, Travis, AWS EC2, S3, CodeDeploy로 CI/CD 환경 구축 2
DevOps

[DevOps] Spring boot, Travis, AWS EC2, S3, CodeDeploy로 CI/CD 환경 구축 2

728x90

지난 글에서는 Travis, S3를 연동하여 S3 버킷에 빌드 된 Jar 파일을 업로드 하는 부분까지 완료했다. 이번 글에서는 CodeDeploy까지 연동하여 자동으로 배포가 되게끔 설정을 해준다.

 

 

Travis와 AWS S3, CodeDeploy 연동하기

CodeDeploy를 이용하기 전에 배포 대상인 EC2가 CodeDeploy를 연동 받을 수 있게 IAM 역할을 하나 생성해준다.


  IAM의 사용자와 역할의 차이는?

  역할 - AWS 서비스에만 할당할 수 있는 권한 (EC2, CodeDeploy, SQS 등)

  사용자 - AWS 서비스 외에 사용할 수 있는 권한 (로컬 PC, IDC 서버 등)


지금 만들 권한은 EC2에서 사용할 것이기 때문에 사용자가 아닌 역할로 처리해준다. 

 

서비스 선택에서는 [AWS 서비스 -> EC2]를 차례로 선택해준다.

 

정책 검색창에 EC2RoleForA를 검색하여 AmazonEC2RoleforAWSCodeDeploy를 선택한다.

 

태그는 본인이 원하는 이름으로 지어준다.

 

마지막으로 역할 이름을 등록하고 나머지 등록 정보를 최종적으로 확인한다.

 

만든 역할을 이제 EC2 서비스에 등록해준다. EC2 인스턴스 목록에서 본인의 인스턴스를 선택하여 [인스턴스 설정 -> IAM 역할 연결/바꾸기]를 차례로 선택한다.

 

앞에서 생성한 역할을 선택해준다.

 

역할 선택이 완료되면 해당 EC2 인스턴스를 재부팅 해준다. 재부팅을 해야만 역할이 정상적으로 적용된다.

 

재부팅이 완료되었으면 CodeDeploy의 요청을 받을 수 있게 에이전트를 설치해야 한다. EC2에 접속해서 아래의 명령어를 입력한다.

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

 

명령어가 정상적으로 실행 되었다면 install 파일이 생성 됐을 것이다. 생성된 install 파일에는 실행 권한이 없으니 실행 권한을 추가해준다.

chmod +x ./install

 

이후 install 파일로 설치를 진행한다.

sudo ./install auto

 

설치가 끝났으면 에이전트가 정상적으로 실행되고 있는지 상태 검사를 한다. 아래의 사진과 같이 메시지가 출력되면 정상이다.

sudo service codedeploy-agent status

 

이제 CodeDeploy를 위한 권한을 생성하자. CodeDeploy에서 EC2에 접근하려면 마찬가지로 권한이 필요하다. IAM 서비스로 들어가서 [역할 -> 역할 만들기]를 차례로 선택한다. 

 

CodeDeploy 서비스를 선택해준다.

 

CodeDeploy는 권한이 하나뿐이라서 선택 없이 바로 다음으로 넘어간다.

 

태그 역시 본인이 원하는 이름으로 짓는다.

 

CodeDeploy를 위한 역할 이름과 선택 항목들을 확인한 뒤 [역할 만들기]를 클릭한다.

 

이제 CodeDeploy를 생성해야 한다. AWS 콘솔창에서 CodeDeploy를 검색하여 이동한다.

 

좌측 카테고리에서 [시작하기]를 누른 후 [애플리케이션 생성] 버튼을 클릭한다.

 

생성할 CodeDeploy의 이름과 컴퓨팅 플랫폼을 선택한다. 컴퓨팅 플랫폼은 [EC2/온프레미스]를 선택한다.

 

생성이 완료되면 배포 그룹을 생성하라는 메세지를 볼 수 있다. 화면 중앙의 [배포 그룹 생성] 버튼을 클릭한다.

 

배포 그룹 이름과 서비스 역할을 등록한다. 서비스 역할은 이전에 생성한 CodeDeploy용 IAM 역할을 선택하면 된다.

 

배포 유형은 현재 위치를 선택한다. 본인이 배포할 서비스가 2대 이상이라면 블루/그린을 선택하면 되지만, 여기서는 1대의 EC2에만 배포하므로 선택하지 않는다. 환경 구성에서는 [Amazon EC2 인스턴스]에 체크한다.

 

마지막으로 배포 구성과 로드 밸런서를 선택한다. 배포 구성이란 한번 배포할 때 몇 대의 서버에 배포할지를 결정한다.

 

CodeDeploy 설정이 끝이 나면 이제 Travis, CodeDeploy를 연동할 차례이다. EC2 서버에 접속하여 아래의 명령어로 디렉토리를 생성해준다. S3에 올라간 Jar 파일을 /home/ec2-user/app/step2/zip로 복사하여 압축을 풀 예정이다.

mkdir ~/app/step2 && mkdir ~/app/step2/zip

 

이제 AWS CodeDeploy 설정을 위해 appspec.yml 파일을 생성하고 코드를 작성해준다.

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/app/step2/zip/
    overwrite: yes

 

.travis.yml에도 CodeDeploy에 대한 내용을 추가한다.

 - provider: codedeploy
    access_key_id: $AWS_ACCESS_KEY   # Travis repo settings에 설정된 값
    secret_access_key: $AWS_SECRET_KEY
    bucket: spring-boot-build # S3 버킷
    key: spring-boot.zip # 빌드 파일을 압축해서 전달
    bundle_type: zip # 압축 확장자
    application: spring-boot #  웹 콘솔에서 등록한 CodeDeploy 애플리케이션
    deployment_group: spring-boot-group # 웹 콘솔에서 등록한 CodeDeploy 배포 그룹
    region: ap-northeast-2
    wait-until-deployed: true

 

모든 내용을 작성했다면 프로젝트를 커밋하고 푸시한다. github으로 푸시가 되면 Travis가 자동으로 시작된다. 

 

Travis가 끝나면 CodeDeploy 화면에서 배포가 수행되는 것을 확인할 수 있다.

 

배포가 끝났다면 다음 명령어로 파일들이 잘 도착했는지 확인해본다. 아래의 사진처럼 파일들이 정상적으로 복사된 것을 확인할 수 있다.

cd /home/ec2-user/app/step2/zip

ls

 

 

 

배포 자동화 구성

Travis, S3, CodeDeploy 연동까지 마무리 되었으니 이제 실제로 Jar를 배포하여 실행까지 해주는 환경을 구축해본다. 우선 scripts 디렉토리를 만든 뒤 deploy.sh 파일을 생성해준다. deploy.sh 안에는 아래의 코드를 넣어준다.

#!/bin/bash

REPOSITORY=/home/ec2-user/app/step2
PROJECT_NAME=spring-boot

echo "> Build 파일 복사"

cp $REPOSITORY/zip/*.jar $REPOSITORY/

echo "> 현재 구동중인 애플리케이션 pid 확인"

CURRENT_PID=$(pgrep -fl spring-boot | 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,classpath:/application-real.properties,/home/ec2-user/app/application-oauth.properties,/home/ec2-user/app/application-real-db.properties \
    -Dspring.profiles.active=real \
    $JAR_NAME > $REPOSITORY/nohup.out 2>&1 &

 

deploy.sh 파일 설정이 끝났으면, 이제 .travis.yml 파일을 수정해준다.

before_deploy:
  - mkdir -p before-deploy # zip에 포함시킬 파일들을 담을 디렉토리 생성
  - cp scripts/*.sh before-deploy/
  - cp appspec.yml before-deploy/
  - cp build/libs/*.jar before-deploy/
  - cd before-deploy && zip -r before-deploy * # before-deploy로 이동 후 전체 압축
  - cd ../ && mkdir -p deploy # 상위 디렉토리로 이동 후 deploy 디렉토리 생성
  - mv before-deploy/before-deploy.zip deploy/spring-boot.zip # deploy로 zip 파일 이동

 

appspec.yml 파일 또한 수정해준다.

permissions:
  - object: /
    pattern: "**"
    owner: ec2-user
    group: ec2-user

hooks:
  ApplicationStart:
    - location: deploy.sh
      timeout: 60
      runas: ec2-user

 

모든 설정이 완료되었으니 github으로 커밋과 푸시를 해준다. Travis에서 성공 메시지를 확인하고 CodeDeploy에서도 배포가 성공한 것을 확인한다.

 

성공 메시지를 확인했다면, 웹 브라우저에서 EC2 도메인을 입력해서 확인해 본다.

 

성공적으로 배포 되는 것을 확인 할 수 있다.

 

 

마무리

이제 로컬에서 코드를 작성하여 github에 푸시만 하면 자동으로 테스트, 빌드 후에 서버에 배포되는 환경이 되었다. 이러한 환경을 구축해놓지 않으면 테스트, 빌드, 배포를 전부 수동으로 해야하므로 전체적인 시간도 많이 들고 매우 귀찮게 된다. 인프라 부분이라서 다소 내용이 어려웠지만 그래도 서버에 관해 조금이나마 익히게 된 것 같다. 

 

 

참고

https://jojoldu.tistory.com/265

728x90