12.2.3 GitHub Actios을 이용한 CD 구축

SummerToday·2024년 6월 23일
0
post-thumbnail
post-custom-banner

build.gradle 수정

  • 빌드 시 플레인 아카이브(plain archive) 파일은 생성되지 않도록 설정

    프로젝트 빌드 시 jar 파일이 2개가 생기는데, 이 중 pain이 붙은 jar 파일은 프로젝트 실행 시 필요한 의존성들이 포함되지 않은 순수 소스 코드의 클래스 파일과 리소스 파일만 포함되는 파일이다. 플레인 아카이브 파일로는 서비스 실행이 안되므로, 효율적인 배포를 위해 빌드 시 일반 jar 파일만 생성되도록 build.gradle을 수정해준다.

    # build.gradle
    
    ~생략~
    
    jar {
    	enabled = false
    }

깃허브 액션 스크립트 작성, CD

ci.yml 파일을 cicd.yml로 변경한 후 다음과 같이 코드를 추가한다.

# cicd.yml

~ 기존 ci.yml 내용 생략 ~

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

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

      - name: Beanstalk Deploy # C
        uses: einaregilsson/beanstalk-deploy@v20
        with:
          aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          application_name: Blog
          environment_name: Blog-env
          version_label: github-action-${{steps.current-time.outputs.formattedTime}}
          region: ap-northeast-2
          deployment_package: ./build/libs/${{env.artifact}}
  • A

    • uses
      josStorer/get-current-time@v2.0.2 - josStorer가 제공하는 v2.0.2 버전의 get-current-time 액션을 사용한다.
      즉, josStorer/get-current-time 플러그인을 사용해 현재 시간을 불러온다. 불러온 시간은 배포 버전을 지정할 때 사용된다.

      • josStorer/get-current-time 플러그인
        josStorer/get-current-time는 GitHub Actions에서 사용되는 시간 관련 플러그이다. 해당 플러그인은 현재 시간을 다양한 형식으로 출력할 수 있도록 하는 플러그인이다. 이를 통해 워크플로우에서 타임스탬프를 포함한 다양한 작업을 자동화할 수 있게 된다.
    • id: current-time
      해당 단계의 식별자이다. 이후 단계에서 해당 식별자를 사용하여 해당 단계의 출력을 참조할 수 있다.

    • with

      • format: YYYY-MM-DDTHH-mm-ss
        시간을 출력할 형식이다. 예를 들어, 2024-06-23T14-30-00와 같은 형식으로 출력된다.

      • utcOffset: "+09:00"
        시간대 오프셋을 설정한다. 해당 단계에서는 UTC+9 시간대를 사용한다.


  • B
    • run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV
      ls ./build/libs 명령어로 ./build/libs 디렉토리 내의 파일 목록을 나열한다. 해당 파일(빌드 이후 생성된 일반 jar 파일) artifact 변수에 저장하고, 이를 GitHub Actions의 환경 변수 파일 $GITHUB_ENV에 추가한다. artifact 변수는 이후 단계에서 참조할 수 있다.

  • C

    • uses: einaregilsson/beanstalk-deploy@v20
      AWS Elastic Beanstalk에 배포하기 위해 einaregilsson가 제공하는 v20 버전의 beanstalk-deploy 액션을 사용한다.

    • with

      • aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS 접근 키를 GitHub Secrets에서 가져와 사용한다.

      • aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        AWS 비밀 접근 키를 GitHub Secrets에서 가져와 사용한다.

      • application_name: spring-boot-developer
        AWS Elastic Beanstalk에 배포할 애플리케이션 이름이다. AWS Elastic Beanstalk의 애플리케이션 이름과 동일하게 맞춰주어야 한다.

      • environment_name: SpringBootDeveloper-env
        AWS Elastic Beanstalk 환경 이름이다. AWS Elastic Beanstalk의 환경 이름과 동일하게 맞춰주어야 한다.

      • version_label: github-action-${{steps.current-time.outputs.formattedTime}}
        추후 유지 관리를 위해 배포할 애플리케이션 버전의 라벨을 설정한다. 여기서는 앞서 얻은 현재 시간을 포함하여 고유하게 설정한다.

      • region: ap-northeast-2
        배포할 AWS 리전이다.

      • deployment_package: ./build/libs/${{env.artifact}}
        앞서 설정한 artifact 변수를 사용하여 배포할 패키지 파일 경로를 지정한다.


