[SpringBoot] Github Action으로 AWS EC2 자동 빌드/배포하기(CI/CD)
빗썸테크아카데미의 강의가 끝나고
팀프로젝트가 시작되었는데, 개발에 앞서 우선 aws에 배포해서
Hello world를 먼저 찍어보고 개발을 하기로 했다.
저번에 CI/CD의 아름다움을 맛본 나는
이번 프로젝트에서 미리 구축해놓고 사용하기로 했다.
지난번에는 Jenkins를 이용해 springboot를 로컬에 자동 빌드, 배포를 해보았는데
이번에는 Github Action을 이용해 AWS에 CI/CD를 해보려고 한다.
Github Action도, AWS도 전부 처음이라 두근두근해
spring boot의 jar 파일은 aws에 바로 올릴수 없기 때문에,
zip으로 압축해서 aws의 s3에 올린 후,
ec2에서 s3에 있는 zip 파일을 가져다가 압축해제하고 자동 배포를 하는
파이프라인을 구축해보자.
1. 깃허브 액션 생성
helloworld가 출력되는 가벼운 spring boot 프로젝트를 만들어
깃허브 리파지토리와 연동한 후,
해당 리파지토리의 set up a workflow yourself를 눌러서
main.yml 파일을 생성한다.
main.yml
name: coinTalk chatRoom server CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
S3_BUCKET_NAME: cointalk-deploy
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew clean build
main.yml에 위의 코드를 입력 후 커밋
약 1분 30초 후 Actions에서 성공적으로 build 한 것을 확인 할 수 있다.
github actions를 이용한 자동빌드 성공!
혹시 몰라 코드를 수정하고 push 해보았다.
성공한 결과를 확인!
2. IAM 사용자 생성
IAM 사용자 - 사용자 추가를 클릭
사용자의 이름을 지정한 뒤, 액세스 유형을 선택하고 다음 클릭
기존 정책 직접 연결을 체크하고
AmazonEC2FullAccess
AmazonS3FullAccess
AWSCodeDeployFullAccess
세가지를 추가
그 다음 확인을 계속 진행하면
위와 같은 액세스 키 ID와 비밀 액세스 키를 얻을 수 있다.
(처음에 사용자가 ID고, 액세스 키 ID가 비밀번호인줄 알고 삽질함)
그 후 깃허브 - 리파지토리 - Settings - Secrets - Actions
New repository secret을 눌러
아래와 같이 추가
AWS_ACCESS_KEY_ID : 위에서 얻은 액세스 키 ID
AWS_SECRET_ACCESS_KEY : 위에서 얻은 비밀 액세스 키
3. S3 생성
버킷 이름을 적고
우리는 IAM에서 만든 사용자로 S3의 FullAccess를 얻을 수 있기 때문에
보안을 위해 모든 퍼블릭 액세스를 차단한 후 생성
그 후 main.yml을 수정
main.yml
name: coinTalk chatRoom server CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
S3_BUCKET_NAME: cointalk-deploy
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew clean build
# 디렉토리 생성
- name: Make Directory
run: mkdir -p deploy
# Jar 파일 복사
- name: Copy Jar
run: cp ./build/libs/*.jar ./deploy
- name: Make zip file
run: zip -r ./coinTalk.zip ./deploy
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: ap-northeast-2
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./coinTalk.zip s3://$S3_BUCKET_NAME/
파일을 압축하고, s3에 업로드 하는 내용을 추가 및 커밋
약 2분 후에 S3에 zip 파일이 잘 올라간 것을 확인 할 수 있다.
4. IAM 역할 생성
1) EC2용 역할
Deploy를 위해 IAM 역할을 만들어 준다.
IAM로 들어가서 역할 - 역할만들기를 클릭
aws 서비스 - EC2 선택
권한 정책에서 아래 2가지를 검색해 체크해서 추가
AmazonS3FullAccess
AWSCodeDeployFullAccess
역할 이름을 부여해주고, 권한이 추가된 것을 확인 한 후 역할을 생성
2) 애플리케이션 그룹용 역할
IAM로 들어가서 역할 - 역할만들기를 클릭
사용사례를 CodeDeploy로 선택해 준 후
다른 부분은 건드리지 않고,
역할 이름을 정한 후 역할을 생성
처음에 애플리케이션 그룹에 서비스 역할이 안떠서
삽질을 많이 했었는데...
저는 그 당시 다른 방법으로 수정을 했지만
찾아보니 이 방법이 훨씬 깔끔해보여 작성 :)
5. EC2 생성
우측 상단 지역을 서울로 클릭하고, 인스턴스 시작을 클릭
인스턴스의 이름을 정하고, 아래에서 ubuntu를 선택해 준 뒤
(ubuntu 20.04 추천. 22.04 사용시 ec2에서 여러 ruby 호환 에러 남)
인스턴스 유형은 t2.micro를 선택하고, 새 키페어를 생성
키페어의 이름을 입력하고 키페어 생성. 키페어 생성시 다운로드 된 pem키는 잘 보관해 둔다.
인스턴스를 생성
인스턴스에서 오른쪽 버튼 클릭 후 보안 - IAM 역할 수정
아까 만들어둔 ec2용 역할을 선택한 후 저장
6. EC2 접속 후 셋팅
아까 저장해두었던 pem 키를 이용해 EC2인스턴스에 접속
나는 윈도우 사용자라 아래 링크를 참고해서 진행했다.
https://wookim789.tistory.com/34
ssh로 ec2에 잘 접속했다면
EC2 에서 /home/ubuntu에 app 디렉토리를 하나 생성
그후 아래 커맨드 입력
sudo apt update
sudo apt install ruby-full
sudo apt install wget
cd /home/ubuntu
sudo apt install awscli
aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2
chmod +x ./install
sudo ./install auto
# 아래 코드로 설치 확인
sudo service codedeploy-agent status
설치가 잘된 경우
다음과 같은 코드를 볼수있다.
처음에 아무생각 없이 ubuntu 최신 버전으로 ec2를 생성했다가 ruby 호환 오류가 나서 열심히 삽질하다가
지우고 새로 까는게 빠르다고 판단되어 결국 ec2 지우고 ubuntu 버전 한단계 내려서 설치했다.
그 다음 jdk 설치
# jdk 11버전 설치
sudo apt-get install openjdk-11-jdk
# java 설치 확인
java
각자 프로젝트 버전에 맞는 jdk를 설치해주면 된다.
7. CodeDeploy
CodeDeploy - 애플리케이션 - 애플리케이션 생성
배포그룹 이름을 입력하고
서비스 역할에서
위에서 생성한
애플리케이션 그룹용 역할을 클릭
환경구성에서 EC2 인스턴스 클릭 후
배포할 EC2 선택 후
그룹을 생성
8. 자동 배포를 위한 스크립트 추가
1) appspec.yml 설정
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/app/
overwrite: yes
permissions:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu
hooks:
ApplicationStart:
- location: deploy.sh
timeout: 60
runas: ubuntu
root 바로 아래 (build.gradle과 같은 위치)에 appspec.yml을 생성하고 위의 코드를 작성
2) deploy.sh 생성
#!/usr/bin/env bash
REPOSITORY=/home/ubuntu/app
echo "> 현재 구동 중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -fla java | grep hayan | awk '{print $1}')
echo "현재 구동 중인 애플리케이션 pid: $CURRENT_PID"
if [ -z "$CURRENT_PID" ]; then
echo "현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다."
else
echo "> kill -15 $CURRENT_PID"
kill -15 $CURRENT_PID
sleep 5
fi
echo "> 새 애플리케이션 배포"
JAR_NAME=$(ls -tr $REPOSITORY/*SNAPSHOT.jar | tail -n 1)
echo "> JAR NAME: $JAR_NAME"
echo "> $JAR_NAME 에 실행권한 추가"
chmod +x $JAR_NAME
echo "> $JAR_NAME 실행"
nohup java -jar -Duser.timezone=Asia/Seoul $JAR_NAME >> $REPOSITORY/nohup.out 2>&1 &
root 바로 아래 (build.gradle과 같은 위치)에 scripts/deploy.sh를 생성하고 위의 코드를 작성
3) main.yml 수정
name: coinTalk chatRoom server CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
S3_BUCKET_NAME: cointalk-deploy
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew clean build
# 디렉토리 생성
- name: Make Directory
run: mkdir -p deploy
# Jar 파일 복사
- name: Copy Jar
run: cp ./build/libs/*.jar ./deploy
# appspec.yml 파일 복사
- name: Copy appspec.yml
run: cp appspec.yml ./deploy
# script files 복사
- name: Copy script
run: cp ./scripts/*.sh ./deploy
- name: Make zip file
run: zip -r ./coinTalk.zip ./deploy
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: ap-northeast-2
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./coinTalk.zip s3://$S3_BUCKET_NAME/
# Deploy
- name: Deploy
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws deploy create-deployment \
--application-name coinTalk[만든 애플리케이션 이름] \
--deployment-group-name coinTalk-group[만든 애플리케이션 그룹 이름] \
--file-exists-behavior OVERWRITE \
--s3-location bucket=cointalk-deploy[S3버킷이름],bundleType=zip,key=coinTalk.zip[S3버킷 속 압축파일] \
--region ap-northeast-2
위와 같이 수정하고 커밋
9. 포트열기
외부에서 EC2로 접근할 수 있도록 포트를 열어줘야 한다.
EC2 -> 인스턴스를 클릭 후 아래에서 보안 - 보안그룹을 눌러준다.
사진은 내가 미리 추가해두었는데, 처음에는 SSH 하나만 보인다.
인바운드 규칙 - 인바운드 규칙 편집
위와같이 내가 쓰고자 하는 포트를 열어준다 (나는 8080)
저장 후
깃에 test commit을 해주고 난 뒤
EC2 -> 인스턴스 클릭 -> 퍼블릭 IPv4:port 로 접속하면
헬로 월드를 만날수 있다!!
퍼블릭 IP:port
퍼블릭주소:port
둘다 가능
팀원들한테 자랑하러가야지 ~.~
'Spring Boot' 카테고리의 다른 글
[Spring Boot] aws s3 presignedUrl로 업로드 하는 법(One Time Token, OTT) (0) | 2022.07.29 |
---|---|
[SpringBoot]Jenkins/windows 빌드 및 배포 자동화 - 4단계 자동 배포 (4) | 2022.03.24 |
[SpringBoot]Jenkins/windows 빌드 및 배포 자동화 - 3단계 자동 빌드 (0) | 2022.03.24 |
[SpringBoot]Jenkins/windows 빌드 및 배포 자동화 - 2단계 github 연동 (0) | 2022.03.23 |
[SpringBoot]Jenkins/windows 빌드 및 배포 자동화 - 1단계 windows에 설치 (0) | 2022.03.23 |
댓글