๊ฐ๋ฐ ํ๊ฒฝ
๐ป OS : M1 Mac Ventura 13.1
๐ Spring : Spring Boot 2.7.7
๐ ๏ธ Java : Amazon corretto 17
๐ฆ Stack : AWS : S3, CodeDeploy, EC2(Amazon Linux), RDS
ํด๋น ๊ธ์ ๊ฐ๋ฐ ๊ณผ์ ์ ๊ธฐ๋กํ๊ธฐ ์ํ ๊ธ์ ๋๋ค.
ํ์ํ ๋ถ๋ถ์ ๋ณธ์ธ์ ๊ฐ๋ฐ ํ๊ฒฝ ๋ฐ ์ํฉ์ ๋ง๊ฒ ๋ฐ๊ฟ์ ์์ฑํด์ผ ํฉ๋๋ค.
CI/CD Flow
1๏ธโฃ : ๋ฐฐํฌ ๋ธ๋์น์ Push ๋ ๋, Github Actions ์คํ
2๏ธโฃ : Actions๋ฅผ ํตํด ๋น๋ํ ํ AWS IAM ์ธ์ฆ์ ๊ฑฐ์น ๋ค, ์ ์ฒด ํ์ผ์ .zip ํ์ผ๋ก ๋ฌถ์ด S3์ ์ ๋ก๋
3๏ธโฃ : S3์ ์ฌ๋ผ๊ฐ ํ์ผ๋ช ์ ํ ๋๋ก CodeDeploy์ ๋ฐฐํฌ ์์ฒญ
4๏ธโฃ : ๋ฐฐํฌ ์์ฒญ์ ๋ฐ์ผ๋ฉด S3์์ ํ์ผ์ ๋ฐ์์ EC2์ ๋ฐฐํฌ
5๏ธโฃ : deploy.sh๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์คํ
CI ํ๊ฒฝ ๊ตฌ์ถ
์ค๋ช ํ๊ธฐ ์์ application*.yml(properties) ํ์ผ๋ค์ ๋ชจ๋ .gitignore์ ๋ฑ๋ก๋ ์ํ์ ๋๋ค.
๋ํ ํ๋์ actions.yml ํ์ผ์ ๊ฐ์ง๊ณ ์ํฉ์ ๋ง๊ฒ ์ง์์ ์ผ๋ก ๋ด์ฉ์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์ค๋ช ํ ์์ ์ด๋ฉฐ, ์ต์ข ๋ณธ์ ๊ฐ์ฅ ๋ง์ง๋ง์ ์ถ๊ฐํด๋๋๋ก ํ๊ฒ ์ต๋๋ค!
Properties ํ์ผ ๋ฑ๋ก
์์์ ์ค๋ช
ํ ๊ฒ๊ณผ ๊ฐ์ด ์ค์ ํ์ผ๋ค์ .gitignore
์ ๋ฑ๋ก๋์ด ์์ด master
๋ธ๋์น์ ์ฌ๋ผ๊ฐ์์ง ์์ ์ํ๋ค.
๋๋ฌธ์ build๋ฅผ ํ๋ ๊ณผ์ ์์ ์๋ฌ๊ฐ ๋ ์ ์๊ณ , ์ต์ข
์ ์ผ๋ก ๋ฐฐํฌ ๋์์ ๋ ์คํ์กฐ์ฐจ ํ ์ ์๊ธฐ ๋๋ฌธ์,
์ค์ ํ์ผ์ Actions Secret์ ์ถ๊ฐํด์ค๋ค.
์ ์ฌ์ง๊ณผ ๊ฐ์ด ํด๋ฆญํ๋ฉด ์๋ก์ด secret์ ๋ฑ๋กํ ์ ์๋ค.
Name : CI/CD๋ฅผ ์ํด ์ฌ์ฉํ actions.yml
์์ ์ฌ์ฉํ ์ด๋ฆ(๋๋ฌธ์ ์ฌ์ฉ)
Secret : Name์ ๋ํ ์์ธ ๋ด์ฉ ์์ฑ

