공hannah부
CI & CD 본문
이론
CI(Continuous Integratrion)란?
개발을 하면서 코드에 대한 통합을 지속적으로 진행함으로써 코드 품질을 유지하는 것
CD(Continous Delivery/Deploy)란?
배포를 자동화하여 지속적으로 배포하는 것
Github Actions + AWS CodeDeploy 아키텍쳐
구현
- EC2 인스턴스 시작
- EC2 tag 추가
- IAM 역할 추가 - EC2 인스턴스에서 S3에 올려놓은 파일에 접근할 수 있도록
- IAM(Identity and Access Management)는 AWS 리소스에 대해 엑세스를 안전하세 제어할 수 있는 웹 서비스이다.
- 이를 사용해 리소스를 사용하도록 인증 및 권한 부여된 대상을 제어한다.
- EC2에 IAM 역할 추가
- EC2에 CodeDeploy Agent 설치(Putty를 이용해 EC2 서버에 원격 접속 후 명령어 입력)
$ sudo apt update
$ sudo apt install ruby-full
$ sudo apt install wget
$ cd /home/ubuntu
$ wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto > /tmp/logfile
$ sudo service codedeploy-agent status
- EC2 서버에 루트 디렉토리 만들기(프로젝트를 빌드하고 실행할 루트 디렉토리)
- AWS S3 생성
- CodeDeploy를 위한 IAM 만들기
- CodeDeploy 애플리케이션 생성
- CodeDeploy 배포 그룹 생성
- GitHub Actions를 위한 IAM 사용자 추가
- 추가시 마지막 단계에서 [완료]를 누르기 전 [.csv 파일 다운로드] 눌러 다운 받기!!
- Github Secrets에 IAM User 엑세스 키 정보 / Application 정보 추가
- Settings -> New repository secret
- appspec.yml 작성(Code Deploy에서 배포하 위해 참조 파일 루트 디렉토리에 작성한다)
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/{내 루트 디렉토리 이름}
overwrite: yes
file_exists_behavior: OVERWRITE
permissions:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu
hooks:
AfterInstall:
- location: scripts/stop.sh
timeout: 60
runas: ubuntu
ApplicationStart:
- location: scripts/start.sh
timeout: 60
runas: ubuntu
- 배포 스크립트 작성(루트 디렉토리 아래에 scripts 디렉토리 생성후 그 자리에)
- scripts/start.sh
#!/usr/bin/env bash
PROJECT_ROOT="/home/ubuntu/{내 루트 디렉토리 이름}"
JAR_FILE="$PROJECT_ROOT/spring-webapp.jar"
APP_LOG="$PROJECT_ROOT/application.log"
ERROR_LOG="$PROJECT_ROOT/error.log"
DEPLOY_LOG="$PROJECT_ROOT/deploy.log"
TIME_NOW=$(date +%c)
# build 파일 복사
echo "$TIME_NOW > $JAR_FILE 파일 복사" >> $DEPLOY_LOG
cp $PROJECT_ROOT/build/libs/*.jar $JAR_FILE
# jar 파일 실행
echo "$TIME_NOW > $JAR_FILE 파일 실행" >> $DEPLOY_LOG
nohup java -jar $JAR_FILE > $APP_LOG 2> $ERROR_LOG &
CURRENT_PID=$(pgrep -f $JAR_FILE)
echo "$TIME_NOW > 실행된 프로세스 아이디 $CURRENT_PID 입니다." >> $DEPLOY_LOG
- scripts/stop.sh
#!/usr/bin/env bash
PROJECT_ROOT="/home/ubuntu/{내 루트 디렉토리 이름}"
JAR_FILE="$PROJECT_ROOT/spring-webapp.jar"
DEPLOY_LOG="$PROJECT_ROOT/deploy.log"
TIME_NOW=$(date +%c)
# 현재 구동 중인 애플리케이션 pid 확인
CURRENT_PID=$(pgrep -f $JAR_FILE)
# 프로세스가 켜져 있으면 종료
if [ -z $CURRENT_PID ]; then
echo "$TIME_NOW > 현재 실행중인 애플리케이션이 없습니다" >> $DEPLOY_LOG
else
echo "$TIME_NOW > 실행중인 $CURRENT_PID 애플리케이션 종료 " >> $DEPLOY_LOG
kill -15 $CURRENT_PID
fi
- build.gradle 파일 수정(아래 코드 추가)
- 빌드시 -plain.jar 파일이 생기지 않도록
jar{
enable = false
}
- Github Actions Workflow 작성
- Simple workflow -> configure
- deploy.yml 작성
# This is a basic workflow to help you get started with Actions
name: Deploy to Amazon EC2
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
AWS_REGION: ap-northeast-2
S3_BUCKET_NAME: {내가 설정한 버킷명 이름}
CODE_DEPLOY_APPLICATION_NAME: {내가 설정한 앱 이름}
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: {내가 설정한 그룹 이름}
APPLICATION: ${{ secrets.APPLICATION }}
permissions:
contents: read
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- uses: actions/checkout@v2
- run: touch ./src/main/resources/application.yml
- run: echo "${{env.APPLICATION}}" > ./src/main/resources/application.yml
- uses: actions/upload-artifact@v2
with:
name: application.yml
path: ./src/main/resources/application.yml
- name: Build with Gradle
uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
with:
arguments: clean build -x test
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Upload to AWS S3
run: |
aws deploy push \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--ignore-hidden-files \
--s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \
--source .
- name: Deploy to AWS EC2 from S3
run: |
aws deploy create-deployment \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
--s3-location bucket=$S3_BUCKET_NAME,key=$GITHUB_SHA.zip,bundleType=zip
- Commit, push 후 actions, codedeploy에서 배포 내역 확인하기
build Gradlew에서 execute permission 에러시
터미널에서
git update-index --chmod=+x./gradlew
하고 commit, push 하기
'공부 > 백엔드' 카테고리의 다른 글
자바 ORM 표준 JPA 프로그래밍 CH04 (엔티티 매핑) (0) | 2023.06.26 |
---|---|
자바 ORM 표준 JPA 프로그래밍 CH03 (영속성 관리) (0) | 2023.06.26 |
자바 ORM 표준 JPA 프로그래밍 CH02 (0) | 2023.05.22 |
EC2 서버에 프로젝트 배포하기 (0) | 2023.05.05 |
AWS에 데이터베이스 환경 만들기-AWS RDS (0) | 2023.05.05 |