Skip to content

✍️ 필사 모드: Advanced CI/CD Pipeline Guide — GitHub Actions, ArgoCD, Tekton, and Security Pipelines

English
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

Introduction

Have you ever moved past understanding CI/CD as simply "code gets deployed automatically when pushed" and considered what a production-grade pipeline truly requires? In real production environments, dozens of stages must be orchestrated seamlessly: security scanning, static analysis, container image signing, multi-cluster deployments, and automated rollbacks.

This guide covers everything from CI/CD maturity models to advanced GitHub Actions patterns, ArgoCD GitOps, Tekton cloud-native pipelines, DevSecOps security pipelines, and advanced deployment strategies.


1. CI/CD Maturity Model

A five-level maturity model for objectively assessing your organization's CI/CD capabilities. Each level builds upon the previous one.

Level 1 - Manual

Developers perform builds and deployments manually. Building locally and deploying to servers via FTP or SCP. "It works on my machine" is a daily occurrence, and deployment cycles are often monthly.

Characteristics: Documented procedures may exist, but almost no automation. Human errors during deployment are frequent, and rollbacks involve manually redeploying previous versions.

Level 2 - Basic Automation

A CI server is introduced, and automatic builds and tests run on code pushes. Tools like Jenkins, GitHub Actions, or GitLab CI are used, but the pipeline is a simple linear build-test-deploy structure.

# Level 2: Basic pipeline example
name: Basic CI/CD
on:
  push:
    branches: [main]
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm install
      - run: npm test
      - run: npm run build
      - run: ./deploy.sh

Level 3 - Standardized

Pipelines are standardized across the organization with reusable templates. Test coverage gates, code quality checks, and security scans are included by default. Environment-specific (dev, staging, prod) deployment pipelines are separated.

Level 4 - Advanced Automation

GitOps-based declarative deployments, canary/blue-green deployment strategies, automated security pipelines (SAST, DAST, container scanning), and SBOM generation with artifact signing are integrated into the pipeline. Deployment cycles shrink to sub-daily.

Level 5 - Self-Healing

Metric-based automatic rollbacks, SLO violation auto-recovery, ML-based anomaly detection, and production feedback automatically fed back into the pipeline. Deployments are fully automated so developers never think about deploying.

LevelDeploy CycleRollbackSecurityTesting
L1 ManualMonthlyManual redeployNoneManual
L2 BasicWeeklyManual triggerNoneAuto unit
L3 StandardDailyOne-clickBasic scansUnit + Integration
L4 AdvancedHourlyAuto canaryFull pipelineUnit + Integration + E2E
L5 HealingContinuousSLO-based autoContinuous validationIncludes chaos

2. Advanced GitHub Actions Patterns

Advanced patterns that go beyond GitHub Actions basics.

2-1. Reusable Workflows

To share identical pipeline logic across multiple repositories, use reusable workflows. The calling side references external workflows with the uses keyword.

# .github/workflows/reusable-build.yml (shared repository)
name: Reusable Build
on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: '20'
      registry-url:
        required: true
        type: string
    secrets:
      npm-token:
        required: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
          registry-url: ${{ inputs.registry-url }}
      - run: npm ci
        env:
          NODE_AUTH_TOKEN: ${{ secrets.npm-token }}
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: dist/
# Calling workflow
name: App CI
on: [push]
jobs:
  call-build:
    uses: my-org/shared-workflows/.github/workflows/reusable-build.yml@v2
    with:
      node-version: '20'
      registry-url: 'https://npm.pkg.github.com'
    secrets:
      npm-token: ${{ secrets.NPM_TOKEN }}

2-2. Composite Actions

A pattern for bundling multiple steps within a single action for reuse. Unlike reusable workflows, these are inserted as steps within a single job.

# .github/actions/setup-and-test/action.yml
name: 'Setup and Test'
description: 'Set up Node.js environment and run tests'
inputs:
  node-version:
    description: 'Node.js version'
    required: false
    default: '20'
runs:
  using: 'composite'
  steps:
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: 'npm'
    - run: npm ci
      shell: bash
    - run: npm test -- --coverage
      shell: bash
    - uses: actions/upload-artifact@v4
      with:
        name: coverage
        path: coverage/

