티스토리 뷰

❖ 배포 스크립트 확인

  • 기본적인 스크립트 작성 방법
  • github에 접속 > Actions 탭 > New workflow > ecs를 선택하면 배포 설정 스크립트 포멧을 확인 할 수 있습니다.

❖ 요구사항

  • develop은 자동 배포가 됩니다.
  • stg, qa, prod 환경은 수동 배포를 진행합니다.
  • 현재 코드를 빌드하여 ECR에 업로드 후 ECS에 배포를 합니다.
  • 배포 시작, 배포 성공, 배포 실패시 슬랙으로 알람을 보냅니다.

❖ 배포 스크립트 작성

- 다양한 옵션들을 설명하려고 보니 코드가 길어졌지만 하나씩 설명을 드리면 커스텀하기 쉬울 것입니다.

 

◈ 트리거 설정

- develop 브랜치가 push가 되면 실행합니다.

- workflow_dispatch 는 수동으로 배포할 수 있는 기능입니다.

- workflow_dispatch

on:
  push:
    branches:
        - develop
  workflow_dispatch:
    inputs:
      stage:
        description: '배포할 환경을 선택하세요.'
        required: true
        default: 'dev'
        type: choice
        options:
        - stg
        - qa
        - prod

 

◈ 전역 환경 변수 설정

- github.ref_name  : 브랜치일 경우 브랜치 명, tag일때는 tag명을 조회합니다.

- github.ref_type : 워크플로 실행을 트리거한 ref의 형식입니다. 유효한 값은 branch 또는 tag입니다.

- github에서 제공하는 다양한 컨텍스트 정보는 아래 링크를 참고해 주세요.
https://docs.github.com/ko/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs

env:
  TAG_NAME: ${{ github.ref_name }}
  REF_TYPE: ${{ github.ref_type }}

 

◈ 환경에 따른 변수 설정

- step에 if 조건으로 특정 조건일때 변수명을 다르게 적용하도록 합니다.

    - 수동으로 입력받은 stage 정보가 운영일 경우와 그렇지 않을 때의 슬랙 알람 정보가 다르게 설정됩니다.

    - develop 브랜치로 push로 이벤트 발생시에는 dev 환경이며 슬랙 알람을 보내지 않습니다.
    - 수동배포일 경우 선택한 stage와 슬랙 알람을 보내도록 합니다.

- echo "start_webhook_url=https://hooks.slack.com/triggers/prod-startUrl" >> $GITHUB_OUTPUT

    - 변수명 : start_webhook_url
    - 값(모든 값은 string입니다.) : https://hooks.slack.com/triggers/prod-startUrl

    - >> : 출력 결과를 지정된 파일에 추가하는 역할입니다.

    - $GITHUB_OUTPUT : GitHub Actions에서 사용되는 특수한 환경 변수로, 지정된 파일에 출력 결과를 저장합니다.

    - $GITHUB_OUTPUT 정의된 변수를 outputs에 정의하면 다른 jobs에서 사용할 수 있도록 합니다.

jobs:
  set-env:
    runs-on: ubuntu-latest
    outputs:
      stage: ${{ steps.set-input.outputs.stage }}
      is_notication: ${{ steps.set-input.outputs.is_notication }}
      start_webhook_url: ${{ steps.set-webhook-url.outputs.start_webhook_url }}
      success_webhook_url: ${{ steps.set-webhook-url.outputs.success_webhook_url }}
      failure_webhook_url: ${{ steps.set-webhook-url.outputs.failure_webhook_url }}
    
    steps:
      - name: Set slack webhook url variables
        id: set-webhook-url
        run: |
          if [ "${{ github.event.inputs.stage }}" == "prod" ]; then
            echo "start_webhook_url=https://hooks.slack.com/triggers/prod-startUrl" >> $GITHUB_OUTPUT
            echo "success_webhook_url=https://hooks.slack.com/triggers/prod-successUrl" >> $GITHUB_OUTPUT
            echo "failure_webhook_url=https://hooks.slack.com/triggers/prod-failureUrl" >> $GITHUB_OUTPUT
          else
            echo "start_webhook_url=https://hooks.slack.com/triggers/etc-startUrl" >> $GITHUB_OUTPUT
            echo "success_webhook_url=https://hooks.slack.com/triggers/etc-successUrl" >> $GITHUB_OUTPUT
            echo "failure_webhook_url=https://hooks.slack.com/triggers/etc-failureUrl" >> $GITHUB_OUTPUT
          fi

      - name: Set input variables
        id: set-input
        run: |
          if [ "${{ github.event_name }}" == "push" ]; then
            echo "stage=dev" >> $GITHUB_OUTPUT
            echo "is_notication=false" >> $GITHUB_OUTPUT
          else
            echo "is_notication=true" >> $GITHUB_OUTPUT
            echo "stage=${{ github.event.inputs.stage }}" >> $GITHUB_OUTPUT
          fi

 

