ECS Service의 CD Pipeline을 GitHub Actions로 구축
12926 단어 GitHubActionsGitHubECSAWS
※ 이미지 태그의 관리 방법, 그리고 ECS Task Definition과 Service의 갱신은 IaC의 툴에 따라 바뀌므로 구체적인 명령은 생략합니다.
흐름
PlantUML에서 CD Pipeline의 흐름을 시각화한 것은 다음과 같습니다.
Build와 Deploy Stage로 나누는 몇 가지 이유가 있습니다.
GitHub Actions에서는 needs에 포함된 작업을 건너뛰면 해당 작업도 건너뜁니다.
따라서 ECS 업데이트 작업에서 Docker 이미지의 빌드 푸시 작업이 needs에 포함되면 ECR에 이미지가 존재하면 ECS 업데이트 작업도 건너 뜁니다.
그렇다면 ECR에 이미지가 존재하는지 확인하는 것을 멈추고 매번 새 이미지를 빌드 푸시하면 됩니다만, 이미지 이외의 파라미터를 갱신을 하고 싶은 경우에 불편합니다.
이런 이유로 두 개의 스테이지로 나눕니다.
CD Pipeline on GitHub Actions
전제
전제
워크플로우
빌딩 스테이지
name: Build Stage
on:
push:
tags:
- 'v*'
# 複数のイメージをBulid・Pushする場合のために、共通パラメータはworkflowレベルで環境変数化
# secretsを環境変数化してもログ上ではマスキングされるので問題なし
env:
DOCKER_BUILDKIT: 1
SLACK_CHANNEL: '#random'
AWS_DEFAULT_REGION: ap-northeast-1
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
jobs:
precheck:
name: Check image existence
runs-on: ubuntu-20.04
outputs:
# ECRに存在していればTrue、存在していなければFalse
sample: ${{ steps.sample.outputs.existence }}
steps:
- uses: actions/checkout@v2
- name: Check sample image
id: sample
run: # ファイルで管理しているイメージがECRに存在しているかチェックする処理
sample:
name: Push sample image
runs-on: ubuntu-20.04
needs: [precheck]
# ECRに存在していなければ実行
if: ${{ ! needs.precheck.outputs.sample }}
steps:
- uses: actions/checkout@v2
- name: Get image name
id: getter
# $(...)でファイルからイメージ名(タグを含む)を取得
# 具体的な処理の記述は省略
run: echo "::set-output name=image::$(...)"
- name: Build image
env:
DOCKER_CONTENT_TRUST: 1
run: docker build -t ${{ steps.getter.outputs.image }} .
# Trivyによってイメージをスキャン
- uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ steps.getter.outputs.image }}
severity: 'HIGH,CRITICAL'
exit-code: '1'
ignore-unfixed: true
- uses: hands-lab/[email protected]
with:
image: ${{ steps.getter.outputs.image }}
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_DEFAULT_REGION }}
aws-account-id: ${{ env.AWS_ACCOUNT_ID }}
# 成否をSlackへ通知
- uses: lazy-actions/slatify@master
if: ${{ always() }}
with:
type: ${{ job.status }}
job_name: ':ecr: *Push sample image to ECR*'
channel: ${{ env.SLACK_CHANNEL }}
url: ${{ secrets.CRM_SLACK_WEBHOOK }}
precheck 작업에서 ECR에 동일한 이미지 이름(태그 포함)이 있는지 확인합니다.
그 샘플 스크립트를 일단 써 둡니다.
\$ repo에 ECR 리포지토리 이름,\$ tag에 이미지 태그를 할당하면
GitHub Actions는 빈 문자이면 False이고, 그렇지 않으면 True입니다. 다음 스크립트의 경우 ECR에 해당하는 이미지가 없으면 공문자가 되므로 위의 workflow에서도 그대로 사용할 수 있습니다.
aws ecr batch-get-image \
--repository-name "$repo" \
--image-ids "imageTag=$tag" \
--query 'images[].imageId.imageTag' \
--output text
sample 작업은 precheck 작업의 출력에 따라 건너뜁니다.
ECR에 존재하지 않는 태그이면 실행합니다.
그리고는 이미지를 빌드하고 푸시하고 있을 뿐입니다.
말하자면 trivy의 공식 GitHub Action에서 이미지 스캔을하고 있습니다.
exit-code: '1'
를 설정해 취약성이 있으면 푸시하지 않는다 = workflow 실패라고 하고 있습니다.Deploy Stage
name: Deploy Stage
on:
workflow_run:
# Build Stage完了後にDeploy Stageを実行
workflows:
- Build Stage
types:
- completed
env:
DOCKER_BUILDKIT: 1
SLACK_CHANNEL: '#random'
AWS_DEFAULT_REGION: ap-northeast-1
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
jobs:
deploy:
name: Deployment
runs-on: ubuntu-20.04
# Build Stageが成功している場合のみ実行
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v2
with:
# Build Stageと同じコミットSHAにチェックアウト
# refの指定がなければデフォルトブランチにチェックアウトします
ref: ${{ github.event.workflow_run.head_sha }}
- name: Update ECS Task Definition and Service
run: # 具体的な処理は省略
# 成否をSlackへ通知
- uses: lazy-actions/slatify@master
if: ${{ always() }}
with:
type: ${{ job.status }}
job_name: ':ecs: *Deploy*'
channel: ${{ env.SLACK_CHANNEL }}
url: ${{ secrets.CRM_SLACK_WEBHOOK }}
Build Stage가 완료된 후 Deploy Stage를 호출하려면
workflow_run
라는 이벤트 트리거를 사용합니다.workflow_run은 의존원인 workflow의 성공 여부에 관계없이 발화하므로 Deploy Stage에서 Build Stage의 성공 여부를 명시적으로 확인해야 합니다. 그것이
if: ${{ github.event.workflow_run.conclusion == 'success' }}
입니다.Reference
Reference
이 문제에 관하여(ECS Service의 CD Pipeline을 GitHub Actions로 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/homines22/items/6aee17de07a5fced176f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)