2-3. Matrix Build Strategy

An advanced matrix configuration that tests multiple environment combinations in parallel while excluding unnecessary ones.

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [18, 20, 22]
        exclude:
          - os: macos-latest
            node: 18
        include:
          - os: ubuntu-latest
            node: 22
            experimental: true
    runs-on: ${{ matrix.os }}
    continue-on-error: ${{ matrix.experimental || false }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci
      - run: npm test

2-4. Cloud Authentication with OIDC

Instead of long-lived secrets (Access Keys), use OIDC (OpenID Connect) tokens to securely authenticate with cloud providers. AWS, GCP, and Azure all support this.

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-actions-role
          aws-region: us-east-1
      - run: aws s3 sync ./dist s3://my-bucket
      - run: aws cloudfront create-invalidation --distribution-id E1234 --paths "/*"

The key advantage of OIDC is eliminating secret management. GitHub issues a short-lived token that AWS STS validates to issue temporary credentials. The token is only valid during workflow execution, making leaked tokens difficult to exploit.


3. GitOps and ArgoCD

3-1. GitOps Principles

GitOps is an operational model that uses Git as the single source of truth for managing the declarative state of infrastructure and applications. Four core principles define it.

Declarative configuration: Describe the desired system state declaratively. Define "what" you want, not "how" to achieve it.

Git as the source of truth: All changes go through Git, and Git history serves as the audit log.

Automatic application: When the declarative state in Git changes, it is automatically applied to the system.

Continuous reconciliation: An agent continuously compares actual state to desired state and corrects any drift.

3-2. ArgoCD Architecture

ArgoCD is a declarative GitOps continuous delivery tool for Kubernetes.

# ArgoCD Application resource
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/k8s-manifests.git
    targetRevision: main
    path: apps/my-app/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: my-app
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

When syncPolicy.automated is configured, Git changes are automatically reflected in the cluster. selfHeal: true means that if someone manually modifies the cluster state, it automatically reverts to the Git state.

3-3. App of Apps Pattern

In large environments with dozens to hundreds of Applications to manage, the App of Apps pattern uses a single root Application that manages all the others.

# root-app.yaml - Root that manages other Applications
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/argocd-apps.git
    targetRevision: main
    path: apps
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
# apps/frontend.yaml - Child Application managed by root
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: frontend
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/k8s-manifests.git
    path: apps/frontend/overlays/production
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: frontend

3-4. Multi-Cluster Deployment with ApplicationSet

ApplicationSet is an ArgoCD feature that automatically generates multiple Applications from a single template, based on cluster lists, Git directories, or PR events.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: my-app-set
  namespace: argocd
spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: production
  template:
    metadata:
      name: 'my-app-{{name}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/my-org/k8s-manifests.git
        targetRevision: main
        path: 'apps/my-app/overlays/{{metadata.labels.region}}'
      destination:
        server: '{{server}}'
        namespace: my-app

4. Tekton Pipelines

4-1. What is Tekton

Tekton is a Kubernetes-native CI/CD framework. Unlike GitHub Actions or Jenkins, all pipeline components are defined as Kubernetes Custom Resources (CRDs). Each task runs as a separate Pod, providing complete isolation and scalability.

Core components:

  • Task: An execution unit composed of one or more Steps. Maps to a single Pod.
  • Pipeline: A DAG (Directed Acyclic Graph) workflow connecting multiple Tasks.
  • TaskRun / PipelineRun: Execution instances of a Task or Pipeline. Trackable as Kubernetes resources.
  • Workspace: Volumes for sharing data between Tasks.

4-2. Task Definition

apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: build-and-push
spec:
  params:
    - name: image-url
      type: string
    - name: image-tag
      type: string
      default: latest
  workspaces:
    - name: source
  steps:
    - name: build
      image: gcr.io/kaniko-project/executor:latest
      args:
        - --dockerfile=Dockerfile
        - --context=$(workspaces.source.path)
        - --destination=$(params.image-url):$(params.image-tag)
        - --cache=true
        - --cache-ttl=24h

4-3. Pipeline Definition

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: ci-pipeline
spec:
  params:
    - name: repo-url
      type: string
    - name: image-url
      type: string
  workspaces:
    - name: shared-workspace
  tasks:
    - name: fetch-source
      taskRef:
        name: git-clone
      workspaces:
        - name: output
          workspace: shared-workspace
      params:
        - name: url
          value: $(params.repo-url)

    - name: run-tests
      taskRef:
        name: npm-test
      runAfter:
        - fetch-source
      workspaces:
        - name: source
          workspace: shared-workspace

    - name: build-image
      taskRef:
        name: build-and-push
      runAfter:
        - run-tests
      workspaces:
        - name: source
          workspace: shared-workspace
      params:
        - name: image-url
          value: $(params.image-url)

    - name: security-scan
      taskRef:
        name: trivy-scan
      runAfter:
        - build-image
      params:
        - name: image-url
          value: $(params.image-url)

4-4. Executing with PipelineRun

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  generateName: ci-pipeline-run-
spec:
  pipelineRef:
    name: ci-pipeline
  params:
    - name: repo-url
      value: https://github.com/my-org/my-app.git
    - name: image-url
      value: ghcr.io/my-org/my-app
  workspaces:
    - name: shared-workspace
      volumeClaimTemplate:
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 1Gi

5. Security Pipeline (DevSecOps)

5-1. Security Pipeline Components

A production-grade security pipeline automatically performs the following stages.

StageToolsPurpose
SAST (Static Analysis)SonarQube, Semgrep, CodeQLDetect source code vulnerabilities
SCA (Dependency Analysis)Snyk, Dependabot, OWASP DCDetect open-source dependency vulnerabilities
Secret ScanningGitLeaks, TruffleHogDetect secrets embedded in code
Container ScanningTrivy, GrypeDetect container image vulnerabilities
DAST (Dynamic Analysis)OWASP ZAP, NucleiDetect running application vulnerabilities
SBOM GenerationSyft, CycloneDXGenerate software component inventory
Artifact SigningCosign, NotationEnsure build artifact integrity

5-2. SAST - SonarQube Integration

# SonarQube analysis in GitHub Actions
name: Security Pipeline
on: [push, pull_request]

jobs:
  sast:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: SonarSource/sonarqube-scan-action@v3
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
        with:
          args: >
            -Dsonar.projectKey=my-project
            -Dsonar.sources=src/
            -Dsonar.tests=tests/
            -Dsonar.coverage.exclusions=**/*.test.ts
      - uses: SonarSource/sonarqube-quality-gate-check@v1
        timeout-minutes: 5
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

5-3. Container Image Scanning - Trivy

  container-scan:
    runs-on: ubuntu-latest
    needs: [build]
    steps:
      - uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'ghcr.io/my-org/my-app:latest'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'

Trivy scans both OS packages and language-specific dependencies. Setting exit-code: '1' causes the pipeline to fail when CRITICAL or HIGH vulnerabilities are found.

5-4. SBOM Generation and Cosign Signing

SBOM (Software Bill of Materials) is a complete inventory of all components in the software. Following US Executive Order 14028, it has become an essential element of supply chain security.

  sbom-and-sign:
    runs-on: ubuntu-latest
    needs: [container-scan]
    permissions:
      id-token: write
      packages: write
    steps:
      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          image: ghcr.io/my-org/my-app:latest
          format: spdx-json
          output-file: sbom.spdx.json

      - name: Install Cosign
        uses: sigstore/cosign-installer@v3

      - name: Sign Container Image
        run: |
          cosign sign --yes \
            ghcr.io/my-org/my-app:latest

      - name: Attach SBOM to Image
        run: |
          cosign attach sbom \
            --sbom sbom.spdx.json \
            ghcr.io/my-org/my-app:latest

Cosign is part of the Sigstore project and supports keyless signing. It uses OIDC tokens to sign images without requiring separate signing key management.

5-5. Secret Scanning - GitLeaks

  secret-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

6. Test Automation Strategy

6-1. The Test Pyramid

In production CI/CD, the types and proportions of tests matter.

Unit Tests (70%): Should be the fastest and most numerous. Test individual functions, methods, and components in isolation.

Integration Tests (20%): Verify that multiple modules work together correctly. Test interactions with external dependencies like databases, APIs, and message queues.

E2E Tests (10%): Validate user scenarios from start to finish. Slowest and most brittle, so only test core flows.

6-2. Parallel Testing and Test Splitting

Strategies for reducing execution time of large test suites.

jobs:
  test:
    strategy:
      matrix:
        shard: [1, 2, 3, 4]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - name: Run Tests (Shard ${{ matrix.shard }}/4)
        run: |
          npx jest --shard=${{ matrix.shard }}/4 \
            --ci --coverage --forceExit
      - uses: actions/upload-artifact@v4
        with:
          name: coverage-${{ matrix.shard }}
          path: coverage/

  merge-coverage:
    needs: [test]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          pattern: coverage-*
          merge-multiple: true
      - name: Merge Coverage Reports
        run: npx istanbul-merge --out merged-coverage.json coverage-*/coverage-final.json

6-3. Playwright E2E Testing

  e2e:
    runs-on: ubuntu-latest
    needs: [deploy-staging]
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      - name: Run E2E Tests
        run: npx playwright test --reporter=html
        env:
          BASE_URL: https://staging.my-app.com
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

7. Advanced Deployment Strategies

7-1. Canary Deployments with Argo Rollouts

Argo Rollouts is a controller that implements advanced deployment strategies in Kubernetes. It provides a Rollout resource that replaces the standard Deployment.

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app
spec:
  replicas: 10
  strategy:
    canary:
      canaryService: my-app-canary
      stableService: my-app-stable
      trafficRouting:
        istio:
          virtualServices:
            - name: my-app-vsvc
              routes:
                - primary
      steps:
        - setWeight: 5
        - pause:
            duration: 5m
        - setWeight: 20
        - pause:
            duration: 5m
        - setWeight: 50
        - pause:
            duration: 10m
        - setWeight: 80
        - pause:
            duration: 5m
      analysis:
        templates:
          - templateName: success-rate
        startingStep: 2
        args:
          - name: service-name
            value: my-app-canary
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: ghcr.io/my-org/my-app:v2.0.0
          ports:
            - containerPort: 8080

7-2. AnalysisTemplate - Metric-Based Automated Decisions

During canary deployment, query Prometheus metrics to automatically decide whether to promote or abort (rollback).

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
    - name: service-name
  metrics:
    - name: success-rate
      interval: 60s
      successCondition: result[0] >= 0.95
      failureLimit: 3
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{
              service="{{args.service-name}}",
              status=~"2.."
            }[5m])) /
            sum(rate(http_requests_total{
              service="{{args.service-name}}"
            }[5m]))

