WIL/웹 개발

2024년 10월 1일 이후 Github Action과 AWS Beanstalk를 사용한 CI/CD

아크리미츠 2024. 10. 29. 17:16

CI/CD

1. CI (지속적 통합, Continuous Integration)

  • 지속적 통합은 개발자들이 코드를 자주 병합하고, 각 병합 시마다 자동으로 빌드와 테스트를 수행하는 것을 뜻한다.
  • 코드 변경 시 자동으로 오류를 발견할 수 있기 때문에 코드의 품질을 높이고, 개발과정에서 문제가 생겼을 때 빠르게 수정할 수 있도록 도와준다.
  • CI 도구로는 Jenkins, GitHub Actions, GitLab CI, CircleCI 등이 있다.

2. CD (지속적 전달, Continuous Delivery)

  • 지속적 전달은 CI 단계를 거쳐 코드가 테스트를 통과하면, 이를 배포 준비 상태로 자동화하여 유지하는 것을 의미한다.
  • 배포는 수동으로 수행할 수 있지만, 준비된 최신 버전의 코드가 언제든 프로덕션 환경으로 전달될 수 있도록 한다.

3. CD (지속적 배포, Continuous Deployment)

  • 지속적 배포는 지속적 전달의 한 단계 확장된 형태로, 테스트를 통과한 코드를 자동으로 프로덕션 환경에 배포하는 것을 뜻한다.
  • 이를 통해 개발자는 배포 과정에 신경 쓰지 않고도 최신 기능을 사용자에게 빠르게 제공할 수 있다.

1. Beanstalk 생성

  • EC2, Code Deploy를 통해 배포환경을 구성하고, 로드밸런서 연결, 오토스케일링 그룹을 생성 연결하는 모든 행위가 Beanstalk에서는 자동으로 이루어진다.
  • 개발자는 코드를 업로드하기만 하면 Elastic Beanstalk가 프로비저닝, 로드 밸런싱, Auto Scaling, 애플리케이션 상태 모니터링, 배포를 자동으로 처리한다.

 

먼저, 애플리케이션 이름과 환경 이름을 정한다.

 

그리고 플랫폼을 정해주는데, 나는 Spring Boot 3를 학습중이기 때문에 그에 맞는 플랫폼과 브랜치를 정했다.

 

 

그 후 서비스 엑세스 구성을 정해주는 데, 3개 다 모두 지정해줘야한다. 필자의 경우에는 정글에서 사용하던 키페어가 있기 때문에 이를 그대로 사용했고, aws-elasticbeanstalk-service-role 서비스 역할과 aws-elasticbeanstalk-ec2-role 인스턴스 프로파일을 적용했다.

 

프로파일 만들기 : TBD

 

 

그 후 VPC나 데이터베이스는 따로 건들지 않고 업데이트, 모니터링 및 로깅 구성에서 환경 변수를 지정할 수 있다. 여기에서 PORT를 추가해주자.

 

환경을 구동해 봤는데, 2024년 10월 1일부로 바뀐 것이 있어 배포가 되지 않는 문제가 생겼다.

 

Beanstalk의 로그를 살펴보면

Creating Auto Scaling launch configuration failed Reason: Resource handler returned message: "The Launch Configuration creation operation is not available in your account. Use launch templates to create configuration templates for your Auto Scaling groups. (Service: AutoScaling, Status Code: 400, Request ID: 52f3fac6-0adb-4d31-a01b-3bc09a91be69)" (RequestToken: dbc74187-1261-f08f-4b23-9347135b1bdc, HandlerErrorCode: GeneralServiceException)
Stack named 'awseb-e-izzvqbfktk-stack' aborted operation. Current state: 'CREATE_FAILED' Reason: The following resource(s) failed to create: [AWSEBAutoScalingLaunchConfiguration].
Service:AmazonCloudFormation, Message:Resource AWSEBAutoScalingGroup does not exist for stack awseb-e-izzvqbfktk-stack

이런식으로 뜨게 되는데 ChatGPT에 물어보니

이 오류는 awseb-e-izzvqbfktk-stack 스택의 AWSEBAutoScalingLaunchConfiguration 리소스를 생성하지 못해서 스택이 CREATE_FAILED 상태로 멈춘 상황입니다. AWS에서는 기존 Launch Configuration 대신 Launch Template 사용을 권장하고 있기 때문에 이를 해결하려면 Launch Configuration을 제거하고 Launch Template으로 대체해야 합니다.

 

라고만 알려준다. 그래서 이를 해결하기 위해 CloudFormation으로 들어가 봤으나 내가 해결할 수 있는 것은 없어서 구글링 해보았다. 그런데 생각보다 아주 간단한 방법으로 해결할 수 있었다.

 

 

루트 볼륨을 gp3으로 설정하라는 것.

 

 

이렇게 설정하고 환경을 동작해 보았다.

 

 

드디어 성공!

 

2. Github Action Script 작성

루트 디렉토리에 .github/workflows 디렉토리를 생성하고 그안에 cicd.yml 작성

 

name: CI/CD

on:
  push:
    branches: [ main ]
    paths-ignore:
      - 'README.md'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - uses: actions/setup-java@v3
        with:
          distribution: 'corretto'
          java-version: '21'

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew clean build

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

      - name: Set artifact
        run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV

      - 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: Beanstalk Deploy
        uses: einaregilsson/beanstalk-deploy@v20
        with:
          aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          application_name: ShoppingMall
          environment_name: test-env
          version_label: github-action-${{ steps.current-time.outputs.formattedTime }}
          region: ap-northeast-2
          deployment_package: ./build/libs/${{env.artifact}}

      - name: Update Elastic Beanstalk Environment Variables
        run: |
          aws elasticbeanstalk update-environment \
            --application-name ShoppingMall \
            --environment-name test-env \
            --option-settings Namespace=aws:elasticbeanstalk:application:environment,OptionName=DB_URL,Value=${{ secrets.DB_URL }} \
            Namespace=aws:elasticbeanstalk:application:environment,OptionName=DB_ID,Value=${{ secrets.DB_ID }} \
            Namespace=aws:elasticbeanstalk:application:environment,OptionName=DB_PW,Value=${{ secrets.DB_PW }} \
            Namespace=aws:elasticbeanstalk:application:environment,OptionName=S3_ACCESS_KEY,Value=${{ secrets.S3_ACCESS_KEY }} \
            Namespace=aws:elasticbeanstalk:application:environment,OptionName=S3_SECRET_KEY,Value=${{ secrets.S3_SECRET_KEY }} \
            Namespace=aws:elasticbeanstalk:application:environment,OptionName=S3_BUCKET,Value=${{ secrets.S3_BUCKET }} \
            Namespace=aws:elasticbeanstalk:application:environment,OptionName=JWT_SECRET_KEY,Value=${{ secrets.JWT_SECRET_KEY }}

 

  • secrets는 깃허브 액션에서 가져오는 비밀값인데, 이도 설정해줘야 한다.

3. Github 환경키/비밀키 등록

 

Repository Setting에서 등록할 수 있다.

 

4. 배포

 

이제 Repo에 push할 때 깃허브 액션이 자동으로 빌드하고, 성공하면 빈스토크에 배포하게 된다.