[GitHub] 새로운 GitHub Actions를 사용해 AWS ECR로 이미지를 푸시하는 CI를 만들었습니다.

18725 단어 GitHubAWSDocker

오프닝


HCL에서 YAML로 CI를 작성할 수 있는 GitHub Actions가 업데이트되었습니다.
이전에는 모든 동작이 Dockerfile을 준비해야 했지만 Ubuntu·Windows·MacOS에서 CI를 돌릴 수 있어 Dockerfile의 유지 보수가 필요하지 않습니다.<-정말 감사합니다
그렇다면 새로운 GitHub Actions를 사용하여 CI를 어떻게 만드는지 설명하고 싶습니다.

개요


이번에 제작된 CI는 Python에서 개발한 어플리케이션 Dockerize를 AWS ECR로 푸시합니다.
푸시 전에 원본 코드의 행 검사, 테스트, Trivy를 사용하여 빈틈 진단과 Dockle을 사용하여 안전 진단을 병행합니다.병행 운행이 가능한 작업은 최대 20개이기 때문에 이번 규모는 여유롭게 병행 운행할 수 있다.
병행 작업을 할 때 주의해야 할 것은 각 작업의 가상 실례가 다르기 때문에 파일 시스템에서 정보를 공유하지 않는다는 것이다.정보를 공유하려면 같은 작업에서 모든 절차를 수행해야 합니다.따라서 구멍 진단 및 보안 진단 ECR로 푸시할 때 각각의 Docker 이미지가 구축됩니다.아, 절충이군요.
온라인으로 CI를 돌릴 때 주의하고 싶은 것은 클레덴 데이터의 처리다.GitHub에는 데이터를 암호화하고 저장할 수 있는 Secrets 기능이 있습니다.GitHub Actions는 Secrets에서 설정한 값에 액세스할 수 있으므로 YAML에 자격 증명 데이터를 직접 쓰지 않아도 됩니다.

프로세스



소스 코드


쿨하게, 완성형만 알고 싶은 사람을 위해 원본 코드를 쓴다.
※ [추적] trivy의 저장소 변경aquasecurity/trivy
.github/workflows/main.yml
on:
  push:
    branches:
      - master
      - develop
name: Build and Push Image to ECR
jobs:
  lint:
    name: Lint check
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@master
      - name: Set up Python 3.7
        uses: actions/setup-python@v1
        with:
          version: '3.7'
          architecture: 'x64'
      - name: Install dependencies
        run: |
          pip install --upgrade pip pipenv flake8
          pipenv install --system
      - name: Lint check with flake8
        run: flake8 src tests

  test:
    name: Python Test
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@master
      - name: Set up Python 3.7
        uses: actions/setup-python@v1
        with:
          version: '3.7'
          architecture: 'x64'
      - name: Install dependencies
        run: |
          pip install --upgrade pip pipenv pytest
          pipenv install --system
      - name: Test with pytest
        run: python -m pytest -v

  trivy:
    name: Trivy Scan Vulnerability
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@master
      - name: Build docker image
        run:
          docker build -t ${IMAGE_NAME} . --file Dockerfile
        env:
          IMAGE_NAME: app
      - name: Install trivy
        run: |
          sudo apt-get install apt-transport-https gnupg
          wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
          echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -cs) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
          sudo apt-get update
          sudo apt-get install trivy
      - name: Vulnerability Scan with Trivy
        run: trivy --only-update alpine -q --severity HIGH,CRITICAL --exit-code 1 ${IMAGE_NAME}
        env:
          IMAGE_NAME: app

  dockle:
    name: Dockle
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@master
      - name: Build docker image
        run: docker build -t ${IMAGE_NAME} . --file Dockerfile
        env:
          IMAGE_NAME: app
      - name: Install dockle
        run: |
          VERSION=$(curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \
          grep '"tag_name":' | \
          sed -E 's/.*"v([^"]+)".*/\1/' \
          )
          curl -L -o dockle.deb https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.deb
          sudo dpkg -i dockle.deb
          rm dockle.deb
      - name: Check image with dockle
        run: dockle ${IMAGE_NAME}
        env:
          IMAGE_NAME: app

  build:
    name: Build and Push Docker Image
    runs-on: ubuntu-18.04
    needs: [lint, test, trivy, dockle]
    steps:
      - uses: actions/checkout@master
      - name: Setup Python 3.7 for awscli
        uses: actions/setup-python@v1
        with:
          version: '3.7'
          architecture: 'x64'
      - name: Install awscli
        run: pip install --upgrade pip awscli
      - name: Login to ECR
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        run: $(aws ecr get-login --no-include-email --region ap-northeast-1)
      - name: Build docker image
        env:
          CONTAINER_REGISTRY_PATH: ${{ secrets.CONTAINER_REGISTRY_PATH }}
          IMAGE_NAME: app
        run: |
          TAG=`echo $GITHUB_REF | sed 's/refs\/heads\///g'`
          docker build -t ${CONTAINER_REGISTRY_PATH}/${IMAGE_NAME}:${TAG} .
      - name: Notify push start to Slack
        run: curl -X POST -H 'Content-type:application/json' --data '{"text":"'"${GITHUB_REPOSITORY}"'\n【START】Push Image to ECR!!"}' ${{ secrets.SLACK_WEBHOOK }}
      - name: Push image to ECR
        env:
          CONTAINER_REGISTRY_PATH: ${{ secrets.CONTAINER_REGISTRY_PATH }}
          IMAGE_NAME: app
        run: |
          TAG=`echo $GITHUB_REF | sed 's/refs\/heads\///g'`
          docker push ${CONTAINER_REGISTRY_PATH}/${IMAGE_NAME}:${TAG}
      - name: Notify push finish to Slack
        run: curl -X POST -H 'Content-type:application/json' --data '{"text":"'"${GITHUB_REPOSITORY}"'\n【FINISH】Pushed Image to ECR!!"}' ${{ secrets.SLACK_WEBHOOK }}

