본문 바로가기

Server/Spring & AWS

[CI/CD] Github Action, AWS로 자동 빌드 및 배포하기

https://kang-james.tistory.com/entry/CICD-Github-Action-AWS로-Java-자동-빌드배포하기 

해당 사이트를 따라 실행하면서 학습했습니다

 

CI/CD란?

 

CI - Continuous Integration

지속적인 통합을 의미한다

(Code - Build - Test)

개발자를 위한 자동화 프로세스 

애플리케이션에 대한 코드 변경사항이 정기적으로 빌드 및 테스트 되어 공유 리포지토리에 통합된다

 

CD - Continuous Delivery / Continuous Deployment

지속적인 서비스 제공, 지속적인 배포를 의미한다

(Release - Deploy - Operate)

  • Release : 배포 가능한 소프트웨어 패키지를 작성
  • Deploy : 프로비저닝을 실행하고 서비스를 사용자에게 노출 (실질적인 배포)
  • Operate : 서비스 현황을 파악하고 생길 수 있는 문제를 감지

CI/CD 파이프라인

개발자가 코드를 push 해서 원격저장소에 올리면, 빌드 테스트 릴리즈를 거쳐서 모든 과정을 통과한 빌드를 배포 서버로 전달한다

배포 서버에 도달한 코드는 애플리케이션 서버에 의해 최종적으로 배포된다

 

지속적인 통합 및 배포를 위하여 코드가 빌드되고 배포되는 과정을 자동화 단계로 만든 것을 파이프라인을 구축한다고 표현한다

 


 

CI / CD 구축

Github Action과 AWS의 CodeDeploy

 

프로젝트를 깃헙에 push 및 merge만 하여도 자동으로 테스트, 배포가 된다

https://cookiee.tistory.com/688

 

Github Action : 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD(연속 통합 및 지속적인 업데이트) 플랫폼

최신 리포지토리에 대해 빌드 및 테스트하거나 프로덕션에 배포하는 워크플로우를 만들 수 있다

(끌어오기 요청이 열리거나 이슈가 생성되는 것과 같은 ‘이벤트’가 리포지토리에서 발생할 때 트리거되도록 GitHub Actions ‘워크플로우’를 구성할 수 있다)

 

워크플로우는 하나 이상의 작업을 실행할 구성이 가능한 자동화 프로세스

워크플로는 리포지토리에 체크인된 YAML 파일에서 정의되며, 리포지토리의 이벤트로 트리거될 때 실행되거나 수동으로 또는 정의된 일정에 따라 트리거될 수 있다

워크플로는 리포지토리의 .github/workflows 디렉터리에 정의된다

  • 끌어오기 요청을 빌드하고 테스트한다
  • 릴리스가 생성될 때마다 애플리케이션을 배포한다
  • 새 문제가 보고될 때마다 레이블을 추가한다

 

 

AWS S3 : 클라우드 스토리지 서비스

S3는 파일, 데이터 및 다양한 유형의 미디어 등을 저장하고 관리하는 데 사용되는 웹 기반 스토리지 시스템이다

 

S3 버킷에 저장되는 데이터는 모두 객체라고 부른다 (바구니 안에 데이터가 쏙)

S3는 데이터를 인터넷을 통해 객체 형태로 저장하는 서비스이다

즉 객체를 업다운로드 하는데 인터넷으로 HTTP/HTTPS를 통한 API가 사용된다

 

 

 

AWS CodeDeploy : 배포서비스 (CD)

CodeDeploy 서버에서 실행되고 있는 Amazon S3 버킷, GitHub 리포지토리 또는 Bitbucket 리포지토리에 저장되는 애플리케이션 콘텐츠를 배포할 수 있

 

 

 

AWS EC2 :  클라우드 컴퓨팅 서비스 (가상 서버)쉽게 말해, 아마존으로부터 한대의 컴퓨터를 임대한다

  • AMI (Amazon machine image) : 서버에 필요한 운영체제와 여러 소프트웨어들이 적절히 구성된 템플릿
  • AMI는 EC2 인스턴스를 실행하기 위한 정보를 모은 단위

1 Github Action build script 작성

name: Sebadog-book server CI/CD # 파이프라인의 이름

