๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ‘ฉ‍๐Ÿ’ป TECH

[TECH] GitHub Actions๋กœ CI/CD ๊ตฌ์ถ•ํ•˜๊ธฐ(2)

by may_yy 2023. 9. 5.

[ํ‹ฐ๋Œ] ํ‹ฐ๋Œ GitHub Actions๋กœ CICD ๊ตฌ์ถ•ํ•˜๊ธฐ(2)

์•ˆ๋…•ํ•˜์„ธ์š” ํ‹ฐํ”Œ์˜ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ๊น€์œ ์ •์ž…๋‹ˆ๋‹ค :)

์ €๋Š” ์˜ค๋Š˜ CI/CD๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋‹จ๊ณ„์—์„œ CodeDeploy Agent ์„ค์น˜ ๊ณผ์ •, ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ, ๋ฐฐํฌ ๋™์ž‘ ์ถ”๊ฐ€์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ์„ค๋ช…ํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค. 


์ด์ „ ๊ธ€์—์„œ ์ด์–ด์ง€๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

๐Ÿ‘ฉ‍๐Ÿ’ป CodeDeploy Agent ์„ค์น˜

๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

*์„ค์น˜ ๋ฐฉ๋ฒ•์€ ubuntu ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค.

 

# apt ์—…๋ฐ์ดํŠธ
sudo apt-get update && sudo apt-get upgrade

# JDK 11 ์„ค์น˜
sudo apt-get install openjdk-11-jdk

# Ruby ์„ค์น˜ (3.xx ๋ฒ„์ „ ์„ค์น˜๋จ)
sudo apt install ruby-full

# wget ๋ชจ๋“ˆ ์„ค์น˜
sudo apt install wget

cd /home/ubuntu

# codedeploy ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ
sudo wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install

๋‹ค์Œ์˜ ๋ช…๋ น์–ด๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ์ˆ˜ํ–‰ํ–ˆ๋‹ค๋ฉด, ๋‹ค์šด๋กœ๋“œ ๋ฐ›์€ ๋””๋ ‰ํ† ๋ฆฌ์— installํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

CICD

 

๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ์ž…๋ ฅํ•ด ์„ค์ • ๋ฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ codedeploy ๋ฒ„์ „์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

# ๊ถŒํ•œ ์„ค์ •
sudo chmod +x ./install

# ์ถœ๋ ฅ์„ ์ž„์‹œ ๋กœ๊ทธํŒŒ์ผ์— ์”€
sudo ./install auto > /tmp/logfile

# aws cli ์„ค์น˜
sudo apt-get install awscli

# ์„œ์šธ ๋ฆฌ์ „์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ codedeploy ๋ฒ„์ „ ํ™•์ธ
sudo aws s3 ls s3://aws-codedeploy-ap-northeast-2/releases/ | grep '\.deb$'

์œ„ ๋ช…๋ น์–ด๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฒ„์ „์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ‹ฐ๋Œ์€ 1.3.2 ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

sudo ./install auto -v releases/codedeploy-agent_1.3.2-1902_all.deb > /tmp/logfile

# ์„œ๋น„์Šค๊ฐ€ ์‹คํ–‰์ค‘์ธ์ง€ ํ™•์ธ
sudo service codedeploy-agent status

 

sudo service codedeploy-agent-status ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด codedeploy-agent service๊ฐ€ Active๋œ ์ƒํƒœ์ž„์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

CodeDeploy

 


๐Ÿ‘ฉ‍๐Ÿ’ป CodeDeploy ์ƒ์„ฑ

AWS์—์„œ CodeDeploy ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒ์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

1. CodeDeploy๋ฅผ ์œ„ํ•œ IAM ์—ญํ•  ์ƒ์„ฑ

“๋‹ค๋ฅธ AWS ์„œ๋น„์Šค์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€ → CodeDeploy”๋ฅผ ํด๋ฆญํ•˜๋ฉด CodeDeploy์˜ ๋ชจ๋“  ๊ถŒํ•œ์ด ๋ณด์—ฌ๋œ ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

AWS
CodeDeployRole

 

2. CodeDeploy ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์„ฑ 

AWS์ฝ˜์†”์—์„œ CodeDeploy๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์ƒˆ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๊ณ , EC2/์˜จํ”„๋ ˆ๋ฏธ์Šค๋ฅผ ์„ ํƒํ•ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

githubActions

 

3. ๋ฐฐํฌ ๊ทธ๋ฃน ์ƒ์„ฑ

์ƒ์„ฑ๋œ CodeDeploy ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํด๋ฆญํ•˜๊ณ  ๋ฐฐํฌ ๊ทธ๋ฃน์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