If three consecutive analyses show a success rate below 95%, an automatic rollback is triggered. This is the core of Level 5 self-healing pipelines.

7-3. Blue-Green Deployment

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-app-bluegreen
spec:
  replicas: 5
  strategy:
    blueGreen:
      activeService: my-app-active
      previewService: my-app-preview
      autoPromotionEnabled: false
      prePromotionAnalysis:
        templates:
          - templateName: smoke-test
      postPromotionAnalysis:
        templates:
          - templateName: success-rate
      scaleDownDelaySeconds: 300
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: ghcr.io/my-org/my-app:v2.0.0

In blue-green deployment, after the new version (green) is fully ready, all traffic switches at once. prePromotionAnalysis runs smoke tests before the switch, and scaleDownDelaySeconds keeps the old version for a period to enable quick rollback.

7-4. Traffic Mirroring (Shadow Traffic)

A technique that replicates real production traffic to the new version for testing under actual load, but does not deliver the new version's responses to users.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: my-app
spec:
  hosts:
    - my-app.example.com
  http:
    - route:
        - destination:
            host: my-app-stable
            port:
              number: 80
      mirror:
        host: my-app-canary
        port:
          number: 80
      mirrorPercentage:
        value: 100.0

8. Multi-Environment Management

8-1. Environment Structure Design