on:
  push:
    branches: [ main ] # main 브랜치로 코드가 push될 때 이 파이프라인이 트리거된다
  pull_request:
    branches: [ main ] # main 브랜치로 코드가 pull될 때 이 파이프라인이 트리거된다

jobs:
  build:

    runs-on: ubuntu-latest # 최신 우분투 환경에서 실행한다

    steps:
    - name: Checkout
      uses: actions/checkout@v3 # 리포지토리의 소스 코드를 워크플로우 환경으로 복사해오는 단계이다

    - name: Set up JDK 17
      uses: actions/setup-java@v3 # JDK(Java Development Kit) 17을 설치하고 설정한다
      with:
        java-version: '17'
        distribution: 'temurin'
        
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew # gradlew를 실행 가능하게 만든다
    
    - name: Build with Gradle
      # run: ./gradlew clean build // 프로젝트를 Gradle로 빌드
      run: ./gradlew clean build -x test # 테스트 Skip 
      //프로젝트의 기존 빌드 결과물을 삭제하고 새롭게 빌드하는 과정을 수행한다

 

2 AWS 구축

CI/CD 파이프라인에서 자동화된 작업이 AWS 리소스에 접근하거나 특정 작업을 수행할 수 있도록 인증과 권한을 부여하는 역할을 한다

 

3 S3 생성과 Githhub Action main.yml에 S3 정보 입력

