ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • GitHub-Actions로 CI/CD 구축하기 (1)
    Lesson-Learned/tech 2023. 12. 17. 17:51
    GitHub-Actions로 CI/CD 구축하기 (1) (AWS S3 + AWS CodeDeploy + Spring Boot)

     

    안녕하세요, MADII의 Server 개발자 하노입니다 🍀

    오늘은 마디의 서버 아키텍처CI/CD 과정을 소개하려고 합니다!

    잘 정리되어 있는 레퍼런스를 그저 따라하기보다는, 기술 하나하나 사용하는 명확한 이유를 갖고 도입하고자 했습니다.


    Server Architecture

    MADII의 Server Architecture

    개발 환경

    • AWS EC2 Ubuntu
    • AWS S3
    • AWS Code Deploy
    • Github Actions
    • Spring Boot
    • Java 17
    • Gradle
    1. IntelliJ에서 코드 작성 후 Giuhub로 push
    2. Github에서 조건 만족할 경우 Github Actions 실행
    3. Github Actions는 yml 스크립트대로 동작
      1. 빌드된 프로젝트 zip 파일을 AWS S3에 업로드
      2. AWS Code Deploy에 배포 요청
    4. AWS Code Deploy는 S3로부터 zip 파일을 받아 배포 진행

     

    🤔 Architecture 설계를 이렇게 한 이유는 뭔가요?

    프로젝트를 새로 이어가면서 서버부터 다시 구축하게 되었는데요, 가장 큰 이유는 ‘무중단 배포’를 위한 서버를 구축하기 위해서입니다. 또한 무중단 배포와 AWS S3와 Code Deploy로 배포하는 경험이 없었기에, 이번 기회로 새로운 기술에 도전하고 공부하고자 하는 이유도 있었습니다.

     

    무중단 블루-그린 배포는 애플리케이션 업데이트 시 서비스 중단 없이 부드러운 전환을 가능하게 하는 배포 전략입니다. 지속적인 서비스를 제공함으로써 유저의 불편함을 최소화합니다.

     

    AWS S3는 프로젝트 버전 관리 기능에 용이하여 변경 사항 추적 및 롤백에 유용합니다. AWS Code Deploy와의 통합을 통해 CI/CD 구축 및 자동화할 수 있으며, IAM을 통한 세밀한 접근 제어, 버킷 정책, 데이터 암호화 등을 통해 보안을 강화할 수 있습니다.

     

    AWS Code Deploy를 사용하여 여러 대의 EC2 인스턴스에 동일한 애플리케이션 버전을 배포함으로써 일관성을 유지할 수 있으며, 배포 자동화가 용이하므로 확장성을 간편하게 관리할 수 있습니다.

    인스턴스 한 대씩 순차적으로 업데이트할 수 있어, 한 인스턴스가 업데이트되는 동안 다른 인스턴스가 트래픽을 처리할 수 있습니다. 이는 서비스 중단을 방지하고 무중단 배포를 가능하게 합니다. 또한, Code Deploy는 AWS의 다른 서비스와 통합이 잘 되어 있어 AWS의 ALB와 연동해 보다 강력한 인프라를 구축할 수 있습니다. 현재는 단일 인스턴스만 운영 중이지만, 향후 확장이 필요할 때 EC2 인스턴스의 수를 늘리고 ALB를 사용하여 여러 인스턴스를 운영할 예정입니다.

     

    Nginx는 트래픽 관리와 무중단 배포를 지원합니다. WAS로 들어오는 트래픽을 관리하고 라우팅합니다. 현재 실행 중인 WAS의 포트, 대상 WAS의 포트를 구분하고 새 애플리케이션 인스턴스를 실행 중이 아닌 포트에서 실행합니다. 이후 새 포트로 트래픽을 전환하여, 유저에게 서비스 중단 없이 새 버전의 애플리케이션을 제공합니다.

     

    본격적으로 CI/CD 구축 과정을 적어보려고 하는데요, 저는 우선 유중단 배포부터 확인한 후 Nginx를 활용한 무중단 배포로 차근차근 나아갔습니다. (유중단 배포 방식이라는 말은 쓰이지 않지만, 무중단 배포와 상대적인 의미로 사용하겠습니다!)

     

    CI/CD 구축 과정 1) 유중단 배포부터 확인하기

    1. AWS EC2/S3/Code Deploy 생성 및 설정

    [레퍼런스 1] 1, 2, 3편을 차례대로 따라가 AWS EC2/S3/Code Deploy 생성 및 설정을 하였습니다. 콘솔 로그인 URL, 사용자 이름, 콘솔 암호는 기록해 두었습니다. 따로 생성한 액세스 키, 비밀 액세스 키도 함께 기록하고 .csv 파일을 다운로드해 저장했습니다.

     

    2. Spring Boot Application 생성

    https://start.spring.io/ 에서 개발 환경에 맞는 프로젝트를 생성합니다. 마디는 Spring Boot ‘3.1.5’ version과 Java 17을 사용했습니다.

     

    3. Github-Actions Secret Keys 등록

    기록해둔 값으로 위와 같이 3가지 Key를 설정합니다.

     

    4. AWS Code Deploy Agent 설치

    AWS Code Deploy Agent는 AWS Code Deploy 서비스가 인스턴스에 애플리케이션을 배포하는 데 필요한 소프트웨어입니다. 주로 EC2 인스턴스에서 실행되며, AWS Code Deploy 서비스와 해당 인스턴스 간의 통신을 담당합니다.

    Agent가 배포 명령을 수신하고, 애플리케이션을 해당 인스턴스에 자동으로 설치하고 구성합니다. 배포 중에 실행해야 할 사용자 정의 스크립트나 명령어도 처리합니다.

    다음 명령어를 입력하고 결과를 확인합니다.

    # 패키지 리스트 업데이트
    sudo apt update
    
    # OpenJDK 17 설치
    sudo apt install -y openjdk-17-jdk
    
    # Java 버전 확인
    java -version

    java version 확인

    # 패키지 매니저 업데이트 및 ruby, wget 설치
    sudo apt update
    sudo apt install -y ruby wget
    
    # 서울 리전에 있는 CodeDeploy 리소스 키트 파일 다운로드
    cd /home/ubuntu
    wget <https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install>
    
    # 설치 파일에 실행 권한 부여
    chmod +x ./install
    
    # 설치 진행
    sudo ./install auto
    
    # codedeploy-agent 재시작
    sudo systemctl restart codedeploy-agent
    
    # Agent 상태 확인
    sudo systemctl status codedeploy-agent
    

    Agent 상태 확인

     

    5. appspec.yml 작성

    version: 0.0
    os: linux
    files:
      - source: /
        destination: /home/ubuntu/my-app/ # 파일들을 EC2 인스턴스에서 어디에 배포할지를 나타내는 경로
        overwrite: yes
    
    permissions:
      - object: /
        pattern: "**"
        owner: ubuntu
        group: ubuntu
    

     

    6. main.yml 작성

    name: 8attery-SeeSaw-V2
    
    on:
      push:
        branches:
          - main
      workflow_dispatch:
    
    env:
      S3_BUCKET_NAME: 8atterybucket
      PROJECT_NAME: seesaw-app
      
    jobs:
      build:
        runs-on: ubuntu-latest
    
        steps:
          - name: Checkout
            uses: actions/checkout@v2
    
          - name: Set up JDK 17
            uses: actions/setup-java@v1
            with:
              java-version: 17
    
          - 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 -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: ${{ secrets.AWS_REGION }}
    
          - name: Upload to S3
            run: aws s3 cp --region ap-northeast-2 ./$GITHUB_SHA.zip s3://$S3_BUCKET_NAME/$PROJECT_NAME/$GITHUB_SHA.zip
    
          - name: Code Deploy
            run: aws deploy create-deployment --application-name seesaw-code-deploy --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name seesaw-server --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=$PROJECT_NAME/$GITHUB_SHA.zip
    
    • application-name : 미리 생성한 CodeDeploy 애플리케이션 이름
    • deployment-group-name : 미리 생성한 배포 그룹 이름

     

    유중단 배포 확인 → 성공

    zip 파일이 성공적으로 올라가고

     

    배포가 성공했습니다!
    생성하고자 했던 위치에 배포 프로젝트 파일이 생성된 것을 확인할 수 있습니다.

     

    이제 유중단 배포는 성공했으니, 다음 편에서는 Nginx를 활용하여 무중단 배포 과정을 진행해 보겠습니다!

    읽어 주셔서 감사합니다 ❤️

Designed by Tistory.