ํ์๋ application.yml
์ ๊ตฌ๋์ ํ์ํ ํ์ ํญ๋ชฉ์ ์์ฑํ๊ณ ,application-prod.yml
์๋ ๋ฐฐํฌ ํ๊ฒฝ์ ํ์ํ RDS ์ ๋ณด์ ๊ฐ์ ๊ฒ์ ์์ฑํด๋์ ์ํ๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ๊ตฌ๋ถํ๋ค.(+ ์ถํ ๊ฐ๋ฐ ์๋ฒ๋ ๋์ฐ๊ธฐ ์ํจ)
# Actions Secrets
PROPERTIES_MAIN_PROD : appication.yml
PROPERTIES_PROD : application-prod.yml
GitHub Actions
๋ฐฐํฌ๋ฅผ ํ๊ณ ์ํ๋ Github Repository์ Actions์ ๋ค์ด๊ฐ actions.yml
์ ์์ฑํด์ค๋ค.
# Actions์์ ๋ณด์ฌ์ง workflow ์ด๋ฆ
name: CI/CD
# ํธ๋ฆฌ๊ฑฐ ์ง์
# master ๋ธ๋์น์ push๊ฐ ์ผ์ด๋ ๋ ์คํ
on:
push:
branches:
- master
jobs:
CI-CD:
runs-on: ubuntu-latest
steps:
## Setting JDK
## ๋ณธ์ธ spring ๋ฒ์ ์ ๋ง๋ ๋ฒ์ ์ง์
## https://github.com/actions/setup-java
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
## Gradle Caching
- name: Gradle Caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
## Create application.yml
- name: make prod application.yml
if: contains(github.ref, 'master')
run: |
cd ./src/main/resources
touch ./application.yml
echo "${{ secrets.PROPERTIES_MAIN_PROD }}" > ./application.yml
shell: bash
## Create application-prod.yml
- name: make prod application-prod.yml
if: contains(github.ref, 'master')
run: |
cd ./src/main/resources
touch ./application-prod.yml
echo "${{ secrets.PROPERTIES_PROD }}" > ./application-prod.yml
shell: bash
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
shell: bash
## Gradle Build
- name: Build with Gradle
run: ./gradlew build
์์ฑ์ ๋ค ์์ฑํ ๋ค์ Start Commit์ ํตํด master
๋ธ๋์น์ ๋ฐ๋ก push ํด์ค๋ค.
์ด ๊ณผ์ ์์ ์๊ธฐ๋ ์ค๋ฅ๋ค์ ๋ฏธ๋ฆฌ ํด๊ฒฐํด ๋๋๊ฒ ๋ง ํธํ๋ค!
๋ณ๊ฒฝํ ์ฌํญ ์ ๋ฆฌ
- Setting JDK
- ๋ณธ์ธ Spring ๋ฒ์ ์ ๋ง๋๋ก ์ง์
- Create *.yml
- properties ํ์ผ์ ์ธ๋ถ์ ๊ณต๊ฐํ๋ฉด ์ ๋๋ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ค.
- ๋๋ฌธ์ Setting - Secretes - Actions์์ ์ถ๊ฐํด์ค๋ค.
- ํ์์ ๋ฐ๋ผ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ง์์ฃผ๊ณ , yml์ด ์๋๋ฉด properties๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค.
์ค๋ฅ ์ ๋ฆฌ
Build With Gradle
Run ./gradlew build
./gradlew build
shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
env:
JAVA_HOME: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/11.0.18-10/x64
JAVA_HOME_11_X64: /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/11.0.18-10/x64
Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain
Caused by: java.lang.ClassNotFoundException: org.gradle.wrapper.GradleWrapperMain
- Project ์๋ฐ ๋ฒ์ ๊ณผ ๋์ผํ๊ฒ ์ค์ ํ๋์ง ํ์ธ
/home/runner/work/.../src/main/java/com/.../app/config/security/CustomAuthenticationFailureHandler 2.java:
13: error: class CustomAuthenticationFailureHandler is public, should be declared in a file named CustomAuthenticationFailureHandler.java
- ํ๋ก์ ํธ์
ClassName 2.java
๊ณผ ๊ฐ์ด ๋ค๋ฅธ ํด๋์ค ํ์ผ๊ณผ ์ค๋ณต๋๋ ํ์ผ์ด ์๋์ง ํ์ธ
* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at:
- ์คํจํ ํ ์คํธ๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ ์์ ๊ฐ์ด ๋ฐ ์ ์์
- ํน์ ํน์
Test
์์ ์ฌ์ฉ๋๋ ํน์ ํ์ผ,Properties
๋ฅผ ๋ถ๋ฌ์ฌ ์ ์์ ๊ฒฝ์ฐ ๋ฐ์ ๊ฐ๋ฅ
AWS
IAM
AWS๋ ์๋น์ค์ ๋ณด์์ ์ํด ์ธ๋ถ ์ ๊ทผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฐจ๋จํ๋ค. ๋๋ฌธ์ IAM(Identify & Access Management)์ ์ด์ฉํด์ ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๋ ๋ฃจํธ๋ฅผ ๋ง๋ค์ด์ค๋ค.
์๋จ ๊ฒ์์ฐฝ์ ํตํด IAM
์ ๋ค์ด๊ฐ ์ฌ์ฉ์ ํญ์ ์ฌ์ฉ์ ์ถ๊ฐ๋ฅผ ๋๋ฌ์ค๋ค.
AWSCodeDeployFullAccess
, AmazonS3FullAccess
2๊ฐ์ง ์ ์ฑ
์ ์ฐ๊ฒฐํด์ค๋ค.
๋ค๋ฅธ ๊ฒ์ ๊ฑด๋ค์ด์ง ์๊ณ ๋ค์์ ๋๋ฅธ ๋ค, ์ฌ์ฉ์๋ฅผ ์์ฑํด์ค๋ค.
์ด IAM์ ๊ฐ์ง๊ณ GitHub์์ ์ฆ๋ช
์ ํด์ค์ผํ๊ธฐ ๋๋ฌธ์ Access Key
๋ฅผ ๋ฐ๊ธ ๋ฐ์์ผ ํ๋ค.
์ค๋ช ์ ์ ํ์ด๊ธฐ ๋๋ฌธ์ ๊ฑด๋ค์ด์ง ์๊ณ ์งํ
Access Key
, Secret Key
๋ ๋ฐ๋ก ๋ฉ๋ชจ๋ฅผ ํด๋๊ณ , .csv
ํ์ผ์ ๋ค์ด์ ๋ฐ์๋์!
Secret ๋ฑ๋ก
๊น๋จน๊ธฐ ์ ์ ์์์ ๋ฐ๊ธ ๋ฐ์ ํค๋ฅผ GitHub Secrets์ ๋ฑ๋กํ์!

