코드스테이츠 백엔드 부트캠프 75, 76일차 - [Cloud] 배포 자동화

wish17·2023년 4월 2일
0
post-thumbnail

Automated Deployment

배포 자동화

  • 한번의 클릭 혹은 명령어 입력을 통해 전체 배포 과정을 자동으로 진행하는 것
    • 시간절약
    • 휴먼 에러(Human Error)를 방지

배포 자동화 파이프라인

소스 코드의 관리부터 실제 서비스로의 배포 과정을 연결하는 구조

  • 파이프라인의 단계는 상황과 필요에 따라 더 세분화되거나 간소화될 수 있다.

파이프라인 단계

  • Source 단계

    • 원격 저장소에 관리되고 있는 소스 코드에 변경 사항이 일어날 경우, 이를 감지하고 다음 단계로 전달하는 작업을 수행하는 단계
  • Build 단계

    • Source 단계에서 전달받은 코드를 컴파일, 빌드, 테스트하여 가공하는 단계 ( + Build 단계를 거쳐 생성된 결과물을 다음 단계로 전달 )
  • Deploy 단계

    • Build 단계로부터 전달받은 결과물을 실제 서비스에 반영하는 단계

AWS 개발자 도구

CodeCommit

  • GitHub과 유사한 버전 관리 도구
    • GitHub보다 보안성 우수
    • but 요금이 부과되니 자잘한 변화는 깃헙을 이용하자
  • Source 단계를 구성할 때 사용

CodeBuild

  • 유닛 테스트, 컴파일, 빌드와 같은 빌드 단계에서 필수적으로 실행되어야 할 작업들을 명령어를 통해 실행할 수 있는 도구
  • Build 단계에서 사용
  • 사용자가 작성한 buildspec.yml 파일을 참조하여 작업을 수행

CodeDeploy

  • 실행되고 있는 서버 애플리케이션에 실시간으로 변경 사항을 전달하는데 사용하는 도구
    • 또한 S3 서비스를 통해 S3 버킷을 통해 업로드된 정적 웹 사이트에 변경 사항을 실시간으로 전달하고 반영할 수 있다.
  • Deploy 단계에서 사용
  • 사용자가 작성한 appspec.yml 파일을 참조하여 작업을 수행

CodePipeline

  • 각 단계를 연결하는 파이프라인을 구축할 때 사용하는 도구

실습

설치

JAVA 설치

$ sudo apt update
$ sudo apt install openjdk-11-jre-headless

//설치 확인
$ java -version

AWS CLI 설치

명령줄 셸의 명령을 사용하여 AWS 서비스와 상호 작용할 수 있는 오픈 소스 도구

$ cd ~
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ sudo apt install unzip
$ unzip awscliv2.zip
$ sudo ./aws/install

//설치 확인
$ aws --version

Code Deploy Agent 설치

CodeDeploy의 명령을 받는 프로그램

  • CodeDeploy로 배포를 진행하려면 EC2에 반드시 CodeDeploy Agent가 설치되어 있어야 한다.
$ cd ~
$ sudo apt update
$ sudo apt install ruby-full                # [Y / n] 선택 시 Y 입력
$ sudo apt install wget
$ cd /home/ubuntu
$ sudo wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
$ sudo chmod +x ./install
$ sudo ./install auto > /tmp/logfile

// 서비스 실행 확인
$ sudo service codedeploy-agent status

EC2 인스턴스 역할 부여


AWS Pipeline을 통한 배포 자동화

풀코드 github 주소

파이프라인 생성

환경변수 설정

  • 보안이슈가 발생할 수 있으니 aws에서 지원하는 Parameter Store을 통해 데이터베이스 패스워드 등을 전달하자.

파이프라인 실습내용 정리

  • ec2 인스턴스 접속하면 습관적으로 cd ~를 입력해 홈 경로에서 시작하자.

    • 기본 루트에서 하면 서버 터질 수 있음(터져서 고생했음 ㅠ.ㅠ)
  • ec2 인스턴스에 프로젝트 파일 자체가 자동으로 전달되는 것이 아니다.

    • /home/ubuntu 경로에 가면 빌드한 결과물인 .jar 파일 등이 있다.
  • Parameter Store에서 변수를 변경하게 된다면 파이프라인 릴리스 해줘야한다.

    • 자동 반영 안됨. 빌드하면서 환경변수 읽어오기 때문
  • ec2 인스턴스 재부팅시 주소값 변하는거 확인

    • 주소값 변하면 클라이언트 파일 중 .env파일 수정 후 리빌드해서 S3 다시 올려야 함.
  • 위와 같은 변경 후에 문제 해결 전 캐쉬기록이 남아 오류발생할 수 있음.

    • 이것저것 수정해도 안되길래 뭔가 했더니 시크릿 모드로 체크하니 통과...