# 디렉토리 생성
    - name: Make Directory
      run: mkdir -p deploy # deploy 디렉토리 생성(존재하지 않을 경우 새로 생성, 존재할 경우 유지)
        
    # Jar 파일 복사
    - name: Copy Jar
      run: cp ./build/libs/*.jar ./deploy
      # ./build/libs/ 경로에 있는 모든 .jar 파일을 ./deploy 디렉토리로 이동시킨다

    - name: Make zip file
      run: zip -r ./sebadog.zip ./deploy
      shell: bash
      # 재귀적으로 deploy 디렉토리의 모든 파일을 포함하여 sebadog.zip을 만든다

    - name: Configure AWS credentials // AWS 리소스에 접근하기 위한 자격 증명을 설정한다
      uses: aws-actions/configure-aws-credentials@v1
      # GitHub Secrets에 저장된 AWS_ACCESS_KEY_ID와 AWS_SECRET_ACCESS_KEY를 사용한다
      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 ./sebadog.zip s3://$S3_BUCKET_NAME/
      # aws s3 cp 명령어를 사용하여 sebadog.zip 파일을 지정된 S3 버킷($S3_BUCKET_NAME)에 복사한다

 

4 EC2, CodeDeploy IAM역할 생성

 

 5 EC2 생성 및 연결(접속)

https://seosh817.tistory.com/309

 

[AWS] AWS EC2 인스턴스(Linux Ubuntu) 생성 및 SSH로 접속하기

이번 포스트에서는 EC2 인스턴스(Linux ubuntu)를 생성하고 인스턴스에 접속하는 방법을 정리하겠습니다. Amazon EC2(Amazon Elastic Compute Cloud)란? Amazon Elastic Compute Cloud(Amazon EC2)는 Amazon Web Services(AWS) 클라

seosh817.tistory.com

 

SSH란 Secure Shell Protocol, 즉 네트워크 프로토콜 중 하나로 컴퓨터와 컴퓨터가 인터넷과 같은 Public Network를 통해 서로 통신을 할 때 보안적으로 안전하게 통신을 하기 위해 사용하는 프로토콜이다

 

sudo apt update # 패키지 업데이트
sudo apt install ruby-full # AWS CodeDeploy 에이전트는 Ruby로 작성되어있기 때문에 Ruby 설치
sudo apt install wget # 파일을 다운로드할 때 사용하는 도구인 wget 설치

cd /home/ubuntu # 작업 디렉토리 이동

sudo apt install awscli # AWS 서비스와 상호작용할 수 있는 명령줄 도구인 AWS CLI(Command Line Interface) 설치
aws s3 cp s3://aws-codedeploy-ap-northeast-2/latest/install . --region ap-northeast-2
# AWS S3에서 CodeDeploy 에이전트 설치 스크립트(install)를 서울 리전(ap-northeast-2)에서 현재 디렉토리로 다운로드하는 역할

chmod +x ./install # 다운로드한 install 파일에 실행 권한을 부여
sudo ./install auto # CodeDeploy 에이전트를 자동으로 설치

# 아래 코드로 설치 확인
sudo service codedeploy-agent status

 

6 CodeDeploy 생성

 

7 main.yml에 CodeDeploy 연결 정보 작성

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

 

deploy.sh 생성

해당 스크립트를 통해서 프로젝트를 배포 후 자동으로 실행하게 되어 무중단 배포를 유지할 수 있다

#!/usr/bin/env bash

REPOSITORY=/home/ubuntu/app # 배포될 애플리케이션이 위치한 디렉토리 경로

echo "> 현재 구동 중인 애플리케이션 pid 확인"
PORT = $(8080)
CURRENT_PID=$(sudo lsof -t -i:$PORT)

echo "현재 구동 중인 애플리케이션 pid: $CURRENT_PID"

if [ -z "$CURRENT_PID" ]; then
  echo "현재 구동 중인 애플리케이션이 없으므로 종료하지 않습니다."
else
  echo "> kill -9 $CURRENT_PID"
  kill -9 $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 &
# 새로운 JAR 파일을 백그라운드에서 실행

 

main.yml 수정 << 오류 발생 

이름을 다시 확인하고, 다시 순서를 되짚어보고(EC2 다시 연결) 했으나, deploy env: 영역에서 여전히 252 에러(AWS CLI에서 발생하는 일반적인 오류 코드)가 발생했다

원인1 : 들여쓰기 문제 (yml 파일에선 들여쓰기 하나 잘못해도 오류가 발생했다, 직접 타이핑을 쳤더니 오류가 해결됐다)원인2 : 마지막 run 부분에서 백슬래시 뒤에 공백이 하나 있었기 때문에 오류가 발생했다

name: Sebadog-book server CI/CD

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  S3_BUCKET_NAME: [bucket 이름]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'
        
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    
    - name: Build with Gradle
      # run: ./gradlew clean build
      run: ./gradlew clean build -x test # 테스트 Skip

    # 디렉토리 생성
    - 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 ./[S3 압축파일 이름].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 ./sebadog.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 [애플리케이션 이름] \
        --deployment-group-name [배포 그룹 이름] \
        --file-exists-behavior OVERWRITE \
        --s3-location bucket=[S3 bucket 이름],bundleType=zip,key=[S3 압축파일 이름].zip \
        --region ap-northeast-2

 

 

8 포트 열기 (EC2 인바운드 규칙 편집)

 

9 EC2 접속 해제

https://hgk5722.tistory.com/401

 

[AWS] AWS 프리티어 인스턴스 EC2 생성 및 접속 해제/중지

AWS를 이용한 웹 서버를 만들어 보겠습니다. EC2 서비스, 프리 티어(free tier)로 생성할 예정입니다. 그전에 EC2에 대한 개념적인 설명을 먼저 진행하겠습니다. 1. EC2 1-1. EC2란? Elastic Compute Cloud의 약자

hgk5722.tistory.com

 


정리하기


출처

https://velog.io/@leejungho9/CICD-%EB%9E%80

https://seongwon.dev/DevOps/20220713-CICD%EB%9E%80/

https://kang-james.tistory.com/entry/CICD-Github-Action-AWS로-Java-자동-빌드배포하기 [내 꿈을 JAVA:티스토리]
https://docs.github.com/ko/enterprise-cloud@latest/actions/about-github-actions/understanding-github-actions 

https://bigco-growth-diary.tistory.com/43 

https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/welcome.html 

https://seoyeonhwng.medium.com/aws-ec2%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-acf6b7041908[

출처: https://inpa.tistory.com/entry/AWS-📚-EC2-개념-사용-구축-세팅-💯-정리-인스턴스-EBS-AMI [Inpa Dev 👨‍💻:티스토리]

https://baked-corn.tistory.com/52

https://velog.io/@mminjg/Github-Actions-CodeDeploy%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-EC2-%EB%B0%B0%ED%8F%AC-%EC%9E%90%EB%8F%99%ED%99%94 

https://m42-orion.tistory.com/139