CI / CD 란?

앱과 조직의 개발 리소스에 따라 새 소프트웨어를 빌드하고 출시하는 데 9개월 이상 소요될 수 있습니다.  CI/CD의 목표는 이 모든 것을 바꾸는 것입니다. CI/CD는 앱 개발 단계에 자동화를 통합하는 앱 제공 방식입니다. CI/CD는 지속적인 통합/지속적인 제공 또는 배포를 뜻하며, 앱 개발 시간을 줄이고 릴리스 수를 늘리는 것을 목표로 하는 Agile 개발 방식에서 비롯되었습니다.

 

 

CI

지속적 통합이라는 뜻으로 개발을 진행하면서도 품질을 관리할 수 있도록 여러 명이 하나의 코드에 대해서 수정을 진행해도 코드 변경 사항을 공유 버전 관리 리포지토리에 병합하는 방식을 설명합니다. CI를 사용하면 개발자 팀 사이에 충돌 없이 동일한 앱을 동시에 작업할 수 있습니다.

CI 덕분에 그림과 같은 현상을 피할 수 있습니다.                             출처 : https://backlog.com/git-tutorial/kr/intro/intro1_1.html
CI를 통해 빌드와 테스트를 진행하며 실패했을 경우 즉각 알려준다.

 

 

CD

지속적 배포/제공 라는 뜻으로 계속 개발되는 코드를 필요한 위치에 자동으로 배포합니다. 프로덕션, 개발 또는 테스트 환경뿐만 아니라 사용자에게 직접 보낼 수도 있습니다. 즉, 코드에 대한 변경 사항이 실제 환경에 배포됩니다.

지속적 통합/제공이 없었다면 여러개의 서버일 경우 하나씩 배포해줘야 한다.

 

 

 

 

 

 

 

gitHub Actions 를 이용한 CI 

 

GitGub Repository 및 API 생성

gitHub에 Repository를 생성(기존의 Spring Boot로 되어 있는 Repository를 사용) 하고, 아래와 같은 API를 생성합니다.

@GetMapping("/hello")
public String test(){
    return "hello";
}

 

 

 

 

Actions에서 workflow를 생성합니다.

 

 

set up a workflow yourself 를 클릭하면 이미 setting이 되어있는데 설명은 아래와 같다.

 

 

하지만 연습하는 것이기에 싹 지우고 아래와 같이 적어준다. 이후 잘 된다면 혼자서 이것 저것 바꿔보세요.

name: Java CI with Gradle

on:
  push:
    branches: [ "master" ]
    
jobs:
  build:
    runs-on: ubuntu-18.04                

    steps:
    - uses: actions/checkout@v3
    
     # 자신의 JDK 버전에 따라 변경
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
    # 자신의 JDK 버전에 따라 변경
        java-version: '11'
        distribution: 'temurin'
        
    # 빌드를 하는 과정입니다.
    - name: Grant execute permission for gradlew
      run: chmod +x ./gradlew
      shell: bash
      
    - name: Build with Gradle
      run: ./gradlew build
      shell: bash

 

 

생성하면 GitHub Repository에 .giyHub/workflows가 생긴것을 확인 할 수 있습니다.

 

Actions 탭에 새로운 workflows가 생성되는데 클릭

 

 

내가 생성한 workflow가 성공하면 이렇게 초록색으로 표시되며 실패하면 빨간색과 무엇때문에 실패했는지 목록에서 펼쳐보면 확인할 수 있습니다. 여기 까지 성공하면 CI는 완료입니다. 

 

 

 

 

 

AWS(ec2, codeDeploy, s3) 를 이용한 CD

 

EC2 생성 및 보안그룹 설정 

ubuntu 20.04는 agent설치가 잘 안되므로 18.04 로 생성해줍니다.

 

보안규칙은 저의 스프링부트 포트인 8090(기본 : 8080)과 사용자들이 접근할 수 있도록 80포트를 열어주세요.

 

 

 

 

 

EC2 IAM 역활 생성 및 부여

아래와 같은 설정으로 IAM 역활을 생성합니다.

 

EC2  보안 > IAM 역활 수정에서 위에서 생성한 IAM을 부여합니다.

 

 

 

 

 

 

EC2에 접속해 JDK와 Agent 설치

자바 설치

1. 사용 가능한 패키지와 버전의 리스트를 업데이트(즉, 최신 버전이 있는지 확인하는 과정)
sudo apt-get update

2.JDK 설치
 설치 중 계속 진행할 것인지 물어보는데 'Y'를 입력하고 엔터를 누르면 계속 설치가 진행됩니다. 
 자신이 맞는 버전을 설치 아래 숫자만 다르게 하면 됩니다. 저는 11버전이라서 11로 설치
sudo apt-get install openjdk-11-jdk


3.JDK 버전 확인
java -version

 

 

Agent 설치

확실한 것은 AWS문서 를 참고하시는게 좋습니다.