Production pipelines operate a minimum of three environments.

  • dev: Feature branch deployments for developers. Instability is acceptable.
  • staging: Main branch deployments. Must have identical configuration to production.
  • production: The environment serving real user traffic.

8-2. Kustomize Overlays

Kustomize is a tool for customizing Kubernetes manifests per environment. It applies environment-specific overlays on top of a base configuration.

k8s/
  base/
    deployment.yaml
    service.yaml
    kustomization.yaml
  overlays/
    dev/
      kustomization.yaml
      replica-patch.yaml
    staging/
      kustomization.yaml
      replica-patch.yaml
    production/
      kustomization.yaml
      replica-patch.yaml
      hpa.yaml
# k8s/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - service.yaml
# k8s/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
  - hpa.yaml
patches:
  - path: replica-patch.yaml
namePrefix: prod-
commonLabels:
  env: production
# k8s/overlays/production/replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 5
  template:
    spec:
      containers:
        - name: my-app
          resources:
            requests:
              cpu: 500m
              memory: 512Mi
            limits:
              cpu: 1000m
              memory: 1Gi

8-3. Helm Values Per Environment

# values-dev.yaml
replicaCount: 1
image:
  tag: latest
resources:
  requests:
    cpu: 100m
    memory: 128Mi
ingress:
  host: dev.my-app.internal