프로세스 종료방법

// 탐색
$ ps -ef | grep jar
// 삭제
sudo kill [PID]

Github Actions를 통한 배포 자동화

Github Actions

  • Github이 공식적으로 제공하는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD 플랫폼
  • 레포지토리에서 Pull Request 나 push 같은 이벤트를 트리거로 GitHub 작업 워크플로(Workflow)를 구성할 수 있다.

설정 파일(.yml)에 따라 Github Repository의 특정 변동사항을 트리거로 작동된다.
(실습에서는 main 브랜치에 push 하는 경우 작동되도록 했다.)

1. GitHub Actions 생성

위와 같이 gradle.yml파일 자동 생성하니 '~/gradlew' is not executable 오류 발생

아래와 같이 Build with Gradle 이전에 ./gradlew에 권한을 부여해서 해결했다.

name: Java CI with Gradle

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

permissions:
  contents: read

env:
  S3_BUCKET_NAME: be-58-wish9

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
    - name: Add permission # '~/gradlew' is not executable. 에러 때문에 추가
      run: chmod +x gradlew # '~/gradlew' is not executable. 에러 때문에 추가
    - name: Build with Gradle
      uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
      with:
        arguments: build

aws access 설정 추가 + 빌드파일 S3에 전달

  • Github Actions는 설정 파일(.yml)에 따라 Github Repository에 특정 변동사항을 트리거로 작동한다.
name: Java CI with Gradle

on:
  push:
    branches: [ "master" ]
  pull_request: # 없어도 됨 (누군가가 해당 레파지토리에서 pull하면 자동배포 되는거임) 
    branches: [ "master" ]

permissions:
  contents: read

env:
  S3_BUCKET_NAME: be-58-wish9

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
    - name: Add permission # '~/gradlew' is not executable. 에러 때문에 추가
      run: chmod +x gradlew # '~/gradlew' is not executable. 에러 때문에 추가
    - name: Build with Gradle
      uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
      with:
        arguments: build

      # build한 후 프로젝트를 압축
    - name: Make zip file
      run: zip -r ./practice-deploy.zip .
      shell: bash

      # Access KeySecret Access Key를 통해 권한을 확인
      # Access KeySecret Key는 직접 작성 X (깃 설정에서 추가)
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려와진다.
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려와진다.
        aws-region: ap-northeast-2

      # 압축한 프로젝트를 S3로 전송
    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./practice-deploy.zip s3://$S3_BUCKET_NAME/practice-deploy.zip

프로젝트 설정에서 access key 등록

인텔리제이에서 수정했던 gradle.yml파일 push
(자동생성 된 gradle.yml파일을 pull해서 수정했음)

자동배포 정상작동!

S3 버킷에 압축파일이 전송된 것도 확인

2. 빌드파일 배포 및 실행

애플리케이션 + 그룹 생성

IAM 권한에 AWSCodeDeployRole 추가되어 있어야 생성 가능

AWSCodeDeployRole

  • AWS CodeDeploy 애플리케이션 및 배포 그룹 생성 및 수정 권한
  • AWS CodeDeploy 배포 작업을 위한 EC2 인스턴스 및 온프레미스 서버에 대한 액세스 권한
  • AWS CodeDeploy 배포 작업에서 Amazon S3 버킷에 대한 읽기 권한
  • AWS CodeDeploy 배포 작업에서 Amazon EC2 Systems Manager에 대한 권한

EC2 배포 진행 상황 별 로그를 기록하고 새로 배포된 빌드 파일을 실행하는 shell script 파일(deploy.sh) 생성

#!/bin/bash
BUILD_JAR=$(ls /home/ubuntu/action/build/libs/practice-githubAction-0.0.1-SNAPSHOT.jar)
JAR_NAME=$(basename $BUILD_JAR)