1. Ubuntu Server 18.04 버전에서만 가능합니다. 아래 코드를 통해 ruby를 설치합니다.

sudo apt update
sudo apt install ruby-full
sudo apt install wget

 

2.  다음 명령을 입력해서 이동합니다.

cd /home/ubuntu

 

3. aws s3버킷 install를 받아야합니다.

wget https://{bucket-name}.s3.{region-identifier}.amazonaws.com/latest/install

bucket-name은 저는 서울이기에 aws-codedeploy-ap-northeast-2 로 대체 region-identifierap-northeast-2로 대체해주면 됩니다.

wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install

 

위까지 잘되었다면 install 이라는 파일이 생긴것을 확인할 수 있습니다.

 

4. 다음 명령을 입력합니다.

chmod +x ./install

 

5. 다음 명령을 입력합니다.

sudo ./install auto

 

 

6. 서비스가 실행 중인지 확인하려면 다음 명령을 입력합니다.

CodeDeploy 에이전트가 설치되어 실행 중이면 "The AWS CodeDeploy agent is running"와 같은 메시지가 표시되어야 합니다.

sudo service codedeploy-agent status

 

 

"error: No AWS CodeDeploy agent running"와 같은 메시지가 표시되면 서비스를 시작하고 다음 두 명령을 한 번에 하나씩 실행합니다.

sudo service codedeploy-agent status
sudo service codedeploy-agent start

 

sudo service codedeploy-agent status 명령어를 치면 아래와 같이 running이 나와야합니다.

 

 

 

 

 

 

S3 생성 및 IAM 사용자 생성

1. S3 버킷 생성

아래와 같은 설정으로 S3 버킷을 생성해주세요.

 

 

 

 

1. IAM 사용자 생성

아래와 같은 설정으로 사용자를 추가해주세요

 

진행하다보면 액세스 키 와 비밀 엑세스키를 주는데 꼭 어디에 메모해 놔주세요 다신 볼 수 없습니다.

 

 

 

 

 

 

액세스키 Secrets에 설정하기

아래와 같이 Repository > settings > secrets > new repository secret 클릭해서 위에 액세스키들을 설정해줍니다.

 

 

 

 

 

CodeDeploy IAM 역활 생성

아래와 같은 설정으로 IAM 역활을 생성해주세요.

 

 

 

 

CodeDeploy 애플리케이션 생성

애플리케이션 생성 이후 배포그룹 생성을 클릭합니다.

 

 

 

 

 

서비스역활에는 위에서 codeDeploy IAM 역활 설정해준것이 자동으로 매칭이 될 것입니다.

 

 

 

 

 

환경 구성도 서비스역활과 동일하게 자동으로 ec2를 맵핑해줍니다.

 

 

 

 

 

배포설정은 아래와 설정해주고 로드밸런싱 활성화는 체크를 풀어주세요.

 

여기까지 잘 따라 오셨습니다. 이제 마지막 단계이니 조금만 더 집중해주세요.

 

 

 

 

 

 

.yml 수정 및 추가 생성

 

workflows안에 있는 yml 수정하기

on: 과 job 사이에 아래 코드를 입력해주세요.

env:
  PROJECT_NAME: youAndI             
  BUCKET_NAME: whitewise
  CODE_DEPLOY_APP_NAME: codeDeployTest
  DEPLOYMENT_GROUP_NAME: codeDeploy_ci_cd
  
  
  #PROJECT_NAME - S3 버킷의 경로 name이며 보통 프로젝트 name을 적습니다.
  #BUCKET_NAME - bucket의 name을 적어주세요.
  #CODE_DEPLOY_APP_NAME - codeDeploy명을 적어주세요.
  #DEPLOYMENT_GROUP_NAME - codeDeploy 배포 그룹명을 적어주세요.

전에 테스트당시 캡쳐한거라 deploy명과 배포그룹명이 다릅니다 위치 참고용으로 확인해주세요

CodeDeploy명과 배포그룹명 확인법

 

 

 

 

 

steps 하위에 name중 Build with Gradle 밑에 다음 step을 추가해주세요.

     # zip파일로 변환
    - name: Make Zip File                
      run: zip -qq -r ./$GITHUB_SHA.zip .
      shell: bash
   
    # AWS 권한 
    - 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

    # AWS S3에 zip파일 업로드
    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip

    # AWS codeDeploy 배포 생성
    - 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

 

 

전체적인  .yml 입니다.

name: Java CI with Gradle

on:
  push:
    branches: [ "master" ]

env:
  PROJECT_NAME: youAndI
  BUCKET_NAME: whitewise
  CODE_DEPLOY_APP_NAME: codeDeployTest
  DEPLOYMENT_GROUP_NAME: codeDeploy_ci_cd

jobs:
  build:

    runs-on: ubuntu-18.04

    steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
        
    # 빌드를 하는 과정입니다.
    - name: Grant execute permission for gradlew
      run: chmod +x ./gradlew
      shell: bash
      
    - name: Build with Gradle
      run: ./gradlew build
      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

 

 

 

 

 

