이제 GitHub으로 들어와서 나머지 설정들을 해보자
1. deploy.yaml 작성하기 ( github action등록하기)
프로젝트 Repo의 Actions에 들어와 New workflow를 눌러준다
만약 기존 workflow가 없다면 아래와 같은 화면이 바로 나올 것 이다.
여기서 set up a workflow yourself를 눌러준다.
그러면 파일등록 창이 나오는데 여기에 아래 코드를 복사해서 붙여 넣어 준다.
name: CI-CD
on:
push:
branches:
- main
env:
S3_BUCKET_NAME: 설정한 버킷 이름
RESOURCE_PATH: ./src/main/resources/application.yaml
CODE_DEPLOY_APPLICATION_NAME: 설정한 codedeploy 애플리케이션 이름
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: 설정한 codedeploy 배포그룹 이름
jobs:
build:
runs-on: ubuntu-20.04 #ec2에 설치한 ubuntu버전
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: 17 #프로젝트 및 ec2에 적용된 java version
# [1]
- name: Set yaml file
uses: microsoft/variable-substitution@v1
with:
files: ${{ env.RESOURCE_PATH }}
env:
override.value: ${{ secrets.DI_FROM_SECRET }}
# override.value: 'from deploy.yaml' <-- 이렇게 사용해도 주입이 된다.
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
shell: bash
# [2]
- name: Build with Gradle
run: ./gradlew build
shell: bash
# [3]
- name: Make zip file
run: zip -r ./$GITHUB_SHA.zip .
shell: bash
# [4]
- 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: ${{ secrets.AWS_REGION }}
# [5]
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip
# [6]
- name: Code Deploy
run: |
aws deploy create-deployment \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--deployment-group-name ${{ env.CODE_DEPLOY_DEPLOYMENT_GROUP_NAME }} \
--s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$GITHUB_SHA.zip
설정한 이름을 환경변수로 저장해준다.
그리고, 자바 버전을 프로젝트에 맞게 설정한다.
여기서 [1], [2], [3] 얘네들은 단계를 의미하는데 1단계의 경우 동적으로 변수에 값을 주기 위한 step이다.
나는 해당 부분을 지금 당장은 주석처리 해놓긴 했지만 이 글을 참고해보면 나중을 위해선 따로 또 파일을 만들어 분리해주는게 좋을 것 같다.
2단계는 Gradle로 빌드를 하는 step이다.
3단계는 빌드한 프로젝트 파일을 압축해서 저장시키는 단계다.
4단계는 AWS 서비스에 접근하기 위해 권한을 받아오는 step이다.
5단계는 S3로 결과물을 저장하는 step이다.
6단계는 CodeDeploy로 배포명령을 주는 단계이다.
이렇게 action 등록을 완료했다.
2. appspec.yml 등록하기
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/github_action
overwrite: yes
permissions:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu
hooks:
ApplicationStart:
- location: scripts/build.sh
timeout: 60
runas: ubuntu
해당 파일을 프로젝트 저장소 최상단에 추가한다.
files는 여기서 source, destination, overwrite로 이루어져 있다.
source의 경우 인스턴스에 복사할 대상 파일들의 경로를 의미한다. 즉, 여기선 appspec이 프로젝트 최상단에 위치하기에 프로젝트 전체가 대상이 된다.
destination의 경우 ec2인스턴스에서 파일이 복사될 위치를 의미한다.
overwrite은 말그대로 덮어쓰기를 할 것 인지 설정하는 것이다.
permissions는 files에서 정의된 파일이 복사된 후 해당 파일의 권한을 적용하는 것을 담당한다. 구성의 경우 object, pattern, owner, group으로 이루어져 있다.
자세한 내용은 여기를 참조하고 글에선 간단하게만 정리한다.
object는 문자열을 사용해 대상을 지정한다.
pattern은 권한을 적용할 패턴을 지정한다. 여기서 지정하지 않거나 **을 사용하면 권한이 Type에 따라 일치하는 모든 파일에 적용된다.
owner는 object의 소유자를 의미한다
group은 object의 그룹 이름을 의미한다.
hooks의 경우 배포과정에서 해당단계(ApplicationStart)에서 사용할 스크립트를 지정하고(location) 타임아웃 시간을 설정하며 ec2인스턴스의 운영체제를 등록한다.
#여기서 location은 appspec이 저장된 위치기준 경로이다.
추가로
jar {
enabled = false
}
이 코드를 build.gradle에 추가해준다.
spring boot 2.5부터 빌드를 그냥 하면 plain.jar가 추가로 생성되기에 해당 옵션을 그레이들에 추가하여 plain빌드 파일을 생성하지 않도록 한다. 만약 둘 다 빌드되게 설정되어 있다면 (아래에서 볼 스크립트파일) build.sh에서 빌드 파일을 특정짓지 못하거나 랜덤하게 빌드가 될 수 있다.
3. build.sh 작성
사실 이부분이 제일 골치아팠는데, 처음엔 ec2인스턴스에 파일을 넣어야 하는 줄 알고 해당 경로를 만들고 scp로 ec2에 파일을 복사했더니 code deploy에서 스크립트를 못찾겠다는 오류를 띄웠다.
근데 이걸 ec2에 넣는게 아닌 project repository에 추가하면 되는 것이었다..
위처럼 프로젝트에서 지정한 경로인 scripts/build.sh를 만들고
#!/bin/bash
#PROJECT_NAME="github_action"
JAR_PATH="/home/ubuntu/github_action/build/libs/*.jar"
DEPLOY_PATH=/home/ubuntu/$PROJECT_NAME/
DEPLOY_LOG_PATH="/home/ubuntu/github_action/deploy.log"
DEPLOY_ERR_LOG_PATH="/home/ubuntu/github_action/deploy_err.log"
APPLICATION_LOG_PATH="/home/ubuntu/github_action/application.log"
BUILD_JAR=$(ls $JAR_PATH)
JAR_NAME=$(basename $BUILD_JAR)
echo "===== 배포 시작 : $(date +%c) =====" >> $DEPLOY_LOG_PATH
echo "> build 파일명: $JAR_NAME" >> $DEPLOY_LOG_PATH
echo "> build 파일 복사" >> $DEPLOY_LOG_PATH
cp $BUILD_JAR $DEPLOY_PATH
echo "> 현재 동작중인 어플리케이션 pid 체크" >> $DEPLOY_LOG_PATH
CURRENT_PID=$(pgrep -f $JAR_NAME)
if [ -z $CURRENT_PID ]
then
echo "> 현재 동작중인 어플리케이션 존재 X" >> $DEPLOY_LOG_PATH
else
echo "> 현재 동작중인 어플리케이션 존재 O" >> $DEPLOY_LOG_PATH
echo "> 현재 동작중인 어플리케이션 강제 종료 진행" >> $DEPLOY_LOG_PATH
echo "> kill -9 $CURRENT_PID" >> $DEPLOY_LOG_PATH
kill -9 $CURRENT_PID
fi
DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> DEPLOY_JAR 배포" >> $DEPLOY_LOG_PATH
nohup java -jar $DEPLOY_JAR >> $APPLICATION_LOG_PATH 2> $DEPLOY_ERR_LOG_PATH &
sleep 3
echo "> 배포 종료 : $(date +%c)" >> $DEPLOY_LOG_PATH
위 코드를 복사해서 넣어준다.
여기서 또 주의할 점은 해당 코드를 텍스트 편집기나 인텔리제이에서 작성하고 업로드하면 안된다는 점이다..
경로에 이상이 없는데 계속 오류가 나길래 뭔가 싶어 깃헙에서 파일을 열어보니 파일이 꺠져있었다 .....
그러니, 직접 add file로 생성해야 한다.
또, 2단계 마지막에 설명한 것 처럼 빌드한 jar파일을 *.jar로 인식하기에 꼭 plain을 빌드하지 않게 설정해주어야 한다 !
여기까지 작성하였다면 actions탭을 눌러 정상적으로 동작하는지 확인해보면 된다.
Github Action은 무사히 잘 동작했고
버킷에도 파일이 잘 들어와 있고
CodeDeploy도 정상적으로 동작한 걸 확인할 수 있다.
인스턴스에도 빌드 파일 및 프로젝트 파일이 잘 들어와있고
배포도 정상적으로 진행되고 있는걸 확인할 수 있다 !
이렇게 GitHub Action, AWS S3,CodeDeploy,EC2,IAM을 이용해 프로젝트의 CI/CD를 적용해보았다.
생각보단 난관이 있긴 했지만 그래도 비교적 쉽게 적용할 수 있었다.
이제 프로젝트에 이메일 인증 기능을 구현 해 봐야 겠다.
참고
https://goodgid.github.io/Github-Action-CI-CD-Workflows/
https://goodgid.github.io/Github-Action-CI-CD-CodeDeploy-App-Spec-File/
https://goodgid.github.io/Github-Action-CI-CD-Build-Gradle-File/
https://velog.io/@bluewind8791/Github-Actions
'DevOps' 카테고리의 다른 글
React+Github Action+AWS로 CI,CD 하기 (0) | 2023.05.01 |
---|---|
[Github actions, secret]github workflow로 배포 시 json 파일 추가하기 (0) | 2023.04.29 |
[AWS RDS] 로컬에서 RDS 연결이 안된다..! (0) | 2023.04.29 |
Github secret으로 배포용 application.yml 암호화 하기 (0) | 2023.04.17 |
GitHub Action, AWS S3,CodeDeploy, EC2로 CI, CD해보기 (1) (1) | 2023.04.16 |