CodeDeployGroup

๋ฐฐํฌ ๊ทธ๋ฃน๋ช…์„ ์ง€์ •ํ•˜๊ณ , ์„œ๋น„์Šค ์—ญํ• ์—๋Š” ๋ฐฉ๊ธˆ ๋งŒ๋“ค์—ˆ๋˜ IAM ์—ญํ• ๊ณผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌ ๊ตฌ์„ฑ์€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ๋ฅผ ์–ด๋–ป๊ฒŒ ์ˆ˜ํ–‰ํ• ์ง€์— ๋Œ€ํ•œ ์„ ํƒ์ž…๋‹ˆ๋‹ค. AllAtOnce๋Š” ํ•œ๋ฒˆ์— ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐฐํฌํ•œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

Deployment

 


๐Ÿ‘ฉ‍๐Ÿ’ป deploy.yml ์ˆ˜์ •

deploy.yml์— ๋ฐฐํฌ ๋™์ž‘ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

 

name: Build and Deploy Spring Boot to AWS EC2

on:
  push:
    branches: [ main ]
# ์ถ”๊ฐ€
env:
  PROJECT_NAME: tikkle-server
  BUCKET_NAME: github-actions-s3-bucket-ec2
  CODE_DEPLOY_APP_NAME: codedeploy-app
  DEPLOYMENT_GROUP_NAME: codedeploy-deployment-group
# ---------------------
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup Java JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 11

      - name: Setup MySQL
        uses: samin/mysql-action@v1
        with:
          character set server: 'utf8'
          mysql database: 'rds'
          mysql user: ${{user}}
          mysql password: ${{password}}

      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew
        shell: bash

      - name: Make application-prod.properties
        if: contains(github.ref, 'main') # branch๊ฐ€ main ์ผ ๋•Œ
        run: |
          cd ./src/main/resources
          touch ./application-prod.properties
          echo "${{ secrets.APPLICATION }}" > ./application-prod.properties
        shell: bash

      - name: Build with Gradle
        run: ./gradlew build -x test
        shell: bash
# ์ถ”๊ฐ€
			- name: Make Zip File
        run: zip -qq -r ./$GITHUB_SHA.zip .
        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 ./$GITHUB_SHA.zip s3://$BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip

      - name: Code Deploy
        run: aws deploy create-deployment --application-name $CODE_DEPLOY_APP_NAME --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name $DEPLOYMENT_GROUP_NAME --s3-location bucket=$BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip
# ---------------------

1) env: deploy.yml ํŒŒ์ผ์— ์‚ฌ์šฉ๋˜๋Š” ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.

  • PROJECT_NAME: ํ”„๋กœ์ ํŠธ ์ด๋ฆ„์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ณ€์ˆ˜๋Š” S3 ๊ฒฝ๋กœ ์„ค์ •์— ์‚ฌ์šฉ์š‰๋‹ˆ๋‹ค.
  • BUCKET_NAME: ์•ž์„œ ์ƒ์„ฑํ•œ S3 ๋ฒ„ํ‚ท ์ด๋ฆ„์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
  • CODE_DEPLOY_APP_NAME: CodeDeploy ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฆ„์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
  • DEPLOYMENT_GROUP_NAME: CodeDeploy ๋ฐฐํฌ ๊ทธ๋ฃน ์ด๋ฆ„์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

2) jobs - steps์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋™์ž‘์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

  • Make Zip File : zipํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • Configure AWS Credentials : AWS_SECRET_ACCESS_KEY์„ ํ†ตํ•ด AWS ๊ณ„์ •์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ์–ป์Šต๋‹ˆ๋‹ค.
  • Upload to S3 : S3 ๋ฒ„ํ‚ท์— zipํŒŒ์ผ์„ ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
  • Code Deploy : CodeDeploy์— ๋ฐฐํฌ ์š”์ฒญ์„ ๋‚ ๋ฆฝ๋‹ˆ๋‹ค.

๐Ÿ‘ฉ‍๐Ÿ’ป appspec.yml ์ƒ์„ฑ

ํ”„๋กœ์ ํŠธ ์ตœ์ƒ๋‹จ ๊ฒฝ๋กœ์— appspec.ymlํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์€ ๋ฐฐํฌ ์‹œ, CodeDeploy๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.

appspec.yml์œ„์น˜

ymlํŒŒ์ผ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

version: 0.0
os: linux
files:
  - source:  /
    destination: /home/ubuntu/tikkle
    overwrite: yes

permissions:
  - object: /
    pattern: "**"
    owner: root
    group: root

