github Actions + S3 + ec2 무 배포 for Spring (1)
https://soobysu.tistory.com/184
[CICD] github Actions + S3 + ec2 무 배포 for Spring (1)
problem현재 하는 사이드 프로젝트에서는 프리티어를 사용하기 때문에 젠킨스를 사용하지 않고github Actions 를 사용하게 되었다.Jenkins젠킨스를 위한 서버가 필요 없다플러그인이 풍부하여 다양한
soobysu.tistory.com
작당한 이름의 파일을 만들어서
./github/workflows
디렉토리에 넣어두면 자동으로 실행된다.
전체 코드
name: CI/CD Pipeline
on:
pull_request:
branches:
- dev
- prd
- main
push:
branches:
- dev
- prd
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Configure AWS Credentials & Test SSH Connection
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
echo "Configuring AWS credentials..."
aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
aws configure set default.region ap-northeast-2
- name: Set up SSH Key from Secrets
run: |
echo "${{ secrets.EC2_SSH_KEY_ILSANG }}" > /tmp/id_rsa
chmod 600 /tmp/id_rsa
- name: Test SSH Connection
run: |
echo "Testing EC2 SSH connection..."
if ! ssh -i /tmp/id_rsa -o StrictHostKeyChecking=no ${{ secrets.EC2_ILSANG_USERNAME }}@${{ secrets.EC2_HOST_ILSANG }} "echo 'SSH connection successful.'"; then
echo "SSH connection failed. Stopping the workflow."
exit 1
fi
- name: Clean Up SSH Key
if: always()
run: |
rm -f /tmp/id_rsa
- name: Check S3 Health
run: |
echo "Performing S3 health check..."
if aws s3api head-bucket --bucket ${{ secrets.S3_BUCKET_NAME }} --region ap-northeast-2; then
echo "S3 connection successful."
else
echo "Failed to connect to S3."
exit 1
fi
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'
- name: Create AWS Info File
run: |
mkdir -p src/main/resources/aws
echo "${{ secrets.RDS_YAML }}" > src/main/resources/aws/rds-info.yml
echo "${{ secrets.S3_YAML }}" > src/main/resources/aws/s3-info.yml
- name: Test Code
run: ./gradlew test
- name: Build JAR File
run: |
chmod +x gradlew
./gradlew clean bootJar
mkdir -p build/libs
cp build/libs/*.jar apiProject.jar
- name: Upload JAR to S3
run: |
aws s3 cp apiProject.jar s3://${{ secrets.S3_BUCKET_NAME }}/jars/apiProject.jar --region ap-northeast-2
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST_ILSANG }}
username: ${{ secrets.EC2_ILSANG_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY_ILSANG }}
script: |
echo "Downloading latest JAR from S3..."
aws s3 cp s3://${{ secrets.S3_BUCKET_NAME }}/jars/apiProject.jar bin/apiProject.jar --region ap-northeast-2
if [ $? -ne 0 ]; then
echo "Failed to download JAR from S3."
exit 1
fi
run-dev:
runs-on: ubuntu-latest
needs: deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
steps:
- name: Execute deploy script on remote server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
if [ -f bin/deploy.sh ]; then
echo "deploy.sh found, executing script..."
bin/deploy.sh dev
else
echo "deploy.sh not found in bin directory"
exit 1
fi
run-prd:
runs-on: ubuntu-latest
needs: deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/prd'
steps:
- name: Execute deploy script on remote server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
if [ -f bin/deploy.sh ]; then
echo "deploy.sh found, executing script..."
bin/deploy.sh prd
else
echo "deploy.sh not found in bin directory"
exit 1
fi
각 단계별 설명
${{ secrets.AWS_ACCESS_KEY_ID }}
같은 구문은 앞서 설정한 깃허브 secret 변수를 사용 한다
1. Trigger
on:
push:
branches:
- dev
- prd
dev / prd 브랜치에 push 이벤트가 발생하면 시작된다.
2. AWS 설정 및 SSH 연결 테스트
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Configure AWS Credentials & Test SSH Connection
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
echo "Configuring AWS credentials..."
aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
aws configure set default.region ap-northeast-2
- name: Set up SSH Key from Secrets
run: |
echo "${{ secrets.EC2_SSH_KEY }}" > /tmp/id_rsa
chmod 600 /tmp/id_rsa
- name: Test SSH Connection
run: |
echo "Testing EC2 SSH connection..."
if ! ssh -i /tmp/id_rsa -o StrictHostKeyChecking=no ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }} "echo 'SSH connection successful.'"; then
echo "SSH connection failed. Stopping the workflow."
exit 1
fi
- name: Clean Up SSH Key
if: always()
run: |
rm -f /tmp/id_rsa
- name: Check S3 Health
run: |
echo "Performing S3 health check..."
if aws s3api head-bucket --bucket ${{ secrets.S3_BUCKET_NAME }} --region ap-northeast-2; then
echo "S3 connection successful."
else
echo "Failed to connect to S3."
exit 1
fi
s3 와 ec2 에 문제가 있을 시 워크플로우가 바로 종료 될 수 있게 한다.
- exit 1
AWS CLI 의 환경변수를 설정해준다.
aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
aws configure set default.region ap-northeast-2
3. SSH 비공개 키 등록 및 EC2 접속 시도
- name: Set up SSH Key from Secrets
run: |
echo "${{ secrets.EC2_SSH_KEY }}" > /tmp/id_rsa
chmod 600 /tmp/id_rsa
- name: Test SSH Connection
run: |
echo "Testing EC2 SSH connection..."
if ! ssh -i /tmp/id_rsa -o StrictHostKeyChecking=no ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }} "echo 'SSH connection successful.'"; then
echo "SSH connection failed. Stopping the workflow."
exit 1
fi
- name: Clean Up SSH Key
if: always()
run: |
rm -f /tmp/id_rsa
SSH 접속시 필요한 비공개 키를 파일로 생성해 주고 비공개 키로 접속을 시도 한다.
사용 후 키파일은 삭제 하도록 한다
4. S3 접속 테스트
- name: Check S3 Health
run: |
echo "Performing S3 health check..."
if aws s3api head-bucket --bucket ${{ secrets.S3_BUCKET_NAME }} --region ap-northeast-2; then
echo "S3 connection successful."
else
echo "Failed to connect to S3."
exit 1
fi
위에서 설정한 aws 자격증명을 가지고 버킷에 접속을 시도한다.
만약 다른 IAM 의 s3 에 접속 할 시 aws 설정을 다시 해주고 접속한다.
5. jdk 설치 && jar 빌드 && 백업 && 배포준비
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'
- name: Create AWS Info File
run: |
mkdir -p src/main/resources/aws
echo "${{ secrets.RDS_YAML }}" > src/main/resources/aws/rds-info.yml
echo "${{ secrets.S3_YAML }}" > src/main/resources/aws/s3-info.yml
- name: Test Code
run: ./gradlew test
- name: Build JAR File
run: |
chmod +x gradlew
./gradlew clean bootJar
mkdir -p build/libs
cp build/libs/*.jar apiProject.jar
- name: Upload JAR to S3
run: |
aws s3 cp apiProject.jar s3://${{ secrets.S3_BUCKETNAME }}/jars/apiProject.jar --region ap-northeast-2
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST_ILSANG }}
username: ${{ secrets.EC2_ILSANG_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY_ILSANG }}
script: |
echo "Downloading latest JAR from S3..."
aws s3 cp s3://${{ secrets.S3_BUCKETNAME }}/jars/apiProject.jar bin/apiProject.jar --region ap-northeast-2
if [ $? -ne 0 ]; then
echo "Failed to download JAR from S3."
exit 1
fi
위에서 접속 테스트를 완료 한 후
jdk 를 설치 하고, 설정파일을 만들고 테스트 후 jar파일로 빌드를 하여 완성 시킨다
- > s3 로 jar 파일을 백업 후 - > ec2 에 접속하여 s3에 올라가 있는 jar파일을 다운받는다.
6. 배포 스크립트 실행
run-dev:
runs-on: ubuntu-latest
needs: deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
steps:
- name: Execute deploy script on remote server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_ILSANG }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
if [ -f bin/deploy.sh ]; then
echo "deploy.sh found, executing script..."
bin/deploy.sh dev
else
echo "deploy.sh not found in bin directory"
exit 1
fi
run-prd:
runs-on: ubuntu-latest
needs: deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/prd'
steps:
- name: Execute deploy script on remote server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
if [ -f bin/deploy.sh ]; then
echo "deploy.sh found, executing script..."
bin/deploy.sh prd
else
echo "deploy.sh not found in bin directory"
exit 1
fi
dev 브랜치에 푸시가 발생됐다면 -> run-dev
prd 브랜치에 푸시가 발생됐다면 -> run-prd
각 스크립트가 실행되면 bin/deploy.sh 스크립트에 환경변수로 실행 시키게 된다.
bin/deploy.sh dev / bin/deploy.sh prd
'개-발 > Infra' 카테고리의 다른 글
[오류노트] Swagger 포트 바인딩 (with. Nginx) (0) | 2024.10.31 |
---|---|
[AWS] swap 메모리 설정하기 (0) | 2024.10.21 |
[CICD] github Actions + S3 + ec2 무중단 배포 for Spring (1) (0) | 2024.10.20 |
[ubuntu] 우분투 내 맘대로 설정들 (0) | 2024.10.17 |
[aws] S3 bucket 버킷 복제 하기 for macOS (0) | 2024.10.17 |
github Actions + S3 + ec2 무 배포 for Spring (1)
https://soobysu.tistory.com/184
[CICD] github Actions + S3 + ec2 무 배포 for Spring (1)
problem현재 하는 사이드 프로젝트에서는 프리티어를 사용하기 때문에 젠킨스를 사용하지 않고github Actions 를 사용하게 되었다.Jenkins젠킨스를 위한 서버가 필요 없다플러그인이 풍부하여 다양한
soobysu.tistory.com
작당한 이름의 파일을 만들어서
./github/workflows
디렉토리에 넣어두면 자동으로 실행된다.
전체 코드
name: CI/CD Pipeline
on:
pull_request:
branches:
- dev
- prd
- main
push:
branches:
- dev
- prd
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Configure AWS Credentials & Test SSH Connection
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
echo "Configuring AWS credentials..."
aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
aws configure set default.region ap-northeast-2
- name: Set up SSH Key from Secrets
run: |
echo "${{ secrets.EC2_SSH_KEY_ILSANG }}" > /tmp/id_rsa
chmod 600 /tmp/id_rsa
- name: Test SSH Connection
run: |
echo "Testing EC2 SSH connection..."
if ! ssh -i /tmp/id_rsa -o StrictHostKeyChecking=no ${{ secrets.EC2_ILSANG_USERNAME }}@${{ secrets.EC2_HOST_ILSANG }} "echo 'SSH connection successful.'"; then
echo "SSH connection failed. Stopping the workflow."
exit 1
fi
- name: Clean Up SSH Key
if: always()
run: |
rm -f /tmp/id_rsa
- name: Check S3 Health
run: |
echo "Performing S3 health check..."
if aws s3api head-bucket --bucket ${{ secrets.S3_BUCKET_NAME }} --region ap-northeast-2; then
echo "S3 connection successful."
else
echo "Failed to connect to S3."
exit 1
fi
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'
- name: Create AWS Info File
run: |
mkdir -p src/main/resources/aws
echo "${{ secrets.RDS_YAML }}" > src/main/resources/aws/rds-info.yml
echo "${{ secrets.S3_YAML }}" > src/main/resources/aws/s3-info.yml
- name: Test Code
run: ./gradlew test
- name: Build JAR File
run: |
chmod +x gradlew
./gradlew clean bootJar
mkdir -p build/libs
cp build/libs/*.jar apiProject.jar
- name: Upload JAR to S3
run: |
aws s3 cp apiProject.jar s3://${{ secrets.S3_BUCKET_NAME }}/jars/apiProject.jar --region ap-northeast-2
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST_ILSANG }}
username: ${{ secrets.EC2_ILSANG_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY_ILSANG }}
script: |
echo "Downloading latest JAR from S3..."
aws s3 cp s3://${{ secrets.S3_BUCKET_NAME }}/jars/apiProject.jar bin/apiProject.jar --region ap-northeast-2
if [ $? -ne 0 ]; then
echo "Failed to download JAR from S3."
exit 1
fi
run-dev:
runs-on: ubuntu-latest
needs: deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
steps:
- name: Execute deploy script on remote server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
if [ -f bin/deploy.sh ]; then
echo "deploy.sh found, executing script..."
bin/deploy.sh dev
else
echo "deploy.sh not found in bin directory"
exit 1
fi
run-prd:
runs-on: ubuntu-latest
needs: deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/prd'
steps:
- name: Execute deploy script on remote server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
if [ -f bin/deploy.sh ]; then
echo "deploy.sh found, executing script..."
bin/deploy.sh prd
else
echo "deploy.sh not found in bin directory"
exit 1
fi
각 단계별 설명
${{ secrets.AWS_ACCESS_KEY_ID }}
같은 구문은 앞서 설정한 깃허브 secret 변수를 사용 한다
1. Trigger
on:
push:
branches:
- dev
- prd
dev / prd 브랜치에 push 이벤트가 발생하면 시작된다.
2. AWS 설정 및 SSH 연결 테스트
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Configure AWS Credentials & Test SSH Connection
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
echo "Configuring AWS credentials..."
aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
aws configure set default.region ap-northeast-2
- name: Set up SSH Key from Secrets
run: |
echo "${{ secrets.EC2_SSH_KEY }}" > /tmp/id_rsa
chmod 600 /tmp/id_rsa
- name: Test SSH Connection
run: |
echo "Testing EC2 SSH connection..."
if ! ssh -i /tmp/id_rsa -o StrictHostKeyChecking=no ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }} "echo 'SSH connection successful.'"; then
echo "SSH connection failed. Stopping the workflow."
exit 1
fi
- name: Clean Up SSH Key
if: always()
run: |
rm -f /tmp/id_rsa
- name: Check S3 Health
run: |
echo "Performing S3 health check..."
if aws s3api head-bucket --bucket ${{ secrets.S3_BUCKET_NAME }} --region ap-northeast-2; then
echo "S3 connection successful."
else
echo "Failed to connect to S3."
exit 1
fi
s3 와 ec2 에 문제가 있을 시 워크플로우가 바로 종료 될 수 있게 한다.
- exit 1
AWS CLI 의 환경변수를 설정해준다.
aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
aws configure set default.region ap-northeast-2
3. SSH 비공개 키 등록 및 EC2 접속 시도
- name: Set up SSH Key from Secrets
run: |
echo "${{ secrets.EC2_SSH_KEY }}" > /tmp/id_rsa
chmod 600 /tmp/id_rsa
- name: Test SSH Connection
run: |
echo "Testing EC2 SSH connection..."
if ! ssh -i /tmp/id_rsa -o StrictHostKeyChecking=no ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }} "echo 'SSH connection successful.'"; then
echo "SSH connection failed. Stopping the workflow."
exit 1
fi
- name: Clean Up SSH Key
if: always()
run: |
rm -f /tmp/id_rsa
SSH 접속시 필요한 비공개 키를 파일로 생성해 주고 비공개 키로 접속을 시도 한다.
사용 후 키파일은 삭제 하도록 한다
4. S3 접속 테스트
- name: Check S3 Health
run: |
echo "Performing S3 health check..."
if aws s3api head-bucket --bucket ${{ secrets.S3_BUCKET_NAME }} --region ap-northeast-2; then
echo "S3 connection successful."
else
echo "Failed to connect to S3."
exit 1
fi
위에서 설정한 aws 자격증명을 가지고 버킷에 접속을 시도한다.
만약 다른 IAM 의 s3 에 접속 할 시 aws 설정을 다시 해주고 접속한다.
5. jdk 설치 && jar 빌드 && 백업 && 배포준비
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'
- name: Create AWS Info File
run: |
mkdir -p src/main/resources/aws
echo "${{ secrets.RDS_YAML }}" > src/main/resources/aws/rds-info.yml
echo "${{ secrets.S3_YAML }}" > src/main/resources/aws/s3-info.yml
- name: Test Code
run: ./gradlew test
- name: Build JAR File
run: |
chmod +x gradlew
./gradlew clean bootJar
mkdir -p build/libs
cp build/libs/*.jar apiProject.jar
- name: Upload JAR to S3
run: |
aws s3 cp apiProject.jar s3://${{ secrets.S3_BUCKETNAME }}/jars/apiProject.jar --region ap-northeast-2
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST_ILSANG }}
username: ${{ secrets.EC2_ILSANG_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY_ILSANG }}
script: |
echo "Downloading latest JAR from S3..."
aws s3 cp s3://${{ secrets.S3_BUCKETNAME }}/jars/apiProject.jar bin/apiProject.jar --region ap-northeast-2
if [ $? -ne 0 ]; then
echo "Failed to download JAR from S3."
exit 1
fi
위에서 접속 테스트를 완료 한 후
jdk 를 설치 하고, 설정파일을 만들고 테스트 후 jar파일로 빌드를 하여 완성 시킨다
- > s3 로 jar 파일을 백업 후 - > ec2 에 접속하여 s3에 올라가 있는 jar파일을 다운받는다.
6. 배포 스크립트 실행
run-dev:
runs-on: ubuntu-latest
needs: deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
steps:
- name: Execute deploy script on remote server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_ILSANG }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
if [ -f bin/deploy.sh ]; then
echo "deploy.sh found, executing script..."
bin/deploy.sh dev
else
echo "deploy.sh not found in bin directory"
exit 1
fi
run-prd:
runs-on: ubuntu-latest
needs: deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/prd'
steps:
- name: Execute deploy script on remote server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
if [ -f bin/deploy.sh ]; then
echo "deploy.sh found, executing script..."
bin/deploy.sh prd
else
echo "deploy.sh not found in bin directory"
exit 1
fi
dev 브랜치에 푸시가 발생됐다면 -> run-dev
prd 브랜치에 푸시가 발생됐다면 -> run-prd
각 스크립트가 실행되면 bin/deploy.sh 스크립트에 환경변수로 실행 시키게 된다.
bin/deploy.sh dev / bin/deploy.sh prd
'개-발 > Infra' 카테고리의 다른 글
[오류노트] Swagger 포트 바인딩 (with. Nginx) (0) | 2024.10.31 |
---|---|
[AWS] swap 메모리 설정하기 (0) | 2024.10.21 |
[CICD] github Actions + S3 + ec2 무중단 배포 for Spring (1) (0) | 2024.10.20 |
[ubuntu] 우분투 내 맘대로 설정들 (0) | 2024.10.17 |
[aws] S3 bucket 버킷 복제 하기 for macOS (0) | 2024.10.17 |