AWS 설정

AWS IAM을 이용하여 깃허브 액션이 AWS 리소스를 사용할 수 있도록 권한을 부여해줘야 한다.

  1. AWS IAM 서비스 접속 -> [사용자] 클릭 -> [사용자 추가] 클릭


  1. [다음]을 클릭하여 나온 화면은 다음과 같이 설정한다. AdministratorAccess 권한을 사용해준다.은 권한의 범위가 너무 넓기 때문에 꼭 필요한 권들만 허용을 해주는 것이 좋지만, 상용 프로그램이 아니기 때문에 편의를 위해 AdministratorAccess 권한을 사용해준다.


  1. [다음]을 클릭하고 [사용자 생성]을 클릭해준다.


  1. 생성한 사용자를 클릭하여 보안 자격증명 탭에 들어가 엑세스 키를 생성한다.


  1. 아래 화면은 엑세스 키를 생성할 때 한번만 보여지므로 넘기지말고, csv 파일을 다운 받아 보관한다.


GitHub Actions 설정

해당 리포지토리에 들어가 settings -> Secrets and variables -> Actions에 들어가 [New repository secret] 버튼을 눌러 시크릿 키를 등록해준다.

AWS_ACCESS_KEY_ID와 AWS_SECRET_ACCESS_KEY 값을 각각 위에서 설정한 AWS의 액세스 키와 비밀 액세스 키로 각각 설정해준다.


application.yml 수정

application.yml 파일에 적혀 있던 jwt의 민감한 정보들을 깃허브 액션 시크릿 키로 등록하여 정보들이 노출되지 않도록 수정하였다.

spring:
  jpa:
    show-sql: true
    properties:
      hibernate:
        format_sql: true
    defer-datasource-initialization: true
  # AWS RDS 사용으로 인한 주석화.
  #datasource:
    #url: jdbc:h2:mem:testdb
    #username: sa 
  h2:
    console:
      enabled: true
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: ${OAUTH2_CLIENT_ID}
            client-secret: ${OAUTH2_CLIENT_SECRET}
            scope:
              - email
              - profile

jwt:
  issuer: ${JWT_ISSURE}
  secret_key: ${JWT_SECRET_KEY}

오류 발생

Beanstalk Deploy 단계에서 오류가 발생하였고 자세한 오류 내용은 아래와 같다.

Run einaregilsson/beanstalk-deploy@v20
Beanstalk-Deploy: GitHub Action for deploying to Elastic Beanstalk.
https://github.com/einaregilsson/beanstalk-deploy

 ***** Input parameters were: ***** 
         Application: Blog
         Environment: Blog-env
       Version Label: github-action-2024-06-23T16-30-57
 Version description: 
          AWS Region: ap-northeast-2
                File: ./build/libs/Blog-0.0.1-SNAPSHOT.jar
Existing bucket Name: null
      AWS Access Key: 20 characters long, starts with A
      AWS Secret Key: 40 characters long, starts with 0
 Wait for deployment: true
  Recovery wait time: 30

No existing bucket name given, creating/requesting storage location
Uploading file to bucket elasticbeanstalk-ap-northeast-2-358652907057
New build successfully uploaded to S3, bucket=elasticbeanstalk-ap-northeast-2-358652907057, key=/Blog/github-action-2024-06-23T16-30-57.zip
Created new application version github-action-2024-06-23T16-30-57 in Beanstalk.
Starting deployment of version github-action-2024-06-23T16-30-57 to environment Blog-env
Deployment started, "wait_for_deployment" was true...