hooks:
  AfterInstall:
    - location: scripts/deploy.sh
      timeout: 60
      runas: root
  • version: appspec.ymlํŒŒ์ผ ๋ฒ„์ „์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • files:
    • ๋ฐฐํฌํ•  ํŒŒ์ผ ๋ฐ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๊ฐ€์ ธ์™€ “/home/ubuntu/tikkle” ๋””๋ ‰ํ† ๋ฆฌ๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • permissions:
    • ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŒŒ์ผ์— ๋Œ€ํ•œ ๊ถŒํ•œ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. “/home/ubuntu/tikkle” ๋””๋ ‰ํ† ๋ฆฌ์˜ ๊ทธ๋ฃน๊ณผ ์†Œ์œ ์ž๋ฅผ root๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • hooks:
    • AfterInstall: ์—ฌ๋Ÿฌ ๋ฐฐํฌ ๋‹จ๊ณ„ ์ค‘ AfterInstall ๋‹จ๊ณ„์—์„œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค
    • ๋ฐฐํฌ ๋‹จ๊ณ„์—์„œ ์‹คํ–‰ํ•  ํ›… ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐํฌ ํ›„ ์‹คํ–‰ํ•  ์Šคํฌ๋ฆฝํŠธ์ธ deploy.sh ํŒŒ์ผ์„ ์ง€์ •ํ•˜๊ณ , ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์‹œ๊ฐ„์„ 60์ดˆ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ‘ฉ‍๐Ÿ’ป scripts/deploy.sh ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ ์ƒ์„ฑ

ํ”„๋กœ์ ํŠธ ์ตœ์ƒ๋‹จ์— scripts/deploy.sh ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌ์Šคํฌ๋ฆฝํŠธ

์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ์ด์ „์— ์‹คํ–‰์ค‘์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ค‘๋‹จํ•˜๊ณ , ์ตœ์‹  ๋ฒ„์ „์˜ JarํŒŒ์ผ์„ ์‹คํ–‰ํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

#!/usr/bin/env bash

REPOSITORY=/home/ubuntu/tikkle
cd $REPOSITORY

echo "> Build ํŒŒ์ผ ๋ณต์‚ฌ"
cp ./build/libs/*.jar $REPOSITORY/

echo "> ํ˜„์žฌ ๊ตฌ๋™์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ pid ํ™•์ธ"
CURRENT_PID=$(pgrep -fl tikkle)
echo "$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/ | grep jar | tail -n 1)

echo "> JAR Name: $JAR_NAME"

echo "> $JAR_NAME์— ์‹คํ–‰๊ถŒํ•œ ์ถ”๊ฐ€"
chmod +x $JAR_NAME

echo ">$JAR_NAME ์‹คํ–‰"

nohup java -jar $JAR_NAME > /dev/null 2> /dev/null < /dev/null &

 


๐Ÿ‘ฉ‍๐Ÿ’ป ๊ฒฐ๊ณผ

cicd๋ฅผ ํ•˜๊ธฐ ์œ„ํ•œ ์ค€๋น„๋Š” ๋‹ค ๋งˆ์ณค์Šต๋‹ˆ๋‹ค. ๋ฉ”์ธ ๋ธŒ๋žœ์น˜๋กœ ํ‘ธ์‹œํ•ด ์ •์ƒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ด…๋‹ˆ๋‹ค.

 

DevOps
springboot


๐Ÿ‘ฉ‍๐Ÿ’ป ๋งˆ์น˜๋ฉฐ

๋“œ๋””์–ด CI/CD ๊ตฌ์ถ•์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด ๋๋‚ฌ์Šต๋‹ˆ๋‹ค!

 

์ž๋™ ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š”๋ฐ ๊ธด ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ์ง€๋งŒ, ํ•œ ๋ฒˆ ๊ตฌ์ถ•ํ•ด ๋†“์œผ๋ฉด ๋ฐฐํฌ ๊ณผ์ •์„ ์ค„์ผ ์ˆ˜ ์žˆ์œผ๋‹ˆ ๊ตฌ์ถ•ํ•ด ๋ณด๋Š” ๊ฒƒ์„ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

 

๋‹ค์Œ์—๋Š” ํ‹ฐ๋Œ์ด ์–ด๋–ป๊ฒŒ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ถ„์„ํ•˜๊ณ  ํ…Œ์ด๋ธ”์„ ์„ค๊ณ„ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๋‚ด์šฉ์œผ๋กœ ์ฐพ์•„๋ต™๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค๐Ÿ˜„

 

๐Ÿ“ฉ Contact : uuuuujeong00000@naver.com

๐Ÿ“ฒ SNS : https://www.instagram.com/may_u_j__