appspec.yml 생성

최상단 root에서 appspec.yml를 생성해 아래와 같이 설정해주세요. 아래코드는 변경할 필요없습니다.

version: 0.0
os: linux
files:
  - source: /               # codeDeploy agent가 다운 받은 코드에서 어느 경로를 다운받을지 결정함 (/ -> 전체 파일을 받음)
    destination: /home/ec2-user/whitewise   # ec2서버에서 어는 경로에 해당 코드를 저장할지 결정
permissions:
  - object: /home/ec2-user/whitewise/
    owner: root
    group: root
hooks:
  AfterInstall:
    - location: scripts/deploy.sh  # scripts 폴더안에서 deploy.sh를 실행하라는 이벤트
      timeout: 60
      runas: root

 

 

 

 

 

 

배포용 쉘 스크립트 작성

최상상 root에서 scripts 라는 폴더를 만들고 deploy.sh를 아래와 같이 생성합니다.

REPOSITORY=/home/ec2-user/whitewise
cd $REPOSITORY

APP_NAME=YouAndI-0.0.1-SNAPSHOT   #빌드되는 jar파일의 명을 입력해주세요.  
JAR_NAME=$(ls $REPOSITORY/build/libs/ | grep '.jar' | tail -n 1)
JAR_PATH=$REPOSITORY/build/libs/$JAR_NAME

CURRENT_PID=$(pgrep -f $APP_NAME)

# 실행되고 있다면 종료시키고 아니라면 스킵합니다.
if [ -z $CURRENT_PID ]
then
  echo "> 종료할것 없음."
else
  echo "> kill -9 $CURRENT_PID"
  kill -15 $CURRENT_PID
  sleep 5
fi


# jar파일을 실행시키는 명령어
echo "> $JAR_PATH 배포"
nohup java -jar $JAR_PATH > /dev/null 2> /dev/null < /dev/null &

 

 

 

 

 

jar파일명은 보통 빌드를 하면 build/ 안에서 확인할 수 있습니다.

 

 

 

 

 

전체적인 경로나 위치는 이렇게 됩니다.

 

 

 

 

 

 

 

확인해보기

설정은 이제 다 되었습니다. 푸시를 해서 확인해봅시다.
Actions에서는 잘 build가 되는 것을 확인할 수 있습니다. 안된다면 스텝을 펼쳐보면 이유를 알 수 있습니다.

 

 

 

 

codeDeploy에서도 상태가 성공인 것을 확인 할 수 있습니다.

 

만약 실패했다면 ec2 서버에 아래 명령어로 로그를 확인할 수 있습니다.

vim /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log

 

배포실패경험 자료들

 

[AWS] codedeploy log 확인

aws codedeploy로 배포시에 상세로그를 확인할수 있다. 배포가 성공했더라도 서버가 실행이 안되는 경우 로그에서 스크립트에서 발생한 오류내역을 살펴봐야한다. vim /opt/codedeploy-agent/deployment-root/de

samtao.tistory.com

 

2022.01.21 CodeDeploy 배포 오류 해결

갑자기 코드디플로이 배포 실패가 나기 시작했다. 배포 설정을 변경한 사람도, 서버에 직접 접속해 작업한 사람도 없다. 어느 순간부터 배포가 안되면서 AWS CodeDeploy 콘솔에서 아래와 같은 오류

prohannah.tistory.com

 

[AWS CodeDeploy] AWS CodeDeploy 오류시 확인 후 해결하기

[AWS CodeDeploy] AWS CodeDeploy 오류시 확인 후 해결하기 Spring Boot 프로젝트를 깃허브 Actions과 AWS S3, EC2를 이용해 CI/CD를 구현했는데 Postman 테스트가 안되는거라~ 그래서 GitHub Actions부터..

be-developer.tistory.com

 

 

 

 

이제는 http://ec2IP:포트번호/hello 로 처음만들었던 API를 확인할 수 있습니다.

 

 

 

 

 

 

 

참고한 자료

 

CI/CD 파이프라인: 개념, 방법, 장점, 구현 과정

CI/CD 파이프라인은 새 버전의 소프트웨어를 제공하기 위해 수행해야 할 일련의 단계입니다.

www.redhat.com

 

CICD - Codedeploy란? (Codedeploy를 이용한 자동배포(CD) 환경 구축하기)

AWs CodeDeploy란 이번 포스팅에서는 AWS의 배포서비스인 Code Deploy에 대해서 알아보도록 하겠습니다. Code deploy란? CodeDeploy는 SourceCode를 운영환경에 자동 배포하는 역할을 수행하는 AWS Service입..

galid1.tistory.com

 

 

 

[git] GitHub Actions 사용법 [1] - 개념과 기본 사용법  - 보러가기
[git] GitHub Actions 사용법 [2] - codeDeploy, S3를 이용한 CI / CD 파이프라인 구축해   - 현재

 

 

복사했습니다!