CI/CD

sunnny·2024년 1월 16일
0

AWS

목록 보기
1/1
post-thumbnail

CI/CD 란?

애플리케이션 개발 단계부터 배포 때까지 이 모든 단계들을 자동화를 통해 조금 더 효율적이고 빠르게 사용자에게 빈번이 배포할 수 있도록 만드는 것을 말합니다.

CI/CD 파이프라인

CI (Continuous Integration) : 지속적 통합

git에 주기적으로 빈번하게 merge가 되면 자동으로 build와 test가 수행되어 안정적인 배포 파일을 만드는 과정을 말합니다.

CI의 규칙
  1. 모든 소스코드가 살아있고 (현재 실행되고) 누구든 현재의 소스에 접근할 수 잇는 단일 지점을 유지할 것
  2. 빌드 프로세스를 자동화해서 누구든 소스로부터 시스템을 빌드하는 단일 명령어를 사용할 수 있게 할 것
  3. 테스팅을 자동화해서 단일 명령어로 언제든지 시스템에 대한 건전한 테스트 수트를 실행할 수 있게 할 것
  4. 누구나 현재 실행 파일을 얻으면 지금까지 가장 완전한 실행 파일을 얻었다는 확신을 하게 할 것
  1. 코드 변경사항을 주기적으로 빈번하게 merge 해야한다. (최대한 작은 단위로 나누어서 개발, 통합하는 것이 중요하다.)
  2. 통합을 위한 단계인 build, test, merge의 자동화 (by. 스크립트)

CI의 장점

빈번한 merge로 인해 conflict가 줄어들어서 개발 생산성이 향상될 수 있습니다.
또한 merge를 할 때마다 build와 test가 자동으로 수행되므로 문제가 발생하면 빠르게 발견하고 수정할 수 있습니다.
테스트가 필수적이어서 코드의 퀄리티가 향상됩니다.

CD (Continuous Delivery / Deployment) : 지속적인 제공 / 배포

Continuous Delivery는 CI 과정을 거친 소스코드를 레포지토리에 자동으로 반영하는 단계입니다.

Continuous Deployment는 애플리케이션을 배포하는 작업을 자동화하여, 변경 사항을 적용한 후 짧은 시간 내에 사용자가 새로운 버전의 애플리케이션을 사용할 수 있도록 합니다.

GitHub Actions의 workflow로 보는 CI/CD 과정

GitHub Actions를 사용하여 CI를 구현하였고, AWS의 S3와 CodeDeploy, Nginx를 사용하여 CD를 구현하였습니다.

Github Actions를 사용하기 위해, 아래 빨간색으로 표시해놓은 버튼을 클릭하여 빌드 관련 Workflow를 프로젝트의 workflow.yml 파일에 작성합니다.

env:
  S3_BUCKET_NAME: springboot-springboot-build
  PROJECT_NAME: Springboot-AWS-Webservice
  CODE_DEPLOY_APP_NAME: springboot-aws-webservice                   
  CODE_DEPLOY_GROUP_NAME: springboot-aws-webservice-group
  • env: : 자주 사용되는 값을 환경변수로 지정합니다. (이름:값)

name: Springboot-AWS-Webservice

on:
  push:
    branches: 'main'
  • name: : GitHub Actions에서 보여질 workflow의 이름을 적습니다. 저는 프로젝트의 이름과 동일하게 적었습니다.
  • on: : 이벤트를 지정합니다. 저는 main 브랜치로 push될 때마다 job이 수행되도록 하였습니다.
    (이벤트 ex. main 브랜치로 머지, 커밋을 푸쉬, 누군가 이슈를 열 때 마다 등등)