◈ 시작 배포 알림

- 알림 설정이 true인 경우에만 실행이 됩니다.

- payload는 slack_webhook 템플릿에 사용할 값을 정의해주는 것입니다.

- SLACK_WEBHOOK_URL 에 웹훅  URL를 설정합니다.
- 슬랙 웹훗 설정 방법 : 슬랙 웹훅 설정

  notify_start:
    runs-on: ubuntu-latest
    needs: set-env
    if: ${{ needs.set-env.outputs.is_notication == 'true' }}
    steps:
      - name: Send start deploy notification
        id: start_notification
        uses: slackapi/slack-github-action@v1.27.0
        with:
          payload: |
            {
              "stage": "${{ needs.set-env.outputs.stage }}",
              "fetchVersion": "${{ env.TAG_NAME }}",
              "workflowRunUrl": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
            }
        env:
          SLACK_WEBHOOK_URL: "${{ needs.set-env.outputs.start_webhook_url }}"

 

◈ ECS 배포

- actions/checkout@v4 : 현재 코드를 체크아웃합니다.

- aws-actions/configure-aws-credentials@v4 : aws 인증을 합니다.

- aws-actions/amazon-ecr-login@v2 : ecr 에 로그인을 합니다.

- build-image : 이미지를 빌드한 후 ECR에 업로드 합니다.

- ecs task definition이 정의된 경로입니다.
    - 파일의 경우 aws ecs > 태스크 정의해서 생성 후 JSON 탭에서 AWS CLI 입력 다운로드를 받으시면 됩니다.

- aws-actions/amazon-ecs-deploy-task-definition@v2

    - ecs를 배포합니다.

옵션명  
task-definition task-definition 정의 파일
cluster  배포할 ecs의 클러스터 정보
service  배포할 ecs 서비스 정보
wait-for-service-stability: true 배포 후 서버가 안정될때까지 대기하는 옵션
propagate-tags: SERVICE task-definition 에 정의된 tag 정보를 service 까지 배포할 때 사용
deploy_service:
    name: deploy_service
    runs-on: ubuntu-latest
    needs: set-env

    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        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: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2
      
      - name: Build and push Docker image
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: "deploy-service-repository"
          IMAGE_TAG: ${{ env.TAG_NAME }}
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f service/deploy/Dockerfile .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
      
      - name: Fill in the new image ID in the Amazon ECS task definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: .github/workflows/aws/task-definitions/${{ needs.set-env.outputs.stage }}/first-service-task-definition.json
          container-name: first-service
          image: ${{ steps.build-image.outputs.image }}
          
      - name:  Deploy to Amazon ECS
        uses: aws-actions/amazon-ecs-deploy-task-definition@v2
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          cluster: deploy-service-cluster
          service: deploy-service-${{ needs.set-env.outputs.stage }}
          wait-for-service-stability: true
          propagate-tags: SERVICE

 

 

◈ 전체 스크립트

name: Deploy

on:
  push:
    branches:
        - develop
  workflow_dispatch:
    inputs:
      stage:
        description: '배포할 환경을 선택하세요.'
        required: true
        default: 'dev'
        type: choice
        options:
        - stg
        - qa
        - prod

env:
  TAG_NAME: ${{ github.ref_name }}
  REF_TYPE: ${{ github.ref_type }}

