항해 74일차
앞에서 S3연동까지 되었다. AWS의 배포 시스템인 CodeDeploy를 이용하기 전에 배포 대상인 EC2가 CodeDeploy를 연동 받을 수 있게 설정해보자.
S3 버킷을 생성하면서 IAM에서 사용자 추가를 하였다. 이번에는 사용자 추가가 아닌 역할 추가를 해야한다.
IAM의 사용자와 역할의 차이
- 역할
- AWS 서비스에서만 할당할 수 있는 권한
- EC2, CodeDeploy, SQS 등- 사용자
- AWS 서비스 외에 사용할 수 있는 권한
- 로컬 PC, IDC 서버 등
이번에 만들 권한은 EC2에서 사용해야 하기 때문에 사용자가 아닌 역할을 설정해준다.
IAM에서 [역할]탭에서 역할 만들기 클릭
AWS서비스 / EC2선택
권한 추가에서 "EC2Role"로 검색 후 "AmazonEC2RoleforAWSCodeDeploy" 선택 후 다음 클릭
마지막으로 역할 이름 등록 후 나머지 등록 정보를 확인하고 역할 생성 클릭
(역할 이름은 보통 "서비스명-EC2CodeDeployRole"로 입력한다고 한다.)
위에서 만든 역할을 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에서 EC2에 접근하려면 권한이 필요하다. AWS의 서비스이니 IAM 역할을 생성한다.
[AWS서비스], "다른 AWS서비스의 사용 사례"에서 CodeDeploy 검색 후 선택
CodeDeploy의 권한은 하나뿐이라서 별도 선택 없이 바로 다음으로 넘어간다.
AWS에서 CodeDeploy 검색 하여 들어가보면 [애플리케이션]탭에 [애플리케이션 생성]이 있다.
애플리케이션을 생성해주고 [배포 그룹 생성]이 보인다. 클릭
배포 그룹 이름을 작성해주고 서비스 역할은 위에서 생성한 CodeDeploy용 IAM 역할을 선택해준다.
환경 구성은 Amazon EC2 인스턴스 선택해주고 태그 그룹에서는 배포할 EC2인스턴스를 선택해준다.
마지막으로 배포 구성을 선택하고 로드밸런싱 체크를 해제 후 배포 그룹 생성 클릭
배포 그룹까지 생성하였다면 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
- 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
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를 생성해준다.
(처음 이것또한 어디에 만들어야 하는지 헷갈렸다...인텔리제이에서 아래 처럼 만들어주면 된다..)
#!/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 &
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
# 파일 권한 추가
permission:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu
hooks:
ApplicationStart:
- location: deploy.sh
timeout: 60
runas: ubuntu