CI / CD
애플리케이션 개발 단계를 자동화하여 애플리케이션을 더욱 짧은 주기로 고객에게 제공하는 방법으로 지속적인 통합, 서비스 제공, 배포 라고 한다. 일명 말하는 통합 지옥을 해결하기 위한 솔루션이라고 한다.
해당 구축 사레를 일반적으로 CI/CD 파이프라인이라고 부른다.
GithubAction 을 통한 AWS EC2 에 배포 / Jenkins
위와 같이 Github 에 올리게 되면 Github Action 이 S3 에 넣어놓고 CodeDeploy 를 통해 EC2 에 배포하게 된다.
위와 같은 방법으로 시도 해봤지만 다른 방법도 많이 있다.
Docker 를 이용하여 할수 도 있고, Jenkins 를 통해 EC2 서버를 한대 더 만들어서 관리 할수 있다.
( 꼭 해보고 싶다 )
하지만 처음으로 구성해보는 파이프라인이라 쉽게 접근 할 수 있는 GIthub Action 를 선택하여 개발진행해봤으므로 그 방법에 대해 블로그를 작성 할려고 한다.
개인적으로 Jenkins 의 장점이 있지만, 구지 EC2 하나를 더 만들어서 돈을 나가도록 만들어야 되나... 고민이 든다.
EC2 준비
EC2 는 ubuntu 로 기본 생성을 해놓는다.
다만 태그 관리를 해야 한다.
위와 같이 태그 관리를 들어간다.
그렇게 들어가면 기본적으로 이렇게 제공해주는데 좀더 Key 를 알수 있도록 수정해놓는다.
다만 테스트로 만들었기 때문에 그냥 진행하겠다.
EC2 에서 설치 할것들.
먼저 codedeploy-agent 를 설치하여야 한다.
sudo apt update
sudo apt install ruby-full
sudo apt install wget
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
S3 설치
S3 도 퍼블릭 액세스를 차단한 상태로 생성한다.
애플리케이션 이름을 알아둬야 한다. ( 이름으로 연결해야 함 )
CodeDeploy 생성
codeDeploy 도 생성하고 안에 그룹을 생성해야 한다.
다만, 애플리케이션 이름과 그룹 이름을 알아둬야 한다. ( 이름으로 연결해야 함 )
또한 그룹을 생성할때 EC2 에서 설정한 태그를 추가해야 한다.
IAM 권한 / 생성
검색에
AmazonS3FullAccess, AWSCodeDeployFullAccess 추가 해준다.
또한, 권한에 들어가서 액세스 설정을 통해 액세스 키, 시크릿 액세스키를 따로 저장해야 한다.
EC2 역할수정
만들어놓은 EC2 에 IAM 역할 수정을 누른다.
또한 IAM 역할 수정을 해야 한다.
들어가게 되고 아래 처럼 아까 IAM 역할을 주면 된다.
AWS 끝
이제 EC2 S3 CodeDeploy 가 준비가 되었다.
우리의 Spring 프로젝트를 가보자.
먼저 GithubAction 공식문서에 파일명은 무조건 .github/workflows 으로 시작해야 한다고 적혀 있다.
그러므로 아래의 구조처럼 파일 생성하자.
공식 문서 : https://docs.github.com/ko/actions/using-workflows/about-workflows
이렇게 나는 deploy yml 을 만들었다.
name: Spring-Boot-twitter-clone-Amazon EC2
on:
push:
branches:
- master
env:
AWS_REGION: ap-northeast-2
S3_BUCKET_NAME: s3 버킷 이름
CODE_DEPLOY_APPLICATION_NAME: codedeploy 이름
CODE_DEPLOY_DEPLOYMENT_GROUP_NAME: codedeplou 그룹 이름
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- run: touch ./src/main/resources/application.yaml
- run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yaml
- run: cat ./src/main/resources/application.yaml
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
shell: bash
- name: Build with Gradle
run: ./gradlew build
shell: bash
- name: Make zip file
run: zip -r ./$GITHUB_SHA .
shell: bash
- 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 }}
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$GITHUB_SHA.zip
- 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
위와 같이 나는 JDK 17 로 썼고 프로젝트를 build 해서 AWS 에 올리도록 하였다. 또한 master 브랜치에 push 하게 되면 gitAction 이 알아서 배포를 도와준다.
${{secrets}} 은 뒤에 더 자세히 설명 하겠다.
또한 루트 경로에 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/gh_deploy.sh
timeout: 60
runas: ubuntu
/home/ubuntu/github_action 배포시 이 경로로 파일 배포가 실행되고 그전에 hooks 를 통해 scripts/gh_deploy.sh 쉘이 발동되게 하였다.
해당 파일에는 아래처럼 구성하면 된다. 주의할점은 .jar 이름이 안가져와서 나는 gradle 에 이름을 써놓고 지정을 해버렸다.
#!/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/$PROJECT_NAME/deploy.log"
DEPLOY_ERR_LOG_PATH="/home/ubuntu/$PROJECT_NAME/deploy_err.log"
APPLICATION_LOG_PATH="/home/ubuntu/$PROJECT_NAME/application.log"
BUILD_JAR=$(ls $JAR_PATH)
JAR_NAME="/twitter.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 "/home/ubuntu/github_action/twitter.jar" >> $APPLICATION_LOG_PATH 2> $DEPLOY_ERR_LOG_PATH &
sleep 3
echo "> 배포 종료 : $(date +%c)" >> $DEPLOY_LOG_PATH
마지막으로 secret 설정
deploy.yml 에 있는 {secret.} 하고 있는것들 즉 환경변수를 설정해야 한다.
해당 저장소에 가서 Settings 를 누르고
위와 같이 Actions 에 들어가서 New repository secret 누르고 환경변수 키의 값까지 설정하면 진짜 끝이다!
이렇게 되면 다 끝났다. master 브랜치에 푸쉬를 넣게 되면
위와같이 배포하는것을 볼수 있다.
마지막...
마지막으로 GithubAction 으로 CI/CD 파이프 라인을 구축하니 확실히 편해졌다. 전에는 scp 명령어로 직접 파일 넣고 실행하고 그랬던 작업이 초기 작업으로 인해 편리해지다니.. 너무 좋았던 경험이였다!
'AWS' 카테고리의 다른 글
LoadBalancer (1) | 2023.08.31 |
---|---|
ElastiCache - Redis 설정 (0) | 2023.08.29 |
AWS scale-up (0) | 2023.08.24 |
Swap (0) | 2023.08.18 |
AWS ECR (0) | 2023.07.31 |