-
Notifications
You must be signed in to change notification settings - Fork 0
CodeDeploy
- CodeDeploy 는 Amazon EC2 인스턴스, 온프레미스 인스턴스, 서버리스 Lambda 함수 또는 Amazon ECS 서비스로 애플리케이션 배포를 자동화하는 배포 서비스
- 안정적으로 변경사항을 운영환경으로 자동 배포하기 위해서
- 소프트웨어 릴리즈 주기를 더 빠르게 하기 위해서
- 작게, 자주 배포를 하게 하여 한 번의 배포에 들어가는 비용, 위험을 줄이기 위해서
- Github, Jenkins, AWS CodePipeline 등과 통합하여 사용 가능
- 각 배포 버전에 대한 상세한 보고서 제공, 가동 중지 시간 최소화 등 AWS에서 제공하는 유용한 기능들이 많기 때문
- 환경
- CI용, CD용 EC2(Amazon Linux 2 AMI) 2대
- Nginx(1.18.0)
- Jenkins 2021.5.14 기준 https://pkg.jenkins.io/redhat-stable/ 최신 stable 버전
- JDK(openjdk version "11.0.11") java-11-amazon-corretto로 설치
-
IAM - 역할
-
역할 생성
- EC2 선택 후,
다음버튼 클릭
- EC2 선택 후,
-
정책 생성
-
AmazonEC2RoleforAWSCodeDeploy정책 선택 후다음버튼 클릭
-
-
태그 추가(선택)
-
원하는 키, 값 설정

-
-
역할 검토
-
3에서 선택한 정책이 제대로 포함되어 있는 지 확인 후
역할 만들기버튼 클릭하여 생성
-
-
배포용 EC2 인스턴스에 생성한 IAM 연결
- EC2 - 작업 - 보안 - IAM 역할 수정


- EC2 재부팅
-
역할 생성

-
정책 생성
- 옵션이 하나밖에 없으므로 다음으로 넘어가면 된다.

-
태그 추가(선택)
-
원하는 키, 값 입력

-
-
역할 검토
-
2에서 선택한 정책이 제대로 포함되어 있는 지 확인 후
역할 만들기버튼 클릭하여 생성
-
-
CodeDeploy 검색 후 사진의
애플리케이션 생성버튼 클릭
-
애플리케이션 이름 입력 및 플랫폼
EC2/온프레미스로 설정 후 생성
-
배포 그룹 생성

-
배포 그룹 이름 및 서비스 역할
-
3. CodeDeploy에서 배포용 EC2에 접근 가능하게 하는 역할 생성 에서 생성한 역할 할당

-
-
배포 유형
-
배포 서버 1대이기 때문에
현재 위치선택- 2대 이상일 경우 블루/그린 선택

-
-
환경 구성
-
Amazio EC2 인스턴스체크 후, 배포 EC2용 태그의 키, 값을 입력해준다.- 배포 서버 1대에 대한 키, 값을 입력해주었으므로
1개의 일치하는 고유한 인스턴스가 뜨는 것을 볼 수 있다.