07:31:07 INFO: Environment update is starting.
07:31:12 INFO: Deploying new version to instance(s).
07:31:16 INFO: Instance deployment successfully detected a JAR file in your source bundle.
07:31:16 INFO: Instance deployment successfully generated a 'Procfile'.
07:31:19 INFO: Instance deployment completed successfully.
07:31:26 INFO: New application version was deployed to running EC2 instances.
07:31:26 INFO: Environment update completed successfully.
07:31:26 INFO: Environment health has transitioned from No Data to Info. Application update in progress on 1 instance. 0 out of 1 instance completed (running for 6 seconds). None of the instances are sending data.
Deployment finished. Version updated to github-action-2024-06-23T16-30-57
Status for Blog-Blog-env is Ready, Health: Grey, HealthStatus: No Data
Warning: Environment update finished, but health is Grey and health status is No Data. Giving it 30 seconds to recover...
Warning: Environment still has health: Grey and health status No Data. Waiting 19 more seconds before failing...
Warning: Environment still has health: Grey and health status No Data. Waiting 8 more seconds before failing...
Error: Deployment failed: Error: Environment still has health Grey 30 seconds after update finished!

위 오류 메시지에서 Environment still has health Grey 30 seconds after update finished!라는 문구를 보아 Elastic Beanstalk에 배포를 하고 나서도 30초가 넘도록 Elastic Beanstalk 환경의 상태가 Grey 상태이기 때문에 오류가 발생한 것으로 보였다.

  • Grey 상태의 의미

    • 데이터 없음 (No Data)
      Elastic Beanstalk가 애플리케이션 인스턴스로부터 상태 데이터를 수신하지 못하고 있는 경우이다. 이는 인스턴스가 아직 시작 중이거나, 애플리케이션이 아직 시작되지 않았거나, Health Check를 수행할 수 없는 상태일 때 발생할 수 있다.

    • 초기화 중 (Initializing)
      환경이 초기화 중이거나 새로 배포된 애플리케이션이 아직 Health Check에 응답하지 않은 경우이다. 이 경우, 인스턴스가 아직 준비되지 않은 상태일 수 있다.

    • 커뮤니케이션 문제 (Communication Issues)
      Elastic Beanstalk가 인스턴스와 통신하는 데 문제가 발생했을 때도 'Grey' 상태가 될 수 있다. 네트워크 문제나 보안 그룹 설정 문제 등이 원인일 수 있다.

    • 애플리케이션 오류 (Application Errors)
      애플리케이션이 제대로 시작되지 않거나 오류가 발생했을 때도 'Grey' 상태가 유지될 수 있다. 해당 경우에는 애플리케이션 로그를 확인하여 애플리케이션이 정상적으로 실행되고 있는지 확인해야 한다.

오류 해결

위 문제를 해결하기 위해 아래 beanstalk-deploy 액션의 원문을 찾아보았다.

https://github.com/einaregilsson/beanstalk-deploy

내용을 보니 health check 시간을 기다리는 디폴트 값이 30초로 설정되어 있고, 원할 시 해당 옵션을 이용하여 추가로 이 시간을 늘릴 수 있다고 나와있다.

따라서 wait_for_environment_recovery: 180 옵션을 추가하여 다음과 같이 cicd.yml 파일을 수정하였다.

 # cicd.yml
 
 ~ 기존 내용 생략 ~
 
 - 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: Blog
          environment_name: Blog-env
          version_label: github-action-${{steps.current-time.outputs.formattedTime}}
          region: ap-northeast-2
          deployment_package: ./build/libs/${{env.artifact}}
          wait_for_environment_recovery: 180 # health check 시간 증가시켜 오류 깃허브 액션 빌드 오류 해결.

위와 같이 수정 후 깃허브 액션으로 들어가 확인을 하니 모든 단계가 정상 동작하는 것을 확인할 수 있었다.

이로써 블로그를 개발하고, GitHub Actios과 AWS Elastic Beanstalk 이용하여 CI/CD까지 구축을 완료하게 되었다.

profile
IT, 개발 관련 정보들을 기록하는 장소입니다.
post-custom-banner

0개의 댓글