본문 바로가기

AWS

[CI/CD] Github Action + AWS Elastic Beanstalk + ECR + IAM + Docker + ARM + Java or Kotlin + Spring Boot + Gradle 배포 (5)

해당 자료는 총 5개 파트로 나누어서 자료를 정리할 예정이다.

part 1. IAM user 권한 설정

part 2. ECR repo 세팅

part 3. EB 설정 후 샘플 코드 서버 세팅

part 4. Spring Boot 프로젝트 내부 설정

part 5. github action 세팅


Part 5. github action 세팅

part 4를 못 보셨다면 먼저 보시길 바란다.

https://dexlee.tistory.com/172

 

1. github action 이란?

GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline.(공식문서 정의)

 

 

2. github action 전체 파일

.github/workflows/deploy.yaml

name: build, deploy

on:
  pull_request_target:
    types:
      - closed
    branches:
      - develop

jobs:
  build_deploy:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up JDK 8
        uses: actions/setup-java@v3
        with:
          java-version: '8'
          distribution: 'temurin'
          cache: gradle

      - name: Validate Gradle wrapper
        uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b

      - name: Build with Gradle
        uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
        with:
          arguments: bootjar

      - name: Set up QEMU #Dockerfile에서 arm64v8 이미지를 사용하기 때문에 설정
        uses: docker/setup-qemu-action@v2

      - 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_EB_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build, tag, and push image to Amazon ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: ecr repo name
          IMAGE_TAG: latest
        #EC2 인스턴스 타입이 ARM이기 때문에 --platform=linux/arm64v8 사용
        run: |
          docker buildx build --platform=linux/arm64v8 -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"

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

      - name: Generate deployment package
        run: |
          mkdir -p deploy
          cp -r .ebextensions deploy/.ebextensions
          cp -r .platform deploy/.platform
          cp Dockerrun.aws.json deploy/Dockerrun.aws.json
          cd deploy && zip -r deploy.zip .

      - name: Deploy to EB
        uses: einaregilsson/beanstalk-deploy@v20
        with:
          aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          application_name: eb app name
          environment_name: eb env name
          version_label: github-action-${{steps.current-time.outputs.formattedTime}}
          region: ${{ secrets.AWS_EB_REGION }}
          deployment_package: deploy/deploy.zip
#          wait_for_deployment: true # 배포 완료까지 기다려야 하는지. default true
#          wait_for_environment_recovery: 30 # 배포 완료 후 녹색 상태까지 기다리는 시간 default 30
  • 각 파트가 무엇을 의미하는지 deploy 확장자부터 마지막까지 자세히 알아보겠다.

 

3. deploy의 확장자 yml이 아닌 yaml을 사용한 이유

  • 둘 다 문법과 성능이 같다. 하지만 yml 과거 버전의 windows가 파일 확장자를 3 단어로 제한했어서 yml을 강제로 사용했다.
  • 물론 현재에는 3단어로 제한하는 OS는 없다.
  • 또한, YAML FAQ와 github action 공식문서에 따르면 yaml 확장자를 사용하는 것을 선호한다고 한다.
  • 이러한 이유로 yaml을 사용했다.

 

4. name:

name: build, deploy

이 파일 workflow의 이름을 의미한다.

 

5. on:

on:
  pull_request_target:
    types:
      - closed
    branches:
      - develop

1)on:

  • workflow를 실행하는 trigger이다.

2)pull_request_target:

  • pull request의 target branch를 지정

3)types: - closed

  • pull request가 closed가 된다.

4)branches: - develop

  • target 브런치 지정

6. jobs:

  • jobs.<job_id>.steps 의 구조
jobs:
  build_deploy:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest

1)jobs:

  • workflow run에서 실행하는 단위

2) build_deploy:

  • job_id
  • 즉, 내가 job id로 정하고 싶은 단어를 적으면 된다.

3) if:

  • 분기문이다.

4) runs-on:

  • 각 job이 이 runner 환경 안에서 동작한다.
  • runner 환경은 os 환경이다.
  • github action은 ubuntu, mac, windows만 지원한다.

7. steps:

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

1)steps:

  • 작업 순서를 차례대로 적는다.

2)name:

  • 해당 step(task)의 이름을 적는다.

3)uses:

  • 해당 작업을 실행하라는 의미
  • 위에 내용을 해석해보자면 actions/checkout의 v3 태그를 참조하여 해당 task를 실행하라는 의미

 

8. actions/checkout@v3

- name: Checkout
  uses: actions/checkout@v3

 

  • 해당 workflows를 실행하기 위해 세팅한 작업들을 확인하는 단계
  • 그래서 해당 repo directory에 세팅한 global git config가 있다면 repo directory에 add를 해준다.

 

9. actions/setup-java@v3

- name: Set up JDK 8
  uses: actions/setup-java@v3
  with:
    java-version: '8'
    distribution: 'temurin'
    cache: gradle
  • adoptOpenJDK 공식 사이트에 들어가 보면 이클립스 제단으로 옮겨졌다고 나오고 이클립스 제단은 temurin 프로젝트를 지원합니다.
  • gradle cache는 아래 공식문서를 읽어보시길 바란다.

10. gradle/wrapper