echo "> 현재 시간: $(date)" >> /home/ubuntu/action/deploy.log

echo "> build 파일명: $JAR_NAME" >> /home/ubuntu/action/deploy.log

echo "> build 파일 복사" >> /home/ubuntu/action/deploy.log
DEPLOY_PATH=/home/ubuntu/action/
cp $BUILD_JAR $DEPLOY_PATH

echo "> 현재 실행중인 애플리케이션 pid 확인" >> /home/ubuntu/action/deploy.log
CURRENT_PID=$(pgrep -f $JAR_NAME)

if [ -z $CURRENT_PID ]
then
  echo "> 현재 구동중인 애플리케이션이 없습니다." >> /home/ubuntu/action/deploy.log
else
  echo "> kill -9 $CURRENT_PID" >> /home/ubuntu/action/deploy.log
  sudo kill -9 $CURRENT_PID
  sleep 5
fi


DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> DEPLOY_JAR 배포"    >> /home/ubuntu/action/deploy.log
sudo nohup java -jar $DEPLOY_JAR >> /home/ubuntu/deploy.log 2>/home/ubuntu/action/deploy_err.log &

Code Deploy의 작동을 모아놓은 appspec.yml 파일 설정

version: 0.0
os: linux
files:
  - source:  /
    destination: /home/ubuntu/action # 배포 진행되는 디렉토리 주소
    overwrite: yes

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

hooks:
  ApplicationStart:
    - location: scripts/deploy.sh # 최상위 디렉토리에서 해당 경로에 있는 deploy라는 이름의 쉘 스크립트 실행
      timeout: 60
      runas: ubuntu

gradle.yml 파일에 Code Deploy 배포 명령 추가

name: Java CI with Gradle

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

permissions:
  contents: read

env:
  S3_BUCKET_NAME: be-58-wish9

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
    - name: Add permission # '~/gradlew' is not executable. 에러 때문에 추가
      run: chmod +x gradlew # '~/gradlew' is not executable. 에러 때문에 추가
    - name: Build with Gradle
      uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
      with:
        arguments: build

      # build한 후 프로젝트를 압축
    - name: Make zip file
      run: zip -r ./practice-deploy.zip .
      shell: bash

      # Access KeySecret Access Key를 통해 권한을 확인
      # Access KeySecret Key는 직접 작성 X (깃 설정에서 추가)
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려와진다.
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려와진다.
        aws-region: ap-northeast-2

      # 압축한 프로젝트를 S3로 전송
    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./practice-deploy.zip s3://$S3_BUCKET_NAME/practice-deploy.zip

-------------------------------------추가된 부분-------------------------------------
      # CodeDeploy에게 배포 명령을 내립니다.
    - name: Code Deploy
      run: >
        aws deploy create-deployment --application-name be-58-wish9
        --deployment-config-name CodeDeployDefault.AllAtOnce
        --deployment-group-name be-58-wish9-group
        --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=practice-deploy.zip
-------------------------------------추가된 부분-------------------------------------

수정, 추가한 파일 깃허브로 push하면 아래와 같이 배포 성공 확인가능

자동 배포 설정해둔 경로

ssm-user@ip-172-31-34-158:/var/snap/amazon-ssm-agent/6312$ cd ~
ssm-user@ip-172-31-34-158:~$ cd /home
ssm-user@ip-172-31-34-158:/home$ ls
ssm-user  ubuntu
ssm-user@ip-172-31-34-158:/home$ cd ubuntu/
ssm-user@ip-172-31-34-158:/home/ubuntu$ ls
action  build  deploy.log  install
ssm-user@ip-172-31-34-158:/home/ubuntu$ cd action
ssm-user@ip-172-31-34-158:/home/ubuntu/action$ ls
appspec.yml  build  build.gradle  deploy.log  deploy_err.log  gradle  gradlew  gradlew.bat  practice-githubAction-0.0.1-SNAPSHOT.jar  scripts  settings.gradle  src

Github Actions 다시 실행하는 방법


응용실습

예전에 파이썬으로 만들었던 프로젝트를 활용해서 간단한 방명록 애플리케이션을 만들어서 배포해봤다.

풀코드 GitHub 주소

0개의 댓글