- 배포 서버 1대에 대한 키, 값을 입력해주었으므로
-
-
배포 설정
-
한 번 배포 시 몇 대의 서버에 배포할 것인지를 결정하는데 배포 서버가 1개이기 때문에 전체 배포하는
AllAtOnce선택, 로 드 밸런싱 활성화 체크 X
-
- 배포용 EC2 접속됐다는 가정하에 진행
-
aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2:aws-codedeploycodedeploy 설치 파일 다운로드
-
chmod +x ./install: install 파일에 실행 권한 추가 -
sudo ./install auto: install 파일로 codedeploy 설치-
/usr/bin/env: ruby: No such file or directory라고 출력된다면,sudo yum install -y ruby를 통해 ruby 설치 후 재입력
-
-
sudo service codedeploy-agent status: codedeploy-agent 서비스 상태 확인
-
mkdir ~/app/ && mkdir ~/app/jenkins && mkdir ~/app/jenkins/jar:app,jenkins,jar폴더 생성
-
배포 EC2에서
sudo vim application-prod-db.yml:/home/ec2-user/app경로에 rds 연결을 위한 yml 파일 생성spring: config: activate: on-profile: prod-db jpa: hibernate: ddl-auto: none dialect: org.hibernate.dialect.MySQL8Dialect storage_engine: innodb datasource: url: jdbc:mysql://EC2주소:3306/DB명?useSSL=false&verifyServerCertificate=false username: username password: passeword driver-class-name: com.mysql.cj.jdbc.Driver
-
프로젝트에
kill_process.sh생성#! /bin/bash echo "> 현재 구동중인 애플리케이션 pid 확인" CURRENT_PID=$(pgrep -fl kodesalon | grep java | 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
- 기존에 동작하고 있던 서버를 종료하기 위해 필요한 셸 스크립트
-
CURRENT_PID=$(pgrep -fl kodesalon | grep java | awk '{print $1}';):"kodesalon"로 되어있는 java 프로세스를 찾은 뒤 ID만 뽑아내어CURRENT_PID에 넣어준다.
-
프로젝트에
deploy.sh생성#!/bin/bash REPOSITORY=/home/ec2-user/app/jenkins echo "> Build 파일 복사" cp $REPOSITORY/build/libs/*.jar $REPOSITORY/jar/ echo "> 새 어플리케이션 배포" JAR_NAME=$(ls -tr $REPOSITORY/jar/*.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.yml,/home/ec2-user/app/application-prod-db.yml \ -Dlogging.config=classpath:/logback-spring.xml \ -Dspring.profiles.active=prod \ $JAR_NAME > $REPOSITORY/nohup.out 2>&1 &
-
cp $REPOSITORY/build/libs/*.jar $REPOSITORY/jar/:$REPOSITORY/build/libs/의 jar 파일을$REPOSITORY/jar/로 복사한다. -
JAR_NAME=$(ls -tr $REPOSITORY/jar/*.jar | tail -n 1):$REPOSITORY/jar/의 jar 파일들을 최종 수정 시간 기준(-t) 역순(-r)으로 나열하고 뒤에서 부터(-n) 첫 번째인 파일의 이름이JAR_NAME에 대입된다. 즉, 가장 최신 수정된 jar 파일이 대입된다. -
chmod +x $JAR_NAME: Jar 파일은 실행 권한이 없는 상태이기 때문에, nohup으로 실행할 수 있게 실행 권한을 부여한다. -
nohup java -jar \ -Dspring.config.location=classpath:/application.yml,/home/ec2-user/app/application-prod-db.yml \ -Dlogging.config=classpath:/logback-spring.xml \ -Dspring.profiles.active=prod \ $JAR_NAME > $REPOSITORY/nohup.out 2>&1 &: 스프링 설정 파일 위치를 지정하는Dspring.config.location을 사용하여, 기본 옵션을 담고 있는application.yml, rds DB 정보를 담고 있는application-prod-db.yml를 지정한다. 또한 log 설정을logback-spring.xml으로 지정한다.(classpath:/는 jar 안에 있는 resources 디렉토리 기준으로 경로가 생성된다고 보면 된다.application-prod-db.yml는 외부에 있기 때문에 절대 경로 지정)- nohup실행 시 CodeDeploy는 무한 대기합니다. 이 이슈를 해결하기 위해 nohub.out파일을 표준 입출력용으로 별도로 사용합니다. 이렇게 하지 않으면 nohup.out파일이 생기지 않고, CodeDeploy 로그에 표준 입출력이 출력됩니다. nohub이 끝나기 전까지 CodeDeploy도 끝나지 않으니 꼭 이렇게 해야합니다 in 스프링 부트와 AWS로 혼자 구현하는 웹 서비스, 명령어에 대해서 간단히 설명하자면 jar 파일 실행 시 발생하는 에러를 표준 출력으로 redirection하여
nohup.out에 저장시킨다고 보면 된다. - nohup으로 jar 파일을 실행시키는 이유는 터미널의 세션 연결이 끊어지더라도 지속적으로 동작 할 수 있게 해주기 위해서이다. 더 자세한 내용은 해당 링크 참조
-
2>&1: 표준 오류를 표준 출력으로 redirection한다는 의미이다.&1을 파일 경로로 대체하여 오류 로그를 보관할 수도 있다.- ex) 2>/tmp/exampleLog)
- 0 : 표준 입력(stdin)
- 1 : 표준 출력(stdout)
- 2 : 표준 에러(stderr)
- 표준출력과 표준에러를 분리해서 파일로 저장하고 싶을 때는 아래와 같은 형식을 사용할 수 있다.
- ex) deploy.sh 1>output.log 2>error.log
-
&: 마지막&은 백그라운드 작업으로 실행하게 한다.
- nohup실행 시 CodeDeploy는 무한 대기합니다. 이 이슈를 해결하기 위해 nohub.out파일을 표준 입출력용으로 별도로 사용합니다. 이렇게 하지 않으면 nohup.out파일이 생기지 않고, CodeDeploy 로그에 표준 입출력이 출력됩니다. nohub이 끝나기 전까지 CodeDeploy도 끝나지 않으니 꼭 이렇게 해야합니다 in 스프링 부트와 AWS로 혼자 구현하는 웹 서비스, 명령어에 대해서 간단히 설명하자면 jar 파일 실행 시 발생하는 에러를 표준 출력으로 redirection하여
-
-
프로젝트에
appspec.yml파일 생성- AWS CodeDeploy 설정 파일로, 반드시 프로젝트 최상단에 위치해야 한다.
version: 0.0 os: linux files: - source: / destination: /home/ec2-user/app/jenkins overwrite: yes permissions: - object: / pattern: "**" owner: ec2-user group: ec2-user hooks: ApplicationStop: - location: scripts/kill_process.sh ApplicationStart: - location: scripts/deploy.sh timeout: 60 runas: ec2-user
-
version: CodeDeploy 버전을 나타내는 것으로, 반드시 0.0으로 설정해야 한다. -
os: 현재 배포 서버 EC2가 Linux이기 때문에 linux를 적는다. -
files: 받은 파일을 EC2 어느 장소에 위치 시킬 것인지를 지정하는 곳이다.-
source: S3 버킷에서 복사할 파일의 위치를 나타내며,/는 전체 파일을 의미한다고 볼 수 있다. -
destination: zip 파일을 복사해 압축을 풀 위치를 지정한다. -
overwrite: 기존에 파일들이 존재할 경우 덮어쓸지를 결정하는 것으로,yes라고 하여 덮어쓰게 만들었다.
-
-
permissions: CodeDeploy에서 EC2 서버로 넘겨준 파일들을 모두 ec2-user 권한을 갖도록 설정한다. -
hooks: 배포 라이프 사이클에 따라서, 스크립트를 실행하는 곳-
ApplicationStop: Repository로부터 Application을 다운받기 전 수행되는 라이프사이클 이벤트를 의미한다.-
location: 실행시킬 스크립트 파일의 위치를 기술하는 곳으로,scripts/kill_process.sh지정
-
-
ApplicationStart: ApplicationStop 이벤트에서 종료한 Application을 다시 시작하거나 할 때 사용하는 라이프 사이클 이벤트 입니다.-
location: 실행시킬 스크립트 파일의 위치를 기술하는 곳으로,scripts/deploy.sh지정 -
timeout: 60초 이상 수행되면 실패가 되게 설정 -
runas:deploy.sh을 ec2-user 권한으로 실행하게 설정
-
-
-
IntelliJ
application.yml수정spring: profiles: active: local --- ## 아래 코드 추가 spring: group: prod: - prod-db --- spring: config: activate: on-profile: local datasource: url: jdbc:h2:mem:test_mem driver-class-name: org.h2.Driver username: sa password:
-
-Dspring.profiles.active = prod로 실행 시킬 때, 운영 EC2 서버에 있는application-prod-db포함하게 설정
-
-
Jenkins 관리 - 플러그인 관리
- CodeDeploy 플러그인 설치
-
작업 생성
-
Freestyle project로 작업 생성

-
-
소스 코드 관리
-
이전 Sonarqube 연동 시 설정해줬던 것과 같이
Repository URL,Credentials설정
-
-
빌드 유발
-
Github에 push가 되었을 때, Jenkins에 hook을 날려 자동 빌드할 수 있도록 Github hook trigger 선택

-
-
Build
- 이전 빌드 결과물을 제거 후, 새로 빌드한 jar 파일 생성하기 위해
./gradlew clean build입력

- 이전 빌드 결과물을 제거 후, 새로 빌드한 jar 파일 생성하기 위해
-
빌드 후 조치
-
Deploy an application to AWS CodeDeploy 선택하여 아래와 같이 입력

-
AWS CodeDeploy Application Name: CodeDeploy 애플리케이션 이름 -
AWS CodeDeploy Deployment Group: CodeDeploy 애플리케이션의 배포 그룹 이름 -
AWS Region: AP_NORTHEAST_2 (서울 Region) -
S3 Bucket: S3 버킷 이름 -
Include Files: CodeDeploy가 배포 EC2로 옮길 파일들-
jar파일 +appspec.yml+ scripts/deploy.sh + scripts/kill_process.sh 가 옮겨진다.
-

- 여기서 발급했던 IAM 사용자의 키를 입력해준다.
-
-
-
Github hook 설정
-
Github - Repository - Settings - Webhooks에 가서
http://젠킨스 EC2 서버:포트/github-webhook/로 입력해주고 아래와 같이 설정 후 생성해주면 된다.

- 위와 같이 초록색으로 체크표시가 나야 정상적으로 작동한다는 것을 알 수 있다.
-
- 지정한 브랜치에 Push시



-
sudo netstat -tnlp입력

-
vim /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log
- Spring Boot 에러 확인은
sudo vim ~/app/jenkins/nohup.out를 통해 확인하면 된다.
- Spring Boot 에러 확인은
- Nginx 1대(80 포트, 443 포트), Spring Boot jar 2대(8081 포트, 8082 포트) 적용할 예정
- Nginx는 웹 서버, 리버스 프록시, 캐싱, 로드 밸런싱, 미디어 스트리밍을 위한 오픈소스 소프트웨어로, 현재 Apache를 대체하는 가장 유명한 웹 서버이자 오픈소스다.
- 외부의 요청을 받아 백엔드 서버로 요청을 전달하는 행위인 리버시 프록시를 사용하여 무중단 배포 환경을 구축한다.
- Nginx 설치
- 이전 Jenkins 2. 설치 및 실행의 8 ~ 12번 과정을 똑같이 따라해주면 된다.)
CICD - Jenkins와 CodeDeploy를 이용한 CICD 구축하기 - 2 (구축)
Jenkins) AWS Codeploy와 S3, Github를 이용해 Jenkins CI 구축하기(1)
[Devops] Github Action을 사용한 Spring boot & gradle CI/CD 구축 - 2
[AWS] Spring Boot, Jenkins, CodeDeploy로 CI/CD 하기
CodeDeploy 란 무엇입니까? - AWS 공식 문서