# Actions Secrets
AWS_IAM_ACCESS_KEY : ์ก์ธ์ค ํค
AWS_IAM_SECRET_KEY : ๋น๋ฐ ์ก์ธ์ค ํค
์ญํ ์ถ๊ฐ
IAM์ ๊ฐ์ง๊ณ S3, CodeDeploy, EC2์ ์ ๊ทผ์ ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ ์๋น์ค์ ๋ํด ์ญํ ์ ์ถ๊ฐํด์ค๋ค.
EC2 Role
EC2์์๋ S3์ ์๋ ํ์ผ์ ๋ฐ์์์ผํ๊ธฐ ๋๋ฌธ์ ์๋์ ๊ฐ์ด ๋ฑ๋กํด์ค๋ค.
AmazonEC2RoleforAWSCodeDeploy
๊ฒ์ ํ ์ฒดํฌ
์ด ์ธ ๋ด์ฉ์ ๋ชจ๋ ๊ทธ๋๋ก ๋๊ณ ์ญํ ์ ๋ง๋ ๋ค.
CodeDeploy Role
CodeDeploy์์๋ S3์ ์๋ ๊ฒ์ EC2์ ๋ณด๋ธ ๋ค, ๋ฐฐํฌ๋ฅผ ์คํํ๋๋ก ํด์ผํ๊ธฐ ๋๋ฌธ์ ์๋์ ๊ฐ์ด ๋ฑ๋กํด์ค๋ค.
CodeDeploy์ ์ ์ฑ ์ 1๊ฐ์ง๋ง ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๊ทธ๋๋ก ๋ค์์ ๋๋ฌ์ค๋ค.
๋์ผํ๊ฒ ์ด๋ฆ์ ์ ์ง์ด์ฃผ๊ณ ์ญํ ์ ๋ง๋ ๋ค.
S3
CI ๊ณผ์ ์ ํตํด ๋น๋๋ ํ์ผ๋ค์ ์ ์ฅํ S3 Bucket์ ์์ฑํด์ค๋ค.
S3 Bucket ์์ฑ
์ด ์ธ์ ์ค์ ์ ๊ฑด๋ค์ด์ง ์๊ณ ๋ฒํท ๋ง๋ค๊ธฐ๋ฅผ ๋๋ฌ์ฃผ๋ฉด ๋!
EC2
๋ค์์ ์ค์ ํ CodeDeploy์์ ํ์ผ์ ๋ฐ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๊ธฐ ์ํ ์ญํ
EC2 ์ธ์คํด์ค ์์ฑ
์ ํคํ์ด๋ฅผ ์์ฑํ๋ฉด, ec2-keypair.pem ํ์ผ์ ๋ค์ด๋ฐ๊ฒ ๋๋ค. ๋ค์ด๋ก๋ํ ํ์ผ์ ๋ฐํํ๋ฉด์ aws ํด๋๋ฅผ ๋ง๋ค์ด ๋ณด๊ดํด๋์!
ํด๋ ์ด๋ฆ์ด๋ ๊ฒฝ๋ก๋ ๋ณธ์ธ์ด ์ํ๋ ๊ณณ์ผ๋ก ๋ฐ๊ฟ๋ ๋๋ค! ๋จ, ec2-keypair.pem
ํ์ผ์ ๋ํ ์ด๋ฆ ์์ ์ ํ๋ฉด ์ ๋๋ค.
๊ธฐ์กด ์์น ๋ฌด๊ด์์ ๋ด IP๋ก ๋ณ๊ฒฝ!
ํ๋ฆฌํฐ์ด ๊ธฐ์ค 30๊ธฐ๊ฐ๊น์ง ์ง์ํ๊ธฐ ๋๋ฌธ์ 30๊ธฐ๊ฐ๋ฅผ ์ฌ์ฉํ๊ณ , ๋ค๋ฅธ ์ต์
์ ์๋ฌด๊ฒ๋ ๊ฑด๋ค์ง ๋ง์
gp2 ๊ฐ์ ๊ฒฝ์ฐ ๋ฒ์ฉ์ด ์๋ ๊ฒ์ ์ฌ์ฉํ ๊ฒฝ์ฐ ๊ณผ๊ธ์ด ๋ฐ์ํ ์ ์์!
๋ค๋ฅธ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ์ธ์คํด์ค ์์์ ๋๋ฌ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ํด์ฃผ์
IAM ์ญํ ๋ถ์ฌ
์๋ก ๋ง๋ ์ธ์คํด์ค๋ฅผ ์ฐํด๋ฆญํ์ฌ ๋ณด์ - IAM ์ญํ ์์ ์ ํด๋ฆญํด์ค๋ค.
์์ ๋ง๋ค์๋ EC2์ IAM ์ญํ ์ ์ ์ฉํด์ค๋ค.
์ญํ ์ ์ฌ์ ์ฉํ๊ธฐ ์ํด ์ธ์คํด์ค๋ฅผ ์ฌ๋ถํ
ํด์ค๋ค. ์ฌ๋ถํ
๊ณผ์ ์ 1 ~ 3๋ถ ์ ๋ ์์๋๋ ๋ค์ ๊ณผ์ ์ ์ฒ์ฒํ ์งํํ์!
ํ๋ ฅ์ IP ์ ์ฉ
์ธ์คํด์ค๊ฐ ์ฌ๋ถํ ๋ ๋๋ง๋ค ํผ๋ธ๋ฆญ ์ฃผ์๋ ๊ณ์ํด์ ๋ณ๊ฒฝ๋๊ธฐ ๋๋ฌธ์ ํ๋ ฅ์ IP ์ฃผ์๋ฅผ ํตํด ๊ณ ์ ํผ๋ธ๋ฆญ IP๋ฅผ ์์ฑํด์ค๋ค.
์๋ฌด๊ฒ๋ ๊ฑด๋ค์ด์ง ์๊ณ ํ ๋น์ ํด๋ฆญํด ๋ถ์ฌํด์ค๋ค!
์์ ๋ง๋ ์ธ์คํด์ค๋ฅผ ์ ํํด์ฃผ๊ณ , ํด๋น ์ธ์คํด์ค์ ๋ํ ํ๋ผ์ด๋น IP๋ฅผ ์ ํํ ๋ค, ์ฐ๊ฒฐ ๋ฒํผ์ ๋๋ฌ์ค๋ค.
ssh ์ ์
์ด์ ์ ์์ ์ผ๋ก ์ ๊ทผ์ด ๊ฐ๋ฅํด์ก๋์ง ํ์ธํด๋ณด์!
์ธ์คํด์ค ์์ธ ํ์ด์ง์์ ์ฐ์ธก ์๋จ์ ์๋ ์ฐ๊ฒฐ ๋ฒํผ์ ํด๋ฆญํ๊ณ , SSH ํด๋ผ์ด์ธํธ ํ ์ ๊ฐ์ฅ ์๋ ์์ ssh ์ฐ๊ฒฐ ์ฃผ์๋ฅผ ๋ณต์ฌํด ํฐ๋ฏธ๋์ ์ ๋ ฅํด์ฃผ์!
ํด๋น ๊ณผ์ ์ .pem์ด ์๋ ๋๋ ํฐ๋ฆฌ์์ ์งํํด์ผ ํฉ๋๋ค.
CodeDeploy ์ค์น
S3์ ์ฌ๋ผ๊ฐ ํ์ผ์ CodeDeploy๋ฅผ ํตํด EC2์ ์ ๋ฌํด ๋ฐฐํฌ๋ฅผ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ssh์ ์ฐ๊ฒฐ๋ ์ํ์์ ์ค์น๋ฅผ ํด์ค๋ค.
# CodeDeploy ์ค์น
aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2
# ์ค์น ํ์ผ์ ๊ถํ ๋ถ์ฌ
chmod +x ./install
# ๋ค์ด ๋ฐ์ ํ์ผ์ ์ค์นํ๊ธฐ ์ํด ruby ์ค์น
sudo yum install ruby;
# CodeDeploy ์ค์น
sudo ./install auto
# ์๋น์ค ์ํ ํ์ธ
sudo service codedeploy-agent status
CodeDeploy
S3
์ ์ฌ๋ผ์จ .zip
ํ์ผ์ EC2์ ๋ฐฐํฌํ๋ ์ญํ
์ ํ๋ฆฌ์ผ์ด์ ์์ฑ
์ ํ๋ฆฌ์ผ์ด์
์ด๋ฆ์ ๋์ค์ actions.yml
์ ๋ค์ด๊ฐ๋ ๋ค๋ฅธ ์ด๋ฆ๊ณผ ํท๊ฐ๋ฆฌ์ง ์๊ฒ ์ง์ด์ค๋ค!
๋ฐฐํฌ ๊ทธ๋ฃน ์์ฑ
๋ฐฐํฌ ๊ทธ๋ฃน ์ด๋ฆ์ ๋ง์๋๋ก ์ง์ด์ฃผ๊ณ , ์๋น์ค ์ญํ ์ IAM์์ ๋ง๋ค์ด๋จ๋ codedeploy-role
์ ์ ์ฉํด์ค๋ค.
์ ๊ณผ์ ์์ ๋ง๋ EC2 ์ธ์คํด์ค๋ฅผ ์ฐ๊ฒฐํด์ค๋ค.
๋ง์ง๋ง์ผ๋ก CodeDeployDefault.AllAtOnce
๋ก ์ค์ ๋์ด์๋์ง ํ์ธํ๊ณ , ๋ก๋ ๋ฐธ๋ฐ์๋ ๋นํ์ฑํ ํด์ค๋ค.
RDS
์์ง ๋ฒ์ ์ ํ์ฌ Spring Boot์์ ์ฌ์ฉ ์ค์ธ ์์ง ๋ฒ์ ๊ณผ ๋์ผํ๊ฒ ๋ง์ถฐ์ผ ํ๋ค!
DB ์ธ์คํด์ค ์๋ณ์๋ host์ ๊ด๋ จ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ ๋นํ ์ ์ง์ด์ฃผ๊ณ , ๋ง์คํฐ ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ๋น๋ฐ๋ฒํธ๋ฅผ ์ง์ ์ง์ ํด์ค๋ค.
์คํ ๋ฆฌ์ง ์๋ ์กฐ์ ์ ํ์ฑํํ๋ฉด ๊ณผ๊ธ์ด ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋นํ์ฑํ ํด์ค๋ค!
EC2์์ ๋ค์ด๊ฐ๋ ์์ฒญ๋ง ํ์ฉํ๊ธฐ ์ํด EC2 ์ปดํจํ ๋ฆฌ์์ค์ ์ฐ๊ฒฐ์ ์ ํํด์ฃผ๊ณ , ์์ ์์ฑํ EC2 ์ธ์คํด์ค๋ฅผ ์ ํํด์ค๋ค. VPC๋ Default๋ก ๋๋ฉด ๋๋ค!
ํผ๋ธ๋ฆญ ์์ธ์ค ๊ฐ๋ฅ์ผ๋ก ๋ณ๊ฒฝ! ๋ง์ฝ ๊ฐ๋ฅ์ผ๋ก ๋ณ๊ฒฝ์ด ์ ๋๋ค๋ฉด, ๋ถ๊ฐ๋ฅ์ผ๋ก ์งํํ ๋ค, RDS ์์ฑ ํ ์งํํ VPC ์ค์ ์ ๋ง์น๊ณ ๋ค์ ์์ ์ ํตํด ๋ณ๊ฒฝํ๋ฉด ๋๋ค!
๋์ค์ ๋ก์ปฌ์์ ์ ์์ด ๊ฐ๋ฅํ๋๋ก ๊ท์น์ ๋ฃ์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์๋ก์ด vpc ๋ณด์ ๊ทธ๋ฃน์ ์์ฑํด์ค๋ค.
์๋ ๋ฐฑ์ ์ ๋นํ์ฑํ ์์ผ์ฃผ๊ณ , ์ด๊ธฐ DB๋ฅผ ์์ฑํ๋ ค๋ฉด ์ด๋ฆ์ ์์ฑํด์ฃผ๊ณ , ํ์์๋ค๋ฉด ๋น ์นธ์ผ๋ก ๋ ๋์!
๋ฒ์ ์ด ์๋์ผ๋ก ์ฌ๋ผ๊ฐ๋ฉด, Spring Boot์์๋ ๋ณ๊ฒฝ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ๊ณ ์ ๋ฒ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ํด ๋นํ์ฑํ ํด์ฃผ์!
์ด ์ํ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฑํ๋ฉด ๋!
๊ท์น ์ ์
์์ฑ๋ DB์ ๋ค์ด๊ฐ์ ์ฐ๊ฒฐ & ๋ณด์ ํญ ์๋์ ๋ณด์๊ทธ๋ฃน ๊ท์น์์ ์ ํ์ด CIDR/IP - Inbound์ธ ๊ฒ์ ํด๋ฆญํด์ ๋ค์ด๊ฐ์!
๊ธฐ์กด์ ๋ฑ๋ก๋์ด ์๋ MYSQL/Aurora
๋ฅผ ๋ชจ๋ ํธ๋ํฝ์ผ๋ก ๋ณ๊ฒฝ ํ ๊ท์น ์ ์ฅ!
VPC ์ธํ
์๋จ ๊ฒ์์ฐฝ์ VPC๋ฅผ ๊ฒ์ํ ๋ค, ๋ผ์ฐํ ํ ์ด๋ธ ํญ์ ๋ค์ด๊ฐ๋ณด์. ๋ณดํต RDS-Pvt-rt๋ก ๋ ํ ์ด๋ธ์ด 1๊ฐ๋ง ์กด์ฌํ ๊ฒ์ด๋ค. (ํ์๋ RDS 2๊ฐ๋ฅผ ๋์๋์ 2๊ฐ์)
ํด๋น ํ ์ด๋ธ ID๋ฅผ ํด๋ฆญํด ์์ธ ํ์ด์ง๋ก ๋ค์ด๊ฐ ๋ค์ ๋ผ์ฐํ ํธ์ง์ ๋๋ฌ์ฃผ์
local์ ๊ทธ๋๋ก ๋ ๋๊ณ , ๋ผ์ฐํ ์ถ๊ฐ๋ฅผ ๋๋ฌ ์ฌ์ง๊ณผ ๊ฐ์ด ๋ง์ถฐ์ฃผ๋ฉด igw-012345678 ์ด๋ฐ ์ฝ๋๊ฐ ์์ฑ๋ ๊ฒ์ด๋ค. ์ด ์ํ๋ก ๋ณ๊ฒฝ์ฌํญ ์ ์ฅ!
DB ์ฐ๋
๋ค์ RDS๋ก ๋์์์ ์๋ํฌ์ธํธ๋ฅผ ๋ณต์ฌํด์ DB ์ฐ๊ฒฐ์ ํด๋ณด์!
์๋ํฌ์ธํธ์ ์ฃผ์๋ฅผ Host์ ๋ฃ์ด์ฃผ๊ณ , ๊ธฐ์กด์ ์ค์ ํ User์ Passowrd๋ฅผ ๋ง๊ฒ ์ ๋ ฅํด์ฃผ์!
CD ํ๊ฒฝ ๊ตฌ์ถ
์์ CI ๊ณผ์ ์ actions.yml์ ๋ฑ๋ก๋์ด ์์ผ๋ ๊ตฌ์ถํ ๋ด์ฉ์ ํ ๋๋ก CD ๊ณผ์ ์ ์ถ๊ฐํ์!
GitHub Actions
# Actions์์ ๋ณด์ฌ์ง workflow ์ด๋ฆ
name: CI/CD
# ํธ๋ฆฌ๊ฑฐ ์ง์
# master ๋ธ๋์น์ push๊ฐ ์ผ์ด๋ ๋ ์คํ
on:
push:
branches:
- master
# env
env:
S3_BUCKET_NAME: deploy-bucket
PROJECT_NAME: project
jobs:
CI-CD:
runs-on: ubuntu-latest
steps:
## Setting JDK
## ๋ณธ์ธ spring ๋ฒ์ ์ ๋ง๋ ๋ฒ์ ์ง์
## https://github.com/actions/setup-java
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
## Gradle Caching
- name: Gradle Caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
## Create application.yml
- name: make prod application.yml
if: contains(github.ref, 'master')
run: |
cd ./src/main/resources
touch ./application.yml
echo "${{ secrets.PROPERTIES_MAIN_PROD }}" > ./application.yml
shell: bash
## Create application-prod.yml
- name: make prod application-prod.yml
if: contains(github.ref, 'master')
run: |
cd ./src/main/resources
touch ./application-prod.yml
echo "${{ secrets.PROPERTIES_PROD }}" > ./application-prod.yml
shell: bash
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
shell: bash
## Gradle Build
- name: Build with Gradle
run: ./gradlew build
- name: Make zip file
run: zip -r ./$GITHUB_SHA.zip .
shell: bash
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_IAM_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_IAM_SECRET_KEY }}
aws-region: ap-northeast-2
# script files ๋ณต์ฌ
- name: Copy script
run: cp ./scripts/*.sh ./deploy
# S3์ ์
๋ก๋
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
# Deploy
- name: Deploy
run: |
aws deploy create-deployment \
--application-name deploy-dev-app \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--deployment-group-name deploy-dev \
--file-exists-behavior OVERWRITE \
--s3-location bucket=deploy-bucket,bundleType=zip,key=project/$GITHUB_SHA.zip \
--region ap-northeast-2 \
๋ณ๊ฒฝํ ์ฌํญ ์ ๋ฆฌ
- env
- S3_BUCKET_NAME : S3 ๋ฒํท ์ด๋ฆ
- PROJECT_NAME : S3 ๋ฒํท ๋ด๋ถ์ ๋น๋๋ ํ์ผ์ ์ ์ฅํ ํด๋(ํ๋ก์ ํธ) ์ด๋ฆ
- Deploy
- application-name : CodeDeploy์ application ์ด๋ฆ
- deployment-group-name : ํด๋น application์ ๋ฐฐํฌ ๊ทธ๋ฃน ์ด๋ฆ
- s3-location
- bucket : S3 ๋ฒํท ์ด๋ฆ
- key : env์ ์๋ PROJECT_NAME์ value์ ๋์ผํ๊ฒ ์์ฑ
deploy.sh ์์ฑ
CodeDeploy๋ฅผ ํตํด S3์์ EC2๋ก ๋ณด๋ด๋ ๊ณผ์ ์์ ๋ฐฐํฌ๋ฅผ ์์ฒญํด์ผํ๊ธฐ ๋๋ฌธ์ ์์ฑํด์ค๋ค.
SpringBoot ํ๋ก์ ํธ ์ต์์์ scripts ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ง๋ ๋ค, ์๋ ๋ด์ฉ์ ์ฃผ์์ ์ง์ฐ๊ณ ์์ฑ

#!/bin/bash
BUILD_JAR=$(ls /home/ec2-user/action/build/libs/*.jar)
JAR_NAME=$(basename $BUILD_JAR)
echo "> build ํ์ผ๋ช
: $JAR_NAME" >> /home/ec2-user/action/deploy.log
echo "> build ํ์ผ ๋ณต์ฌ" >> /home/ec2-user/action/deploy.log
DEPLOY_PATH=/home/ec2-user/action/
cp $BUILD_JAR $DEPLOY_PATH
echo "> ํ์ฌ ์คํ์ค์ธ ์ ํ๋ฆฌ์ผ์ด์
pid ํ์ธ" >> /home/ec2-user/action/deploy.log
CURRENT_PID=$(pgrep -f $JAR_NAME)
if [ -z $CURRENT_PID ]
then
echo "> ํ์ฌ ๊ตฌ๋์ค์ธ ์ ํ๋ฆฌ์ผ์ด์
์ด ์์ผ๋ฏ๋ก ์ข
๋ฃํ์ง ์์ต๋๋ค." >> /home/ec2-user/action/deploy.log
else
echo "> kill -15 $CURRENT_PID"
kill -15 $CURRENT_PID
sleep 5
fi
DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> DEPLOY_JAR ๋ฐฐํฌ" >> /home/ec2-user/action/deploy.log
nohup java -jar $DEPLOY_JAR >> /home/ec2-user/deploy.log 2>/home/ec2-user/action/deploy_err.log &
appspec.yml ์์ฑ

ํด๋น ํ์ผ์ ํ๋ก์ ํธ ๊ตฌ์กฐ ์ต์์์ ๋ฐ๋ก ๋ง๋ค์ด ์ค๋ค.
์ต์ข ์ ์ผ๋ก CodeDeploy๊ฐ EC2 ํ๊ฒฝ์ S3์์ ๊ฐ์ ธ์จ jar ํ์ผ์ ๋ฐฐํฌํ ์ ์๋๋ก ๋ง๋ค์ด์ฃผ๋ ํ์ผ
version: 0.0
os: linux
# S3์ ์๋ zip ํ์ผ์ด EC2์ ๋ฐฐํฌ๋ ์์น๋ฅผ ์ง์
files:
# CodeDeploy์์ ์ ๋ฌํด ์ค ํ์ผ ์ค destination์ผ๋ก ์ด๋์ํฌ ๋์์ ๋ฃจํธ๋ก ์ง์ (์ ์ฒดํ์ผ)
- source: /
# source์์ ์ง์ ๋ ํ์ผ์ ๋ฐ์ ์์น, ์ดํ jar๋ฅผ ์คํํ๋ ๋ฑ์ destination์์ ์ฎ๊ธด ํ์ผ๋ค๋ก ์งํ
destination: /home/ec2-user/action/
overwrite: yes
# CodeDeploy์์ EC2์๋ฒ๋ก ๋๊ฒจ์ค ํ์ผ๋ค์ ๋ชจ๋ ec2-user๊ถํ์ ๊ฐ๋๋ก ํฉ๋๋ค.
permissions:
- object: /
pattern: "**"
owner: ec2-user
group: ec2-user
# ApplicationStart ๋จ๊ณ์์ deploy.sh๋ฅผ ์คํ์ํค๋๋ก ํฉ๋๋ค.
# CodeDeploy๋ฐฐํฌ ๋จ๊ณ์์ ์คํํ ๋ช
๋ น์ด๋ฅผ ์ง์ ํฉ๋๋ค.
hooks:
# deploy.sh๋ฅผ ec2-user๊ถํ์ผ๋ก ์คํํฉ๋๋ค.
ApplicationStart:
- location: scripts/deploy.sh
# ์คํฌ๋ฆฝํธ ์คํ 60์ด ์ด์ ์ํ๋๋ฉด ์คํจ๊ฐ ๋ฉ๋๋ค.
timeout: 60
runas: ec2-user
๋ ํผ๋ฐ์ค
์ฃผํ๋ ๋ธ๋ก๊ทธ - ๊ฐ๋น์ + Amazon Linux + Nginx + Cerbot/SSL์ ํ์ฉํ https ์ค์
Github Actions Variable
๋ฑ๊ทค๋ ๋ธ๋ก๊ทธ
๊น์ฌ์ฑ๋ ๋ธ๋ก๊ทธ
danuri๋ ๋ธ๋ก๊ทธ
zzang9ha๋ ๋ธ๋ก๊ทธ
'DevOps > AWS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[AWS] - Spring Boot ํ๋ก์ ํธ ๋ฐฐํฌ(2) (0) | 2023.09.11 |
---|