- name: Validate Gradle wrapper
  uses: gradle/wrapper-validation-action@e6e38bacfdf1a337459f332974bb2327a31aaf4b
  • to validate the checksums of Gradle Wrapper JAR files present in the source tree.(공식문서 정의)

11.  gradle/gradle-build-action

- name: Build with Gradle
  uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
  with:
    arguments: bootjar

12. QEMU

- name: Set up QEMU #Dockerfile에서 arm64v8 이미지를 사용하기 때문에 설정
  uses: docker/setup-qemu-action@v2

13.  aws-actions/configure-aws-credentials

- 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_EB_REGION }}
  • aws service에 접근하기 위해 iam user 정보를 등록해주는 task이다.

14. aws-actions/amazon-ecr-login

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build, tag, and push image to Amazon ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: ecr repo name
          IMAGE_TAG: latest
        #EC2 인스턴스 타입이 ARM이기 때문에 --platform=linux/arm64v8 사용
        run: |
          docker buildx build --platform=linux/arm64v8 -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
  • id는 step의 이름이다.
  • ecr에 접근해서 registry 고유한 이름을 가져와서 docker build 후 ecr에 push 한다.

15. time

- name: Get current time
  uses: 1466587594/get-current-time@v2
  id: current-time
  with:
    format: YYYY-MM-DDTHH-mm-ss
    utcOffset: "+09:00"
  • 현재 시간 설정
  • utc 기준 한국은 9시간이 더 빠르므로 +9

16. 배포 파일 생성

- name: Generate deployment package
  run: |
    mkdir -p deploy
    cp -r .ebextensions deploy/.ebextensions
    cp -r .platform deploy/.platform
    cp Dockerrun.aws.json deploy/Dockerrun.aws.json
    cd deploy && zip -r deploy.zip .

 

17. EB 배포

- name: Deploy to EB
  uses: einaregilsson/beanstalk-deploy@v20
  with:
    aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    application_name: eb app name
    environment_name: eb env name
    version_label: github-action-${{steps.current-time.outputs.formattedTime}}
    region: ${{ secrets.AWS_EB_REGION }}
    deployment_package: deploy/deploy.zip

 

18. dev와 prod 환경 세팅 방법

  • dev repo와 prod repo를 따로 만들어 관리하고 prod repo에서는 배포 파일만 놓은 프로젝트를 만들어 dev에서 생성된 이미지를 ecr에서 pull 하고 eb에 배포하는 방식으로 관리하면 편하다.
  • dev 서버에서 이미지를 생성해 테스트를 하고 해당 이미지를 가지고 prod 서버에 배포를 한다.
  • 즉, 빌드는 한 번만 하고 생성된 이미지를 바탕으로 dev, qa, stage, prod에 모두 배포한다.
  • 각 환경에 필요한 환경 변수 세팅은 EB에서 한다.

1) prod deploy.yaml

name: prod deploy

on:
  push:
    branches:
      - master

jobs:
  build_deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - 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_EB_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

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

      - name: Generate deployment package
        run: |
          mkdir -p deploy
          cp -r .ebextensions deploy/.ebextensions
          cp -r .platform deploy/.platform
          cp Dockerrun.aws.json deploy/Dockerrun.aws.json
          cd deploy && zip -r deploy.zip .

      - name: Deploy to EB
        uses: einaregilsson/beanstalk-deploy@v20
        with:
          aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          application_name: eb app name
          environment_name: eb env name
          version_label: github-action-${{steps.current-time.outputs.formattedTime}}
          region: ${{ secrets.AWS_EB_REGION }}
          deployment_package: deploy/deploy.zip

19. the end

모든 과정이 끝났다.

part 1부터 part 5까지 내가 설정한 그대로 따라 하면 무리 없이 정상 작동할 것이다.

좀 더 깊이 있게 알고 싶으면 내가 남긴 reference를 참고하길 바란다.

여기까지 따라오느라 고생하셨습니다.

 

references

1)github action 정의

https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions

 

2)yml vs yaml

https://www.w3schools.io/file/yaml-vs-yml/

https://stackoverflow.com/questions/22268952/what-is-the-difference-between-yaml-and-yml-extension

 

3)gitHub action syntax

https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions

https://frontside.com/blog/2020-05-26-github-actions-pull_request/

https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idsteps

 

4)github action os 지원 목록

https://github.com/actions/virtual-environments

 

5)steps: checkout

https://github.com/actions/checkout

 

6)adoptOpenJDK vs temurin

https://adoptopenjdk.net/about.html

https://projects.eclipse.org/projects/adoptium.temurin

https://blog.adoptopenjdk.net/2021/03/transition-to-eclipse-an-update/

 

7)gradle cache

https://github.com/marketplace/actions/gradle-cache

 

8)gradle with githubaction

https://github.wiki/en/enterprise-cloud@latest/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

 

9)docker buildx

https://github.com/marketplace/actions/build-and-push-docker-images

 

10)configure-aws-credentials

https://github.com/aws-actions/configure-aws-credentials

 

11)ecr login

https://github.com/aws-actions/amazon-ecr-login

 

12)current time

https://github.com/marketplace/actions/get-current-time

 

13)eb deploy

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