autoscaling:
  enabled: false
# values-production.yaml
replicaCount: 5
image:
  tag: v2.0.0
resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: 1000m
    memory: 1Gi
ingress:
  host: my-app.example.com
  tls: true
autoscaling:
  enabled: true
  minReplicas: 5
  maxReplicas: 20
  targetCPU: 70
# Deploy per environment
helm upgrade --install my-app ./chart \
  -f values-production.yaml \
  --namespace production \
  --wait --timeout 5m

9. Monitoring and Rollback

9-1. Post-Deployment Monitoring Checklist

Core metrics to verify immediately after deployment.

Immediate check (0-5 minutes):

  • Pod status: Are all Pods in Running/Ready state
  • Error logs: Have exceptions surged in the new version
  • Health checks: Are readiness/liveness probes healthy

Short-term check (5-30 minutes):

  • Response time: Are p50, p95, p99 latencies similar to the previous version
  • Error rate: Is the 5xx rate within threshold
  • Throughput: Is request throughput in the expected range

Medium-term check (30 minutes to hours):

  • Memory usage: Any signs of memory leaks
  • CPU usage: Is CPU utilization stable
  • Business metrics: Are orders, conversion rates, etc. normal

9-2. Prometheus-Based Automatic Rollback

# PrometheusRule - Automatic rollback trigger
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: deployment-rollback-rules
spec:
  groups:
    - name: deployment-health
      rules:
        - alert: HighErrorRate
          expr: |
            sum(rate(http_requests_total{status=~"5.."}[5m]))
            /
            sum(rate(http_requests_total[5m]))
            > 0.05
          for: 2m
          labels:
            severity: critical
            action: rollback
          annotations:
            summary: "Error rate above 5 percent for 2 minutes"

        - alert: HighLatency
          expr: |
            histogram_quantile(0.99,
              sum(rate(http_request_duration_seconds_bucket[5m])) by (le)
            ) > 2
          for: 3m
          labels:
            severity: critical
            action: rollback
          annotations:
            summary: "p99 latency above 2 seconds for 3 minutes"

9-3. SLO-Based Deployment Gates

Use Service Level Objectives (SLOs) as the basis for deployment decisions. When the error budget is exhausted, halt deployments.

# SLO definition example
apiVersion: sloth.slok.dev/v1
kind: PrometheusServiceLevel
metadata:
  name: my-app-slo
spec:
  service: my-app
  labels:
    team: platform
  slos:
    - name: requests-availability
      objective: 99.9
      sli:
        events:
          errorQuery: sum(rate(http_requests_total{status=~"5.."}[5m]))
          totalQuery: sum(rate(http_requests_total[5m]))
      alerting:
        name: MyAppAvailability
        pageAlert:
          labels:
            severity: critical
        ticketAlert:
          labels:
            severity: warning

