Backend

GitHub Actions를 이용하여 GitOps의 YAML 파일 동적 업데이트

산희 2024. 7. 4. 20:32

배경

  • Jenkins & Spinnaker 기반의 CI/CD 환경에서 GitHub Action & Argo CD로 전환하게 되었습니다.
  • Spinnaker에서는 배포 시 동적 파라미터를 제공하여 yaml 을 수정하는 기능이 있었으나, Argo CD는 이러한 기능을 지원하지 않는걸로 파악했습니다.

 

구현

  • Argo CD가 GitOps 방식을 따르므로, 애플리케이션 배포 시 GitHub Actions를 활용하여 Deploy Repository의 yaml 파일을 워크플로우 디스패치 이벤트로부터 받은 파라미터로 동적으로 수정합니다. 이를 통해 최종 배포 단계에서 yaml 파일을 업데이트하여 파라미터를 주입합니다. (* yq 활용)

 

구현 샘플.

Application Repository 설정

# GitHub Workflow name: Update WORKER_COUNT in sample.yaml on: ​​workflow_dispatch: ​​​​inputs: ​​​​​​workerCount: ​​​​​​​​description: 'New WORKER_COUNT value' ​​​​​​​​required: true ​​​​​​​​default: '99' ​​​​​​userName: ​​​​​​​​description: 'New userName value' ​​​​​​​​required: true ​​​​​​​​default: 'root' ​​​​​​versionName: ​​​​​​​​description: 'New Version Value' ​​​​​​​​required: true ​​​​​​​​default: '2' jobs: ​​update-yaml: ​​​​runs-on: ubuntu-latest ​​​​steps: ​​​​- name: Checkout B Repository ​​​​​​uses: actions/checkout@v2 ​​​​​​with: ​​​​​​​​repository: 'author/repository' ​​​​​​​​token: ${{ secrets.TEST_B_REPO_TOKEN }} ​​​​​​​​ref: 'main' ​​​​- name: Install yq (YAML Processor) ​​​​​​run: sudo snap install yq ​​​​- name: Update WORKER_COUNT in sample.yaml ​​​​​​run: | ​​​​​​​​yq eval '.version = ${{ github.event.inputs.versionName }}' -i sample.yaml ​​​​​​​​yq eval '.services.worker.environment.WORKER_COUNT = "${{ github.event.inputs.workerCount }}"' -i sample.yaml ​​​​​​​​yq eval '.databases.postgres.environment.POSTGRES_USER = "${{ github.event.inputs.userName }}"' -i sample.yaml ​​​​- name: Commit and Push changes ​​​​​​uses: EndBug/add-and-commit@v7 ​​​​​​with: ​​​​​​​​author_name: authorName ​​​​​​​​author_email: authorEmail ​​​​​​​​message: 'Update WORKER_COUNT in sample.yaml to ${{ github.event.inputs.workerCount }}' ​​​​​​​​add: 'sample.yaml' ​​​​​​​​push: true ​​​​​​​​token: ${{ secrets.B_REPO_TOKEN }}

Deploy Repository의 sample.yaml 예시

version: 1 services: ​​web: ​​​​image: "example/webapp:latest" ​​​​ports: ​​​​​​- "80:80" ​​​​environment: ​​​​​​DEBUG: "false" ​​​​​​DATABASE_URL: "postgres://user:password@postgres:5432/dbname" ​​worker: ​​​​image: "example/worker:latest" ​​​​environment: ​​​​​​QUEUE: "tasks" ​​​​​​WORKER_COUNT: "2" databases: ​​postgres: ​​​​image: "postgres:13" ​​​​ports: ​​​​​​- "5432:5432" ​​​​environment: ​​​​​​POSTGRES_USER: "sampe" ​​​​​​POSTGRES_PASSWORD: "password" ​​​​​​POSTGRES_DB: "dbname" networks: ​​default: ​​​​external: ​​​​​​name: "my-custom-network"