-
Travis CI 배포 자동화 (Travis CI repository 연동 오류)AWS 2023. 11. 9. 16:10
참고 : 스프링 부트와 AWS로 혼자 구현하는 웹 서비스
CI (Continuous Integration - 지속적 통합)
: 코드 버전 관리를 하는 VCS 시스템(Git, SVN 등)에 PUSH가 되면 자동으로 테스트와 빌드가 수행되어 안정적인 배포 파일을 만드는 과정
- 모든 소스 코드가 살아 있고(현재 실행되고) 누구든 현재의 소스에 접근할 수 있는 단일 지점을 유지할 것
- 빌드 프로세스를 자동화해서 누구든 소스로부터 시스템을 빌드하는 단일 명령어를 사용할 수 있게 할 것
- 테스팅을 자동화해서 단일 명령어로 언제든지 시스템에 대한 건전한 테스트 수트를 실행할 수 있게 할 것
- 누구나 현재 실행 파일을 얻으면 지금까지 가장 완전한 실행 파일을 얻었다는 확신을 하게 할 것
CD (Continuous Deployment - 지속적인 배포)
: 이 빌드 결과를 자동으로 운영 서버에 무중단 배포까지 진행되는 과정
1. Travis CI 연동하기
- Travis CI는 깃허브에서 제공하는 무료 CI 서비스
- 젠킨스는 설치형이기 때문에 이를 위한 EC2 인스턴스가 하나 더 필요
※ Travis CI My Repositories 연동 안 되는 문제
(1) Plan - Trial Plan $1 결제
해당 플랜을 결제하였는데도 My Repository 연동이 되지 않았다.
금요일 오후에 결제 후, 월요일에 확인해보니 연동이 되어있었다.
하루, 이틀 정도 후에 확인해보기 ! 결제된 $1는 일주일 정도 후에 취소 처리되었다.
(2) Github Actions 사용하기
Travis CI 연동이 안 되어 Github Actions로 진행하려고 했으나, 며칠 후 연동이 되어 Travis CI로 진행하였다.
Github Actions 내용은 하기 블로그 참고
* 프로젝트 설정
프로젝트의 build.gradle과 같은 위치에서 .travis.yml 생성 후 Travis CI 상세 설정
.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: - 본인 메일 주소
2. Travis CI와 AWS S3 연동하기
CodeDeploy는 저장 기능이 없어서 Travis CI가 빌드한 결과물을 받아서 CodeDeploy가 가져갈 수 있도록 보관할 수 있는 공간이 필요
→ AWS S3를 이용
CodeDeploy에서는 깃허브 코드를 가져오는 기능을 지원하므로, CodeDeploy가 빌드도 하고 배포도 할 수 있다.
하지만 이렇게 하는 경우 빌드 없이 배포만 필요할 때 대응하기가 어렵다.
빌드와 배포가 분리되어 있으면 예전에 빌드되어 만들어진 Jar를 재사용하면 되지만, CodeDeploy가 모든 것을 하게 될 땐 항상 빌드를 하게 되니 확장성이 많이 떨어진다. 웬만하면 빌드와 배포는 분리 !
AWS Key 발급
일반적으로 AWS 서비스에 외부 서비스가 접근할 수 없다. 그러므로 접근 가능한 권한을 가진 Key를 생성해서 사용해야 한다.
AWS에서는 이러한 인증과 관련된 기능을 제공하는 서비스로 IAM(Identity and Access Management)이 있다.
IAM은 AWS에서 제공하는 서비스의 접근 방식과 권한을 관리한다. 이 IAM을 통해 Travis CI가 AWS와 S3에 접근할 수 있도록 설정할 수 있다.
생성된 엑세스 키와 비밀 엑세스 키를 Travis CI에 등록한다.
Travis CI에 키 등록
해당 Repository > More options > Settings > Environment Variables
여기에 AWS_ACCESS_KEY, AWS_SECRET_KEY을 변수로 해서 IAM 사용자에서 발급받은 키 값들을 등록한다.
- AWS_ACCESS_KEY: 엑세스 키 ID
- AWS_SECRET_KEY: 비밀 엑세스 키
→ .travis.yml에서 $AWS_ACCESS_KEY, $AWS_SECRET_KEY으로 사용 가능
.travis.yml
language: java jdk: - openjdk8 branches: only: - master # Travis CI 서버의 Home cache: directories: - '$HOME/.m2/repository' - '$HOME/.gradle' script: "./gradlew clean build" before_deploy: - zip -r freelec-springboot2-webservice * - mkdir -p deploy - mv freelec-springboot2-webservice.zip deploy/freelec-springboot2-webservice.zip deploy: - provider: s3 access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값 secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값 bucket: freelec-sol-springboot-build # S3 버킷 region: ap-northeast-2 skip_cleanup: true acl: private # zip 파일 접근을 private으로 local_dir: deploy # before_deploy에서 생성한 디렉토리 wait_until_deploy: true - provider: codedeploy access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값 secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값 bucket: freelec-sol-springboot-build # S3 버킷 key: freelec-springboot2-webservice.zip # 빌드 파일을 압축해서 전달 build_type: zip # 압축 확장자 application: freelec-springboot2-webservice # 웹 콘솔에서 등록한 CodeDelploy 애플리케이션 deployment_group: freelec-springboot2-webservice-group # 웹 콘솔에서 등록한 CodeDeploy 배포 그룹 region: ap-northeast-2 wait_until_deploy: true # CI 실행 완료 시 메일로 알람 notifications: email: recipients: - 본인 메일 주소
3. Travis CI와 AWS S3, CodeDeploy 연동하기
CodeDeploy 생성
- Code Commit
- 깃허브와 같은 코드 저장소의 역할을 한다.
- 프라이빗 기능을 지원한다는 강점이 있지만, 현재 깃허브에서 무료로 프라이빗 지원을 하고 있어서 거의 사용되지 않는다. - Code Build
- Travis CI와 마찬가지로 빌드용 서비스
- 멀티 모듈을 배포해야 하는 경우 사용해 볼만하지만, 규모가 있는 서비스에서는 대부분 젠킨스/팀시티 등을 이용하여 사용할 일이 거의 없다. - CodeDeploy
- AWS의 배포 서비스
- 앞에서 언급한 다른 서비스들은 대체제가 있고, 딱히 대체제보다 나은 점이 없지만, CodeDeploy는 대체제가 없다.
- 오토 스케일링 그룹 배포, 블루 그린 배포, EC2 단독 배포 등 많은 기능을 지원한다.
현재 Code Commit의 역할은 깃허브가, Code Build의 역할은 Travis CI가 하고 있어 CodeDeploy만 사용한다.
Travis CI, S3, CodeDeploy 연동
# S3에서 넘겨줄 zip 파일을 저장할 디렉토리 생성 mkdir ~/app/step2 && mkdir ~/app/step2/zip
Travis CI의 Build가 끝나면 S3에 zip 파일이 전송되고, 이 zip 파일은 /home/ec2-user/app/step2/zip로 복사되어 압축을 풀 예정
AWS CodeDeploy의 설정은 appspec.yml
appspec.yml
version: 0.0 os: linux files: - source: / destination: /home/ec2-user/app/step2/zip overwrite: yes
4. 배포 자동화 구성
프로젝트/scripts/deploy.sh 생성
#!/bin/bash REPOSITORY=/home/ec2-user/app/step2 PROJECT_NAME=freelec-springboot2-webservice echo "> Build 파일 복사" cp $REPOSITORY/zip/*.jar $REPOSITORY/ echo "> 현재 구동 중인 애플리케이션 pid 확인" CURRENT_PID=$(pgrep -fl freelec-springboot2-webservice | 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 &
.travis.yml
language: java jdk: - openjdk8 branches: only: - master # Travis CI 서버의 Home cache: directories: - '$HOME/.m2/repository' - '$HOME/.gradle' script: "./gradlew clean build" 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 # 상위 디렉토리로 이동 후 deplooy 디렉토리 생성 - mv before-deploy/before-deploy.zip deploy/freelec-springboot2-webservice.zip # deploy로 zip파일 이동 deploy: - provider: s3 access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값 secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값 bucket: freelec-sol-springboot-build # S3 버킷 region: ap-northeast-2 skip_cleanup: true acl: private # zip 파일 접근을 private으로 local_dir: deploy # before_deploy에서 생성한 디렉토리 wait_until_deploy: true - provider: codedeploy access_key_id: $AWS_ACCESS_KEY # Travis repo settings에 설정된 값 secret_access_key: $AWS_SECRET_KEY # Travis repo settings에 설정된 값 bucket: freelec-sol-springboot-build # S3 버킷 key: freelec-springboot2-webservice.zip # 빌드 파일을 압축해서 전달 build_type: zip # 압축 확장자 application: freelec-springboot2-webservice # 웹 콘솔에서 등록한 CodeDelploy 애플리케이션 deployment_group: freelec-springboot2-webservice-group # 웹 콘솔에서 등록한 CodeDeploy 배포 그룹 region: ap-northeast-2 wait_until_deploy: true # CI 실행 완료 시 메일로 알람 notifications: email: recipients: - 본인 메일 주소
appspec.yml
version: 0.0 os: linux files: - source: / destination: /home/ec2-user/app/step2/zip/ overwrite: yes permissions: - object: / pattern: "**" owner: ec2-user group: ec2-user hooks: ApplicationStart: - location: deploy.sh timeout: 60 runas: ec2-user
5. CodeDeploy 로그 확인
CodeDeploy에 관한 대부분 내용은 /opt/codedeploy-agent/deployment-root에 있다.
- 최상단의 영문과 대시(-)가 있는 디렉토리명은 CodeDeploy ID
- 사용자마다 고유한 ID가 생성되어 각자 다른 ID가 발급된다.
- 해당 디렉토리로 들어가 보면 배포한 단위별로 배포 파일들이 있습니다.
- 본인의 배포 파일이 정상적으로 왔는지 확인해볼 수 있다. - /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log
- CodeDeploy 로그 파일
- CodeDeploy로 이루어지는 배포 내용 중 표준 입/출력 내용은 모두 여기에 담겨있다.
- 작성한 echo 내용도 모두 표기된다.
'AWS' 카테고리의 다른 글
Nginx 무중단 배포 (0) 2023.11.10 EC2 서버에 프로젝트 배포하기 (EC2 ./gradlew test 무한 로딩, nohub java ~ application-real-db.properties 오류) (1) 2023.11.09 Mac/Linux EC2 서버 접속하기 (0) 2023.11.08