Day 75
- 실전 프로젝트
오늘은 프로젝트에 CI/CD를 적용했다. 초반에 자바 버전문제와 DB문제 때문에 시간을 많이 잡아먹었는데 그 후로는 무리없이 작동했다. 오늘 있었던 트러블 슈팅을 다 적었었는데 방금 갑자기 다 날라갔다...
다시 정리해보면
자바 버전 문제 : 테스트 프로젝트의 자바 버전을 17로 해놓고 Action의 세팅을 자바 11로 설정해서 생긴 문제였다.
로컬 DB 문제 : 로컬 mysql을 사용한 프로젝트를 CI하는 과정에서 로컬DB와 연결문제가 계속 발생했다. 아무리해도 해결이 안돼서 결국 DB를 RDS로 변경하는 방식으로 해결했다. 아직도 왜 에러가 발생했는지 모르겠다.
그 후로는 큰 문제없이 진행되어서 현재는 main브랜치에 pull request를 요청하면 자동으로 빌드하고 배포하도록 설정하였다. 이제 배포하려고 빌드하고 ubuntu키고 파일질라로 빌드파일 넣고 실행하지 않아도 되니 너무 행복하다. 오늘 공부한 github action에 대해서 정리하고 마무리 해야겠다.
GIthub Action 적용하기
참고 자료
전반적인 진행 과정
application.properties ignore시 적용법
준비물
- EC2 서버 하나 (스파르타 방식대로 하나 만들면 됨)
- IAM 역할 추가 (S3FullAccess, CodeDeployRole) 각각 하나씩
- S3 버킷 하나
- CodeDeploy 애플리케이션, 배포 그룹 하나씩
- IAM 사용자 하나 (DeployFullAccess, S3FullAccess)
IAM 역할 추가
- AmazonS3FullAccess 역할 추가
- AWSCodeDeployRole 역할 추가
EC2 서버 설정
- 태그 추가
작업 -> 인스턴스 설정 -> 태그 관리 -> 태그 하나 추가 (이름은 본이 마음대로) - EC2 역할 부여
보안 -> IAM 역할 수정 -> AmazonS3FullAccess역할 선택
S3 버킷 생성
버킷 하나 만들면 됨
CodeDeploy
$ 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
- ubuntu에 설치
기본 메뉴얼 - 애플리케이션 생성
- EC2/온프레미스로 생성
- 배포 그룹 생성
- 서비스 역할 IAM 역할(AWSCodeDeployRole) 선택
- EC2 인스턴스의 key값은 [EC2 서버 설정]에서 설정한 key값 선택
GithubAction에서 사용할 IAM 사용자 추가
- AWSCodeDeployFullAccess
- AmazonS3FullAccess
Access key, Secret Key
Github Action secret key로 등록하기
파일 작성
- AppSpec.yml
- stop.sh
- start.sh
- build.gradle 수정
AppSpec.yml
전문
CodeDeploy에서 배포를 위해 참조할 파일 -> EC2 배포 설정
루트 디렉토리에 위치해야 한다.
version: 0.0
os: linux
# file section
# 인스턴스에서 파일이 복사되는 위치
# 파일이 있는 경우 대체 여부
files:
- source: /
destination: /home/ubuntu/app
overwrite: yes
# pattern 매칭되는 패턴에만 권한 부여
permissions:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu
# 배포 이후 수행할 스크립트 지정
# AfterInstall : scripts/stop.sh 실행 (기존에 실행중이던 애플리케이션 종료)
# ApplicationStart : scripts/start.sh 실행 (새로운 애플리케이션 실행)
# timeout = 스크립트 실행 허용 시간
hooks:
AfterInstall:
- location: scripts/stop.sh
timeout: 60
runas: ubuntu
ApplicationStart:
- location: scripts/start.sh
timeout: 60
runas: ubuntu
stop.sh
현재 설정에는 scripts 디렉토리에 위치해야함
#!/usr/bin/env bash
PROJECT_ROOT="/home/ubuntu/app"
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
start.sh
현재 설정에는 scripts 디렉토리에 위치해야함
#!/usr/bin/env bash
PROJECT_ROOT="/home/ubuntu/app"
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
build.gradle 수정
build시 jar 파일이 두 개가 생성된다. (~.jar, ~-plaij.jar)
두 개가 만들어지면 *.jar 복사가 안되므로 -plain.jar 파일이 안만들어지도록 설정해야 한다.
// plugin 밑에 위치해야함
jar {
enabled = false
}
workflow 작성
name: Deploy to Amazon EC2
# 현재 main에 pull-request하면 아래 과정(빌드 테스트 후 자동배포) 실행
on:
pull_request:
branches:
- main
# 본인이 설정한 값을 여기서 채워넣습니다.
# 리전, 버킷 이름, CodeDeploy 앱 이름, CodeDeploy 배포 그룹 이름
env:
AWS_REGION: ap-northeast-2
S3_BUCKET_NAME: action-test-bucket
CODE_DEPLOY_APPLICATION_NAME: my-codeDeploy-app
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: my-codeDeploy-app-group
permissions:
contents: read
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
# (1) 기본 체크아웃
- name: Checkout
uses: actions/checkout@v3
# (2) application.properties 추가
- run: touch ./src/main/resources/application.properties
- run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties
- run: cat ./src/main/resources/application.properties
# (3) JDK 11 세팅
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
# (4) Gradle build (Test 제외)
- name: Build with Gradle
uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee
with:
arguments: clean build -x test
# (5) AWS 인증 (IAM 사용자 Access Key, Secret Key 활용)
- 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 }}
# (6) 빌드 결과물을 S3 버킷에 업로드
- 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 .
# (7) S3 버킷에 있는 파일을 대상으로 CodeDeploy 실행
- 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
(2) application.properties 추가
현재 우리 프로젝트에는 application.properties가 ignore에 등록되어 있어서 github에는 존재하지 않음
그래서 따로 배포시 작성하는 과정이 필요함
- Action의 secret에서 APPLICATION(이름은 자유)이란 이름으로 application.properties을 내용으로 가지는 키를 하나 생성한다.
(2)의 과정
# resource 루트에 application.properties 생성
- run: touch ./src/main/resources/application.properties
# 생성된 application.properties에 등록한 secret 키 입력
- run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties
# 열어보기
- run: cat ./src/main/resources/application.properties '항해99 > TIL | WIL' 카테고리의 다른 글
| WIL (10주) (0) | 2023.03.26 |
|---|---|
| 2023.03.25 (76일) (0) | 2023.03.26 |
| 2023.03.23 (74일) (0) | 2023.03.24 |
| 2023.03.22 (73일) (0) | 2023.03.23 |
| 2023.03.21 (72일) (0) | 2023.03.22 |