-
Notifications
You must be signed in to change notification settings - Fork 0
Build CICD pipeline with Github Action ‐3 : AppSpec, shell script, Github Action workflow 파일 작성하기
Written by Dayeon Kim
저번장까지 환경 세팅을 다 했으므로 이번장부터는 배포 자동화 step에 맞도록 파일을 잘 작성해보자
파일 위치 : 프로젝트의 루트 경로
CodeDeploy가 수행할 일들을 지정하는 파일이다
🚨 참고로 프로젝트 파일 안에서 루트가 아니라 repository 자체에서 루트이다.. (이거때문에 고생좀 했음)
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/app
overwrite: yes
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
/ 인 경우 수정버전의 모든 파일이 인스턴스에 복사된다
현재 배포 중인 애플리케이션 수정 버전의 파일 버전이 인스턴스에 이미 있는 버전을 대체
인스턴스에서 파일이 복사되어야 하는 위치를 나타낸다
결과 이미지 첨부함
아래와같이 지정한 디렉토리에 복사됨
파일 시스템 객체가 인스턴스로 복사된 이후 지정한 권한이 적용되는 파일 시스템 객체 (파일, 디렉토리,폴더)
배포이후에 수행할 스크립트를 지정하는 곳이다
pipeline은 아래와같이 구성된다
hooks:
AfterInstall:
- location: scripts/stop.sh
timeout: 60
runas: ubuntu
ApplicationStart:
- location: scripts/start.sh
timeout: 60
runas: ubuntu
🔖 AfterInstall : 파일을 설치한 후 AfterInstall에서 기존에 실행중이던 어플리케이션을 종료시키고 .. →
🔖 ApplicationStart: ApplicationStart에서 새로운 어플리케이션을 실행한다
블로그 에서 찾은 코드로 작성하였음
#!/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
실행하는 코드
build 할 JAR파일을 복사하여 nohup
으로 실행한다
#!/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
jar {
enabled = false
}
tasks.getByName<Jar>("jar") {
enabled = false
}
workflow를 지정해주는 파일
GithubAction이 시작하는 파일로 이 파일을 기점으로 앞에서 만들어준 파일들이 실행됨
name: Deploy to Amazon EC2
on:
push:
branches:
- feature/21-deploytestbranch
# 본인이 설정한 값을 여기서 채워넣습니다.
# 리전, 버킷 이름, CodeDeploy 앱 이름, CodeDeploy 배포 그룹 이름
env:
AWS_REGION: ap-northeast-2
S3_BUCKET_NAME: pochak-github-actions-s3-bucket
CODE_DEPLOY_APPLICATION_NAME: pochak-codedeploy-app
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: pochak-codedeploy-deployment-group
permissions:
contents: read
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
# (1) 기본 체크아웃
- name: Checkout
uses: actions/checkout@v3
with:
ref: feature/21-deploytestbranch
# (2) JDK 17 세팅
- name: JDK 17 설치
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'
- name: gradlew에 실행 권한 부여
run: chmod +x ./pochak/gradlew
- name: init gradle
run: gradle init
# (3) Gradle build (Test 제외)
- name: Build with Gradle
uses: gradle/gradle-build-action@v1
with:
arguments: build
gradle-version: 8.1.1
# (4) 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 }}
# (5) 빌드 결과물을 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 .
# (6) 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
에러가 났던 부분이나 중요한 부분 위주로 코드를 살펴보자
- JDK 버전 맞춰주기
- gradlew 경로를 찾지 못하는 문제에서는 프로젝트 파일로 직접 이동을 시켜줘야 했다
🚨 trouble shooting - 1
Cannot locate a Gradle wrapper properties file at '/home/runner/work/2023-POCHAK-server/2023-POCHAK-server/gradle/wrapper/gradle-wrapper.properties'. Specify 'gradle-version' or 'gradle-executable' for projects without Gradle wrapper configured.
🤷🏻♂️ 해결방법
- 버전을 명시해주라길래
gradle-version: 8.1.1
로 버전 명시 - gradle init
🚨 trouble shooting - 2
* What went wrong:
Task 'clean' not found in root project '2023-POCHAK-server'.
🤷🏻♂️ 해결방법
- clean이라는 메서드를 추가적으로 만들어주라고 함...
- 참고했던 블로그들을 보니 그냥
arguments: build
을 하여 해결하신 분들이 많길래 일단 이렇게 작성 - 차이점을 추가적으로 좀 찾아봐야함
결론적으로 수정한 코드는 아래와 같음
# (2) JDK 17 세팅
- name: JDK 17 설치
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'
- name: gradlew에 실행 권한 부여
run: chmod +x ./pochak/gradlew
- name: init gradle
run: gradle init
# (3) Gradle build (Test 제외)
- name: Build with Gradle
uses: gradle/gradle-build-action@v1
with:
arguments: build
gradle-version: 8.1.1
- name: Upload to AWS S3
run: |
aws deploy push \
--application-name ${{ env.CODE_DEPLOY_APPLICATION_NAME }} \
--s3-location s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip \
--ignore-hidden-files \
--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
결과