해설


원본 코드에 쓴 내용을 분할하여 설명하다.

이벤트 트리거

on:
  push:
    branches:
      - master
      - develop
트리거된 이벤트를 설정합니다.
설정할 수 있는 이벤트는push,issues,pull_request 등.모든 활동을 알고 싶은 사람은 참조하세요Events that trigger workflows - GitHub Help.
이것은push를 트리거로 하고master와develop 지점만 대상으로 합니다.이벤트 대상을 제한하기 위해,branches 이외에tags와paths가 있습니다.tags는 말 그대로 paths가 고려할 파일과 디렉터리를 지정합니다.

Jobs

jobs:
  lint:
    name: Lint check
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@master
on에서 실행할 CI 프로세스를 선언합니다.여러 개의 job가 존재하면 기본적으로 병행 실행됩니다.<-대단하다
job를 순서대로 실행하려면 jobs 를 사용하십시오.이것은 지정한 작업이 끝날 때까지 기다릴 것입니다.needs는 job의 ID입니다.jobs에서 유일해야 하지만 분배된 ID는 취향에 따라 진행할 수 있습니다.lint에서 가상 인스턴스를 지정합니다.지정할 수 있는 OS는 Ubuntu, MacOS 및 Windows입니다.버전을 지정할 수도 있습니다.
현재,job가 실행할 수 있는 환경은 이미 준비되었고, runs-on 실제 처리 내용을 설명할 것입니다.

Steps

steps:
  - uses: actions/checkout@master
  - name: Set up Python 3.7
    uses: actions/setup-python@v1
    with:
      version: '3.7'
      architecture: 'x64'
  - name: Install dependencies
    run: |
      pip install --upgrade pip pipenv flake8
      pipenv install --system
  - name: Lint check with flake8
    run: flake8 src tests
stpes에 처리 내용을 기술합니다.모든 단계의 작업은 같은 가상 실례에서 실행된다.정보를 공유하고 싶으면 같은 단계에서 작성하여 처리하세요.steps 사용할 동작을 지정합니다.동일한 저장소의 작업, 공용 저장소의 작업 및 공용 저장소 이미지를 지정할 수 있습니다.steps가 최초로 선언한 조작uses은 뒷면에서 actions/checkout@mastergit fetch와 같은 조작을 수행한다.즉, 트리거 이벤트 커밋으로 체크 아웃할 수 있습니다.이 작업을 지정해야 합니다.겸사겸사 actions/setup-python@v1뒷면에서 TypeScript가 이동합니다.git checkout $GITHUB_SHA 작업에 대한 입력 값을 지정합니다.각 동작의 YAML에 쓰인 것을 지정할 수 있습니다. 저쪽을 확인하십시오.
실행할 명령은 with 에서 지정합니다.명령을 너무 길게 실행하면 가독성이 떨어지므로 작업을 만드는 것이 좋습니다.

환경 변수

env:
  IMAGE_NAME: app
환경 변수는 run 에서 지정합니다."environment"를 쓸 필요가 없어서 편해요.

Secrets

${{ secrets.AWS_ACCESS_KEY_ID }}
Secrets로 설정된 값에 액세스하려면 위에서 설명한 대로 하십시오.secrets 다음에 가져올 값을 지정하는 키(AWS_ACCESS_KEY_ID).

잡담


한마디로 GitHub Actions의 실행 화면이 상당히 풍부해졌다.

끝내다


나는 GitHub Actions에 CI를 써 보았는데, 품질과 다른 CI 도구가 손색이 없다고 느꼈다.다만, CI 결과를 통지하는 수단은 우편물만 지원하는 것이 아프다.이번 CI에는 Slack을 먼저 curl로 알려주는 처리가 들어갔지만 동작을 만드는 것이 좋다고 생각합니다.
이 글이 앞으로 GitHub Actions에 CI를 쓰고 싶은 분들에게 참고가 됐으면 좋겠네요.

Reference

  • About GitHub Actions
  • Workflow syntax for GitHub Actions
  • Virtual environments for GitHub Actions
  • 좋은 웹페이지 즐겨찾기