AWS

[CI/CD] Github Prod Repo + Github Action + ECR tag + Dockerrun.aws.json 설정

Dexlee 2022. 7. 12. 12:51

Intro.

github repo를 repo-dev와 repo-prod로 나누어서 관리하는 것이 좋다. dev에서는 이미지 빌드를 한 후 ecr에 push 한 후 dev-eb 배포를 한다. 그 후 prod에서 이미지를 pull 받아 prod 환경에 배포한다.

 

1. prod 배포 상황

  • dev에 배포가 되었고 image가 ecr에 올려져 있다.
  • prod에서는 이 이미지를 pull만 받으면 되는 상황

2. deploy.yaml

name: main-prod deploy

on:
  workflow_dispatch:
    inputs:
      image-tag:
        description: 'image tag name'
        required: true
        type: string

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: Set Environment Variable
        run: |
          echo "REPOSITORY_NAME=$(echo '${{ github.repository }}' | awk -F '/' '{print $2}')" >> $GITHUB_ENV
        shell: bash

      - 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
          sed -i "s/{ECR_REGISTRY}/${{ steps.login-ecr.outputs.registry }}/" deploy/Dockerrun.aws.json
          sed -i "s/{REPOSITORY_NAME}/${{ env.REPOSITORY_NAME }}/" deploy/Dockerrun.aws.json
          sed -i "s/{TAG}/${{ inputs.image-tag }}/" 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: ${{ env.REPOSITORY_NAME }}-${{steps.current-time.outputs.formattedTime}}
          region: ${{ secrets.AWS_EB_REGION }}
          deployment_package: deploy/deploy.zip

 

3. on:

on:
  workflow_dispatch:
    inputs:
      image-tag:
        description: 'image tag name'
        required: true
        type: string
  • 수동 배포로 pull 받을 image tag를 입력한다.
  • 왜냐하면 prod에 배포할 image를 해당 workflow가 알 수 없기 때문이다. 그래서 prod에 배포하고 싶은 image tag를 입력해서 해당 이미지를 prod에 배포한다.

4. deploy.zip

- 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
    sed -i "s/{ECR_REGISTRY}/${{ steps.login-ecr.outputs.registry }}/" deploy/Dockerrun.aws.json
    sed -i "s/{REPOSITORY_NAME}/${{ env.REPOSITORY_NAME }}/" deploy/Dockerrun.aws.json
    sed -i "s/{TAG}/${{ inputs.image-tag }}/" deploy/Dockerrun.aws.json
    cd deploy && zip -r deploy.zip .
  • inputs.<input_id> 로 해당 입력 값에 접근할 수 있다.

5. Dockerrun.aws.json

{
  "AWSEBDockerrunVersion": "1",
  "Image": {
    "Name": "{ECR_REGISTRY}/{REPOSITORY_NAME}:{TAG}",
    "Update": "true"
  },
  "Ports": [
    {
      "ContainerPort": 5000,
      "HostPort": 5000
    }
  ]
}

 

6. 결론

이러한 방식으로 배포 파일만 prod-repo에 넣어두면 dev-repo에서 작업한 이미지를 prod-repo에서 배포만 하면 되어서 관리하기가 아주 편하다.