jobs:
  build:
    runs-on: ubuntu-latest 
    permissions:
      contents: read
      packages: write
  • jobs: build: : 지정한 이벤트가 발생했을 때 수행할 일들(workflows)을 지정해줍니다. 저는 build를 지정해 주었습니다.
    지정한 이벤트가 발생하면 workflow.yml에 정의된 각각의 job들은 병렬적으로 수행됩니다.
    (job ex. build, test, slack으로 알림 설정 등등)
  • runs-on: : 해당 GitHub Actions 스크립트가 작동할 OS 환경을 지정합니다.
  • permissions: : 파일 및 패키지에 대한 권한을 설정합니다.
  • steps: : 순차적으로 수행되어야 하는 job들의 step을 명시해줄 수 있습니다.
    이름(name)과 실행내용을 나열해서 작성한다.
    왼쪽의 체크표시가 붙은 채로 나열된 것들이 각 step들의 이름입니다.

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

    - name: Set up JDK 1.8
      uses: actions/setup-java@v3 
      with:
        java-version: '8'
        distribution: 'temurin'
  1. 프로젝트의 코드를 ckeckout 합니다.
    uses: actions/checkout@v3 : 공개적으로 open된 액션을 사용하였습니다.

  2. GiHub Action이 실행될 OS에 Java를 설치합니다. (프로젝트의 자바 버전과 일치해야 합니다.)


    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
      shell: bash
      
    - name: Build with Gradle
      run: ./gradlew clean -x test build 
      shell: bash
  1. gradle wrapper를 실행할 수 있도록 실행 권한 (+x)을 줍니다.
    ./gradlew를 실행하기 위함입니다.
  2. gradle wrapper를 통해 해당 프로젝트를 build 합니다.

    - name: Get current time
      uses: 1466587594/get-current-time@v2 
      id: current-time
      with:
        format: YYYY-MM-DDTHH-mm-ss
        utcOffset: "+09:00"

    - name: Show Current Time
      run: echo "CurrentTime=${{steps.current-time.outputs.formattedTime}}" 
      shell: bash
  1. action의 기준이 UTC이므로 한국시간인 KST로 진행 하기 위해 offset에 +09:00 를 해줍니다.
  2. 현재 시간을 출력합니다.

    - name: Generate deployment package
      run: |
        mkdir -p before-deploy
        cp scripts/*.sh before-deploy/  # jar파일을 실행시킬 수 있는 deploy.sh파일
        cp appspec.yml before-deploy/
        cp build/libs/*.jar before-deploy/
        cd before-deploy && zip -r before-deploy *
        cd ../ && mkdir -p deploy
        mv before-deploy/before-deploy.zip deploy/$PROJECT_NAME.zip
      shell: bash
   	
    - name: Make zip file
      run: zip -r ./$PROJECT_NAME.zip .         
      shell: bash
  1. 스크립트 및 JAR 파일을 포함하고 있는 배포 패키지({PROJECT_NAME}.zip)를 생성합니다.
    • 스크립트, yml, jar 파일들을 before-deploy로 복사한 뒤에
    • before-deploy 디렉토리 안에 있는 모든 파일과 서브디렉토리를 압축하여 before-deploy.zip라는 하나의 압축 파일을 생성합니다.
    • 해당 압축 파일을 deploy로 이동하고, $PROJECT_NAME.zip로 이름을 변경합니다.
  2. 프로젝트 전체를 압축하여 zip 파일 생성
    • deploy 폴더를 $PROJECT_NAME.zip로 압축합니다.

    - 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
  1. AWS 인증 정보 설정
    • with: 에 지정된 키 값을 사용하여 AWS에 접속을 진행합니다.

    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./deploy/$PROJECT_NAME.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$PROJECT_NAME.zip  
      
    - name: Code Deploy
      run: aws deploy create-deployment --application-name $CODE_DEPLOY_APP_NAME --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name $CODE_DEPLOY_GROUP_NAME --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$PROJECT_NAME.zip   
  1. 생성된 배포 패키지를 S3에 업로드
    • deploy폴더에 있는 $PROJECT_NAME.zip 파일을 복사하여 S3에 저장합니다.
    • 해당 zip 폴더에는 배포 자동화를 위한 스크립트, appspec.yml, jar 파일들이 들어있습니다.
  2. AWS CodeDeploy를 사용하여 S3에 있는 파일 배포
    • CodeDeploy 애플리케이션의 배포 그룹에 새로운 배포를 생성하며, 지정된 S3 버킷의 압축 파일을 가져와서 해당 배포를 실행합니다.

Tool 소개

  • github actions

    • 이벤트(push) 발생 시 자동 build와 test를 담당
  • AWS S3

    • AWS에서 제공하는 일종의 파일 서버
    • 배포할 Zip 파일이 모여있는 장소
    • CodeDeploy에는 저장 기능이 없어서 Github Actions에서 빌드한 결과물을 받아서 CodeDeploy가 가져갈 수 있도록 보관하는 공간
  • AWS CodeDeploy

    • AWS의 배포 서비스. 실제 배포를 담당한다.
    • 오토 스케일링 그룹 배포, 블루 그린 배포, 롤링 배포, EC2 단독 배포 등 많은 기능을 지원한다.

👏🏻 GitHub Actions와 S3 연동하기

GitHub Actions에서 S3로 Jar 파일과 스크립트 파일 등을 전달하기 위해서는 둘을 연동해야 한다!

  1. AWS Key 발급
    : IAM - 사용자 추가AmazonS3FullAccess, AWSCodeDeployFullAccess 권한을 추가하여 사용자를 생성한다. (엑세스 키 & 비밀 엑세스 키 꼭 저장, 기록해두기!!!)

  2. Github Actions에 AWS Key 등록
    : 레포 settings - Secrets and variable - Actions - New repository secret

       AWS_ACCESS_KEY_ID : {IAM 엑세스 키 (ID)}
       AWS_SECRET_ACCESS_KEY : {IAM 비밀 엑세스 키}

👏🏻 S3와 CodeDeploy 연동하기

S3에서 CodeDeploy로 배포 패키지({PROJECT_NAME}.zip)를 전달하기 위해서는 둘을 연동해야 한다!

  1. IAM - 역할 생성 → EC2, AmazonEC2RoleforAWSCodeDeploy 정책 선택

  2. 인스턴스에 IAM 역할을 적용 → 인스턴스 재부팅

IAM 사용자 🆚 역할

  • 사용자 : AWS 서비스 외에 사용할 수 있는 권한 (ex. 로컬 PC, IDC서버 등)
    → GitHub Actions이 AWS 외부 서비스이므로 사용자를 사용해야 한다.
  • 역할 : AWS 서비스에만 할당할 수 있는 권한 (ex. EC2, CodeDeploy, SQS 등)

참고

0개의 댓글