jobs:
  set-env:
    runs-on: ubuntu-latest
    outputs:
      stage: ${{ steps.set-input.outputs.stage }}
      is_notication: ${{ steps.set-input.outputs.is_notication }}
      start_webhook_url: ${{ steps.set-webhook-url.outputs.start_webhook_url }}
      success_webhook_url: ${{ steps.set-webhook-url.outputs.success_webhook_url }}
      failure_webhook_url: ${{ steps.set-webhook-url.outputs.failure_webhook_url }}
    
    steps:
      - name: Set slack webhook url variables
        id: set-webhook-url
        run: |
          if [ "${{ github.event.inputs.stage }}" == "prod" ]; then
            echo "start_webhook_url=https://hooks.slack.com/triggers/prod-startUrl" >> $GITHUB_OUTPUT
            echo "success_webhook_url=https://hooks.slack.com/triggers/prod-successUrl" >> $GITHUB_OUTPUT
            echo "failure_webhook_url=https://hooks.slack.com/triggers/prod-failureUrl" >> $GITHUB_OUTPUT
          else
            echo "start_webhook_url=https://hooks.slack.com/triggers/etc-startUrl" >> $GITHUB_OUTPUT
            echo "success_webhook_url=https://hooks.slack.com/triggers/etc-successUrl" >> $GITHUB_OUTPUT
            echo "failure_webhook_url=https://hooks.slack.com/triggers/etc-failureUrl" >> $GITHUB_OUTPUT
          fi

      - name: Set input variables
        id: set-input
        run: |
          if [ "${{ github.event_name }}" == "push" ]; then
            echo "stage=dev" >> $GITHUB_OUTPUT
            echo "is_notication=false" >> $GITHUB_OUTPUT
          else
            echo "is_notication=true" >> $GITHUB_OUTPUT
            echo "stage=${{ github.event.inputs.stage }}" >> $GITHUB_OUTPUT
          fi

  notify_start:
    runs-on: ubuntu-latest
    needs: set-env
    if: ${{ needs.set-env.outputs.is_notication == 'true' }}
    steps:
      - name: Send start deploy notification
        id: start_notification
        uses: slackapi/slack-github-action@v1.27.0
        with:
          payload: |
            {
              "stage": "${{ needs.set-env.outputs.stage }}",
              "fetchVersion": "${{ env.TAG_NAME }}",
              "workflowRunUrl": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
            }
        env:
          SLACK_WEBHOOK_URL: "${{ needs.set-env.outputs.start_webhook_url }}"
  
  deploy_service:
    name: deploy_service
    runs-on: ubuntu-latest
    needs: set-env

    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        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: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2
      
      - name: Build and push Docker image
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: "deploy-service-repository"
          IMAGE_TAG: ${{ env.TAG_NAME }}
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f service/deploy/Dockerfile .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
      
      - name: Fill in the new image ID in the Amazon ECS task definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: .github/workflows/aws/task-definitions/${{ needs.set-env.outputs.stage }}/first-service-task-definition.json
          container-name: first-service
          image: ${{ steps.build-image.outputs.image }}
          
      - name:  Deploy to Amazon ECS
        uses: aws-actions/amazon-ecs-deploy-task-definition@v2
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          cluster: deploy-service-cluster
          service: deploy-service-${{ needs.set-env.outputs.stage }}
          wait-for-service-stability: true
          propagate-tags: SERVICE

  notify_success:
    runs-on: ubuntu-latest
    needs: [set-env, deploy_service]
    if: ${{ needs.set-env.outputs.is_notication == 'true' && success() }}
    steps:
      - name: Send success notification
        id: success_notification
        uses: slackapi/slack-github-action@v1.27.0
        with:
          payload: |
            {
              "stage": "${{ needs.set-env.outputs.stage }}",
              "fetchVersion": "${{ env.TAG_NAME }}",
              "workflowRunUrl": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
            }
        env:
          SLACK_WEBHOOK_URL: "${{ needs.set-env.outputs.success_webhook_url }}"

  notify_failure:
    runs-on: ubuntu-latest
    needs: [set-env, deploy_service]
    if: ${{ needs.set-env.outputs.is_notication == 'true' && failure() }}
    steps:
      - name: Send failure notification
        id: failure_notification
        uses: slackapi/slack-github-action@v1.27.0
        with:
          payload: |
            {
              "stage": "${{ needs.set-env.outputs.stage }}",
              "fetchVersion": "${{ env.TAG_NAME }}",
              "workflowRunUrl": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
            }
        env:
          SLACK_WEBHOOK_URL: "${{ needs.set-env.outputs.failure_webhook_url }}"

'git' 카테고리의 다른 글

github action 워크플로우 작성방법 및 구성요소  (1) 2024.11.05
gitgub actions 의 주요 개념  (0) 2024.11.05
CI / CD란?  (0) 2024.11.05
git commit 순서 바꾸기  (1) 2022.03.19
댓글
공지사항