CI/CD Pipeline을 결정할 때
Github Actions와 Jenkins
두가지 파이프라인에 대한 특징들을 비교해 보았습니다.
Jenkins와 다르게 Github Action은 스크립트가 github 소스코드 내에서 관리되고 직관적인 UI를 가진다는 특징이 있었고
Jenkins의 경우에는 깃헙 내부에만 제한 되지 않는 높은 확장성이 있다는 장점이 있었습니다.
Github를 사용할 것이고 간편한 자동배포에 목적성이 있다고 생각하여 Gihub Actions 를 사용하기로 결정했습니다.
EC2 인스턴스 생성 -> IAM ROLE 생성 후 지정 ->
빌드 파일을 올린 s3 버킷 생성 -> IAM ROLE 생성 후 지정 ->
code deploy 생성 -> IAM ROLE 생성 후 지정
deploy.yml 작성
name: Deploy to Amazon EC2
on:
push:
branches:
- master
env:
AWS_REGION: ap-northeast-2
S3_BUCKET_NAME: hangu-github-actions-s3-bucket
CODE_DEPLOY_APPLICATION_NAME: my-codedeploy-app
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: my-codedeploy-deployment-group
permissions:
contents: read
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- run: touch ./src/main/resources/application.properties
- run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties
- run: cat ./src/main/resources/application.properties
- name: Make gradlew executable
run: chmod +x gradlew
- 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
sh 파일 작성
start.sh
#!/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
stop.sh
#!/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
문제점: 환경변수 등록 문제
이 문제가 정말 하루종일 골칫거리였다..
application properties 파일에 환경변수를 지정해두고
github repository -> settings -> secrets and variables
-> Actions -> Actions secrets and variables 에서
해당 환경변수를 properties 파일에 통쨰로 넣어주는 방식으로 사용하니 해결이 됐다.
- run: touch ./src/main/resources/application.properties
- run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties
- run: cat ./src/main/resources/application.properties
echo 명령이 APPLICAITON에 저장된 파일을 properties 파일에 넣어준다.
CI/CD는 구축성공..