Here is how error budget calculation works. With a 99.9% SLO, roughly 43 minutes of downtime are allowed per month. If 30 minutes have already been consumed, the remaining 13 minutes of error budget mean risky deployments should not proceed.


10. Production Pipeline Architecture in Practice

10-1. Overall Architecture

A complete production-grade CI/CD pipeline follows this structure.

Developer Code Push
    |
    v
[CI Stage - GitHub Actions]
    |-- Code checkout
    |-- Dependency install (with caching)
    |-- Lint + format check
    |-- Unit tests (parallel 4 shards)
    |-- Integration tests
    |-- SAST (SonarQube)
    |-- Secret scanning (GitLeaks)
    |-- Dependency vulnerability scan (Snyk)
    |-- Container build (Kaniko)
    |-- Container scan (Trivy)
    |-- SBOM generation (Syft)
    |-- Image signing (Cosign)
    |-- Image registry push
    |
    v
[CD Stage - ArgoCD / GitOps]
    |-- Manifest repo auto-update
    |-- ArgoCD sync
    |-- dev auto-deploy
    |-- staging auto-deploy
    |-- E2E tests (Playwright)
    |-- DAST (OWASP ZAP)
    |
    v
[Production Deploy - Argo Rollouts]
    |-- Canary 5% deploy
    |-- Metric analysis (AnalysisTemplate)
    |-- Canary increase to 20%
    |-- Re-analysis
    |-- Canary increase to 50%
    |-- Final analysis
    |-- 100% promotion or automatic rollback
    |
    v
[Monitoring - Prometheus / Grafana]
    |-- SLO dashboard
    |-- Error budget tracking
    |-- Automatic rollback alerts

10-2. Pipeline Optimization Tips

Caching strategy: Cache dependency installation, Docker layers, and test results to reduce pipeline time by over 50%.

- uses: actions/cache@v4
  with:
    path: |
      ~/.npm
      node_modules
    key: deps-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      deps-

Conditional execution: Run only relevant tasks based on changed files to prevent unnecessary builds.

- uses: dorny/paths-filter@v3
  id: changes
  with:
    filters: |
      backend:
        - 'src/api/**'
        - 'src/models/**'
      frontend:
        - 'src/components/**'
        - 'src/pages/**'
      infra:
        - 'terraform/**'
        - 'k8s/**'

Parallelization: Run independent tasks in parallel. Linting, testing, and security scans do not depend on each other and can run concurrently.

10-3. Pipeline Metrics

The pipeline itself must also be measured.

MetricDescriptionTarget
Lead TimeTime from commit to production deployUnder 1 hour
Deploy FrequencyProduction deploys per day10+ per day
Change Failure RatePercentage of deploys requiring rollbackUnder 5%
MTTRTime to recover from incidentsUnder 30 minutes
Pipeline Execution TimeTotal CI timeUnder 15 minutes
Test CoverageCode coverage percentageOver 80%

These are the core of DORA metrics (Lead Time, Deploy Frequency, Change Failure Rate, MTTR). Elite-performing teams achieve top rankings across all four metrics.


Conclusion

A CI/CD pipeline is not just an automation tool but critical infrastructure that determines software quality and development velocity. Here is a summary of everything covered.

  1. Assess your current level against the maturity model. Do not aim for Level 5 all at once; build capabilities incrementally.
  2. Design reusable pipelines. Use GitHub Actions reusable workflows and Composite Actions to standardize pipelines across your organization.
  3. Adopt GitOps. Implementing declarative deployments with tools like ArgoCD gives you audit trails, automatic recovery, and consistency.
  4. Embed security in the pipeline. DevSecOps is not a separate stage but security woven into every stage of the pipeline.
  5. Make metric-based decisions. Use SLOs and error budgets to quantitatively manage deployment risk.
  6. Track DORA metrics. Continuously improve the performance of the pipeline itself.

Production-grade CI/CD is not built overnight. But by understanding each component and introducing them incrementally, your team's deployment capabilities will improve dramatically.

현재 단락 (1/816)

Have you ever moved past understanding CI/CD as simply "code gets deployed automatically when pushed...

작성 글자: 0원문 글자: 23,770작성 단락: 0/816