Pro Level | Part 4/5

GitLab CI/CD Best Practices

แนวทางปฏิบัติที่ดีที่สุดสำหรับ GitLab CI/CD ครอบคลุม Performance, Security, Cost Optimization และ CI/CD Maturity Model

30 นาที Pro 9 หัวข้อ
Performance Security Cost Maturity

สารบัญ (Table of Contents)

1. Pipeline Performance Optimization

การ optimize pipeline performance เป็นสิ่งสำคัญในการลดเวลารอคอยและเพิ่ม productivity ของทีมพัฒนา เราจะมาดูกันทีละหัวข้อ

Pipeline Performance Optimization Flow

Pipeline Performance Optimization Strategy ❌ Before Optimization Build 5 min Test Unit 4 min Test E2E 8 min Lint 2 min ⚠️ No Cache - npm install every time (+3 min) Total: ~22 minutes Optimize ✅ After Optimization Build 3 min Test Unit 2 min Test E2E 5 min Lint 1 min Security 2 min ✓ Cache enabled - npm install cached Total: ~8 minutes (63% faster!) 🛠️ Key Optimization Techniques 📦 Caching node_modules, vendor Save ~3 min/build ⚡ Parallelization Run jobs simultaneously Save ~7 min/build 🎯 Fail Fast Stop on first failure Quick feedback loop 📊 Analytics Monitor & identify bottlenecks Time Saved 14 min/build Cost Savings (100 builds/day) ~$500/month

1.1 วัดเวลา Pipeline (Pipeline Analytics)

GitLab มี Pipeline Analytics ในตัวสำหรับวัดประสิทธิภาพ pipeline

# เข้าถึง Pipeline Analytics
# Navigate to: CI/CD > Pipelines > Analytics

# ดูข้อมูลที่ได้:
# - Average pipeline duration
# - Success rate
# - Failed jobs breakdown
# - Slowest jobs identification

# ใช้ GitLab API สำหรับดึงข้อมูล
curl --header "PRIVATE-TOKEN: " \
  "https://gitlab.com/api/v4/projects/:id/pipelines?statistics=1"

Tip: ตั้งเป้าหมายลดเวลา pipeline ลง 20-30% จากค่าเฉลี่ยเดิม

1.2 ลดเวลา Build

ใช้ Docker Image ที่เหมาะสม
  • ใช้ slim/alpine images
  • Pre-install dependencies
  • Create custom base images
Minimize Dependencies
  • ใช้ npm ci แทน npm install
  • Remove unused packages
  • Use workspace features
# .gitlab-ci.yml - Build Optimization

build:
  stage: build
  image: node:20-alpine  # ✅ ใช้ alpine (เล็กกว่า 5x)
  before_script:
    - npm ci --prefer-offline --no-audit  # ✅ เร็วกว่า npm install
  script:
    - npm run build
  cache:
    key: ${CI_COMMIT_REF_SLUG}-node
    paths:
      - node_modules/
    policy: pull-push
  variables:
    NODE_ENV: production
    npm_config_cache: "$CI_PROJECT_DIR/.npm"  # ✅ Cache npm downloads

1.3 Parallelization Strategies

Strategy Use Case Example
parallel: แบ่ง job เดียวเป็นหลาย instances Test matrix
matrix: รันหลาย configurations Multi-version testing
needs: DAG pipelines Out-of-order execution
# .gitlab-ci.yml - Parallelization Examples

# 1. Matrix Jobs - ทดสอบหลายเวอร์ชันพร้อมกัน
test:
  stage: test
  image: node:${NODE_VERSION}
  parallel:
    matrix:
      - NODE_VERSION: [18, 20, 22]
        TEST_SUITE: [unit, integration]
  script:
    - npm run test:${TEST_SUITE}
  cache:
    key: ${NODE_VERSION}-${TEST_SUITE}

# 2. DAG Pipeline - รัน jobs ไม่ต้องรอ stage
lint:
  stage: test
  script: npm run lint

test:unit:
  stage: test
  needs: [build]  # ✅ ไม่ต้องรอ lint
  script: npm run test:unit

test:e2e:
  stage: test
  needs: [build]  # ✅ รันพร้อม test:unit
  script: npm run test:e2e

# 3. Parallel Jobs - แบ่งงานเป็นส่วนๆ
test:parallel:
  stage: test
  parallel: 5  # ✅ แบ่งเป็น 5 instances
  script:
    - npm run test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL

1.4 ใช้ Cache อย่างมีประสิทธิภาพ

# .gitlab-ci.yml - Advanced Caching

# Global cache configuration
cache:
  key: ${CI_COMMIT_REF_SLUG}-${CI_JOB_NAME}
  paths:
    - node_modules/
    - .npm/
    - .next/cache/
  policy: pull-push

# Job-specific cache with fallback
variables:
  CACHE_KEY: node-modules-${CI_COMMIT_REF_SLUG}

install:
  stage: build
  cache:
    key: ${CACHE_KEY}
    paths:
      - node_modules/
    policy: pull-push
  script:
    - |
      if [[ -d node_modules ]]; then
        echo "Cache found, checking for updates..."
        npm ci --prefer-offline
      else
        echo "No cache, fresh install..."
        npm ci
      fi

# Read-only cache for downstream jobs
test:
  cache:
    key: ${CACHE_KEY}
    policy: pull  # ✅ ไม่อัพเดท cache
  script:
    - npm test

Warning: อย่า cache sensitive files เช่น .env หรือ credentials

1.5 Fail Fast กับ allow_failure

# .gitlab-ci.yml - Fail Fast Strategy

stages:
  - quick-check
  - build
  - test
  - deploy

# ✅ Quick checks ที่ fail เร็ว
lint:
  stage: quick-check
  script: npm run lint
  allow_failure: false  # ❌ หยุด pipeline ถ้า fail

type-check:
  stage: quick-check
  script: npm run type-check
  allow_failure: false

security:audit:
  stage: quick-check
  script: npm audit
  allow_failure: true   # ⚠️ ให้ผ่านได้แต่แจ้งเตือน

# ✅ Build only if quick checks pass
build:
  stage: build
  needs: [lint, type-check]
  script: npm run build

# ใช้ rules เพื่อ skip งานที่ไม่จำเป็น
deploy:staging:
  stage: deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: manual
  script: npm run deploy:staging
Performance Optimization Checklist

2. YAML Best Practices

2.1 ใช้ Anchors และ Aliases (&, *)

YAML anchors ช่วยลดการ duplicate code และทำให้ maintenance ง่ายขึ้น

# .gitlab-ci.yml - Anchors & Aliases

# ✅ Define reusable configurations
.node_job_template: &node_job_config
  image: node:20-alpine
  before_script:
    - npm ci --cache .npm --prefer-offline
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
      - .npm/

.deploy_template: &deploy_config
  image: alpine:latest
  before_script:
    - apk add --no-cache curl bash
  only:
    - main
    - develop

# ✅ Use aliases to reference configurations
test:unit:
  <<: *node_job_config  # Merge template
  stage: test
  script:
    - npm run test:unit

test:integration:
  <<: *node_job_config
  stage: test
  script:
    - npm run test:integration
  coverage: '/Lines\s*:\s*(\d+.?\d*)%/'

deploy:production:
  <<: *deploy_config
  stage: deploy
  environment:
    name: production
  script:
    - ./deploy.sh production

2.2 YAML extends และ includes

# .gitlab-ci.yml - Extends & Includes

# ✅ Include external templates
include:
  - project: 'my-org/ci-templates'
    ref: main
    file: '/templates/node.yml'
  - project: 'my-org/ci-templates'
    ref: main
    file: '/templates/docker.yml'
  - component: 'my-org/components/security-scanner@1.0'
    inputs:
      severity_level: high

# ✅ Use extends for local inheritance
.build_template:
  script:
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 week

build:app:
  extends: .build_template
  stage: build
  variables:
    APP_ENV: production
  script:
    - echo "Building for $APP_ENV"
    - !reference [.build_template, script]  # Include parent script

2.3 การจัดโครงสร้างไฟล์

project/
├── .gitlab-ci.yml           # Main pipeline file
├── .gitlab/
│   ├── ci-templates/        # Reusable templates
│   │   ├── node.yml
│   │   ├── docker.yml
│   │   └── deploy.yml
│   └── jobs/                # Job definitions
│       ├── build.yml
│       ├── test.yml
│       └── security.yml
└── scripts/
    └── ci/                  # CI scripts
        ├── setup.sh
        └── deploy.sh
# .gitlab-ci.yml - Modular Structure

# Global variables
variables:
  NODE_VERSION: "20"
  DOCKER_REGISTRY: "registry.example.com"

# Include modular components
include:
  - local: '/.gitlab/jobs/build.yml'
  - local: '/.gitlab/jobs/test.yml'
  - local: '/.gitlab/jobs/security.yml'
  - local: '/.gitlab/jobs/deploy.yml'

# Global defaults
default:
  tags:
    - docker
  retry:
    max: 2
    when:
      - runner_system_failure
      - stuck_or_timeout_failure

# Workflow rules
workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"
    - if: $CI_COMMIT_BRANCH == "develop"

2.4 Linting .gitlab-ci.yml

# วิธี lint .gitlab-ci.yml

# 1. ใช้ GitLab CI Lint (UI)
# Navigate to: CI/CD > Editor > Validate

# 2. ใช้ GitLab API
curl --header "PRIVATE-TOKEN: " \
  --header "Content-Type: application/json" \
  --data @.gitlab-ci.yml \
  "https://gitlab.com/api/v4/ci/lint"

# 3. ใช้ gitlab-ci-lint tool
npm install -g gitlab-ci-lint
gitlab-ci-lint .gitlab-ci.yml

# 4. ใช้ pre-commit hook
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/python-jsonschema/check-jsonschema
    rev: 0.28.0
    hooks:
      - id: check-gitlab-ci
        files: \.gitlab-ci\.yml$

3. Security Best Practices

Security is Critical

การรั่วไหลของ credentials สามารถนำไปสู่การโจมตีระบบได้ ต้องปฏิบัติตาม security best practices เสมอ

3.1 ไม่ Hardcode Secrets

❌ ไม่ควรทำ
AWS_KEY=AKIAIOSFODNN7EXAMPLE
DB_PASS=mysecretpass123
✅ ควรทำ
AWS_KEY=$AWS_ACCESS_KEY_ID
DB_PASS=$DATABASE_PASSWORD
# .gitlab-ci.yml - Secure Variable Usage

deploy:
  stage: deploy
  script:
    # ✅ ใช้ variables จาก GitLab
    - echo "Deploying to $DEPLOY_ENV"
    - kubectl config set-credentials deploy-user --token=$K8S_TOKEN
    
    # ❌ อย่าทำแบบนี้!
    # - export PASSWORD="hardcoded-password"
    
    # ✅ ใช้ files สำหรับ sensitive data
    - echo "$SSH_PRIVATE_KEY" | base64 -d > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    
  variables:
    # ✅ Override ใน GitLab UI > Settings > CI/CD > Variables
    DEPLOY_ENV: staging

3.2 ใช้ Protected Variables

Variable Type When to Use Example
Protected Production secrets, deploy keys PROD_DB_PASSWORD
Masked API keys, tokens (single line) API_TOKEN
File SSH keys, certificates SSH_KEY_FILE
# .gitlab-ci.yml - Protected Variables Usage

deploy:production:
  stage: deploy
  rules:
    - if: $CI_COMMIT_REF_NAME == "main"  # ✅ Protected branch only
  script:
    - echo "Deploying to production..."
    # Variables below should be marked as Protected + Masked
    - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
    - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
    - aws s3 sync ./dist s3://$S3_BUCKET
  environment:
    name: production
    url: https://app.example.com

# GitLab UI Setup:
# Settings > CI/CD > Variables > Add Variable
# ☑ Protected (only available on protected branches/tags)
# ☑ Mask (hide in job logs)
# Variable type: File (for multi-line content)

3.3 Scan Vulnerabilities

# .gitlab-ci.yml - Security Scanning

# Enable GitLab Ultimate security features
include:
  - template: Security/SAST.gitlab-ci.yml
  - template: Security/Dependency-Scanning.gitlab-ci.yml
  - template: Security/Container-Scanning.gitlab-ci.yml
  - template: Security/Secret-Detection.gitlab-ci.yml

# Custom security job
security:audit:
  stage: test
  image: node:20-alpine
  script:
    - npm audit --audit-level=high
    - npx better-npm-audit audit --level=high
  allow_failure: true
  artifacts:
    reports:
      dependency_scanning: gl-dependency-scanning-report.json

# Container scanning
container_scan:
  stage: test
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock
      aquasec/trivy image $IMAGE_NAME:$CI_COMMIT_SHA
  allow_failure: true
Security Checklist

4. Cost Optimization

💰 CI/CD Cost Savings

การ optimize อย่างถูกวิธีสามารถลดค่าใช้จ่ายได้ 40-60%

~$500
savings/month

4.1 วัด CI/CD Minutes Usage

# ตรวจสอบ CI/CD minutes usage

# 1. ผ่าน GitLab UI
# Navigate to: Settings > CI/CD > CI/CD minutes

# 2. ผ่าน GitLab API
curl --header "PRIVATE-TOKEN: " \
  "https://gitlab.com/api/v4/namespaces/:id/ci_minutes_usage"

# 3. ตั้ง quota alerts
# Settings > CI/CD > CI/CD minutes > Set notification threshold

# 4. วิเคราะห์ usage ตาม project
curl --header "PRIVATE-TOKEN: " \
  "https://gitlab.com/api/v4/projects/:id/pipelines?statistics=1" \
  | jq '.[] | {duration: .duration, created_at: .created_at}'

4.2 ใช้ Shared Runners อย่างคุ้มค่า

Shared Runners

Pay per minute
Good for variable load

Self-hosted

Fixed cost
Good for high volume

Hybrid

Best of both
Cost optimized

# .gitlab-ci.yml - Runner Optimization

# ใช้ tags เพื่อ route ไปยัง runner ที่เหมาะสม
job:
  tags:
    - self-hosted  # ใช้ self-hosted runner สำหรับงานหนัก
    - linux
    - docker

# ใช้ resource groups เพื่อ limit concurrent jobs
deploy:
  stage: deploy
  resource_group: production  # ✅ Only one deploy at a time
  script:
    - ./deploy.sh

# ใช้ rules เพื่อ skip unnecessary jobs
test:
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
      when: never  # ❌ Skip scheduled pipelines
    - changes:
      - src/**/*.{js,ts}
      - tests/**/*

4.3 Auto-cancel และ Resource Optimization

# .gitlab-ci.yml - Cost Optimization

# Auto-cancel redundant pipelines
workflow:
  rules:
    - if: $CI_COMMIT_BRANCH =~ /^feature\//
      auto_cancel:
        on_new_commit: conservative  # Cancel older pipelines

# Skip unnecessary pipelines
workflow:
  rules:
    # Skip for draft MRs
    - if: $CI_MERGE_REQUEST_TITLE =~ /^(Draft|WIP):/
      when: never
    # Skip for docs-only changes
    - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_MESSAGE =~ /\[skip ci\]/
      when: never
    - when: always

# Use interruptible for long-running jobs
test:e2e:
  interruptible: true  # ✅ Can be cancelled if new commit pushed
  script:
    - npm run test:e2e

# Limit job timeout
build:
  timeout: 15 minutes  # ✅ Prevent runaway jobs
  script:
    - npm run build

# Use needs to start jobs early (less waiting = less runner time)
deploy:staging:
  needs: [build]  # Don't wait for all test jobs
  script:
    - ./deploy.sh staging
Optimization Savings Implementation Effort
Auto-cancel redundant pipelines 20-30% Low
Enable caching 15-25% Low
Skip draft MRs 10-15% Low
Self-hosted runners (high volume) 40-60% Medium
Parallelization Time: 50%+ Medium

5. Code Quality Gates

Code Commit Gate 1 Lint ✓ Format ✓ Type Check ✓ Block if fail Gate 2 Unit Tests ✓ Coverage >80% ✓ Security Scan ✓ Block if fail Gate 3 E2E Tests ✓ Performance ✓ Review ✓ Block if fail 🚀 Deploy
# .gitlab-ci.yml - Quality Gates Configuration

# Quality Gate Stages
stages:
  - quality       # Gate 1: Code Quality
  - test          # Gate 2: Testing
  - security      # Gate 2: Security
  - build
  - deploy

# ============ GATE 1: Code Quality ============
lint:
  stage: quality
  script:
    - npm run lint
  allow_failure: false  # ❌ Block merge if fail

format:check:
  stage: quality
  script:
    - npm run format:check
  allow_failure: false

type-check:
  stage: quality
  script:
    - npm run type-check
  allow_failure: false

# ============ GATE 2: Testing ============
test:unit:
  stage: test
  script:
    - npm run test:unit -- --coverage
  coverage: '/Lines\s*:\s*(\d+.?\d*)%/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: on_success
  allow_failure: false

# Coverage threshold check
coverage:threshold:
  stage: test
  script:
    - |
      COVERAGE=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
      if (( $(echo "$COVERAGE < 80" | bc -l) )); then
        echo "❌ Coverage $COVERAGE% is below 80% threshold"
        exit 1
      fi
      echo "✅ Coverage $COVERAGE% meets threshold"

# ============ GATE 3: Security ============
security:sast:
  stage: security
  include:
    - template: Security/SAST.gitlab-ci.yml
  rules:
    - exists:
      - '**/*.js'
      - '**/*.ts'

# Merge Request Settings
# Settings > Merge requests > Merge checks
# ☑ Pipelines must succeed
# ☑ All discussions must be resolved
# ☑ Require approval (Code Owners)
Metric Threshold Action if Fail
Linting Errors 0 Block
Code Coverage ≥ 80% Block
Security Vulnerabilities (Critical/High) 0 Block
Unit Tests 100% pass Block
Code Review Approval ≥ 1 Block

6. Monitoring & Observability

Pipeline Metrics

~8 min
Avg Duration
95%
Success Rate
12/d
Deploy Freq
15 min
MTTR
# .gitlab-ci.yml - Pipeline Metrics Collection

# Custom metrics reporting
metrics:report:
  stage: .post
  script:
    - |
      echo "📊 Pipeline Metrics:"
      echo "Duration: $CI_PIPELINE_DURATION seconds"
      echo "Jobs: $CI_JOB_TOTAL"
      echo "Status: $CI_PIPELINE_STATUS"
      
      # Send to monitoring system
      curl -X POST $METRICS_ENDPOINT \
        -H "Content-Type: application/json" \
        -d '{
          "pipeline_id": "'$CI_PIPELINE_ID'",
          "duration": "'$CI_PIPELINE_DURATION'",
          "status": "'$CI_PIPELINE_STATUS'",
          "branch": "'$CI_COMMIT_REF_NAME'",
          "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
        }'
  rules:
    - when: always  # Run even on failure

Alerting สำหรับ Failed Pipelines

# .gitlab-ci.yml - Alerting Configuration

# Alert on failure
notify:failure:
  stage: .post
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
      when: on_failure
  script:
    # Slack notification
    - |
      curl -X POST $SLACK_WEBHOOK_URL \
        -H "Content-Type: application/json" \
        -d '{
          "text": "🚨 Pipeline Failed!",
          "blocks": [
            {
              "type": "section",
              "text": {
                "type": "mrkdwn",
                "text": "*Pipeline Failed* on `'"$CI_COMMIT_REF_NAME"'`\nProject: '"$CI_PROJECT_NAME"'\n<'"$CI_PIPELINE_URL"'|View Pipeline>"
              }
            }
          ]
        }'
    
    # Email notification (GitLab built-in)
    # Settings > Integrations > Pipeline status emails

# Alert on long-running pipeline
check:duration:
  stage: .post
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
      when: always
  script:
    - |
      DURATION=$(echo $CI_PIPELINE_DURATION | cut -d'.' -f1)
      if [ "$DURATION" -gt 600 ]; then
        curl -X POST $ALERT_WEBHOOK \
          -d "Pipeline took ${DURATION}s - exceeds 10min threshold"
      fi

GitLab Observability

GitLab Observability (Ultimate) มี features:

  • • Tracing & Distributed Tracing
  • • Metrics & Dashboards
  • • Log Management
  • • Error Tracking
  • • On-call Scheduling

7. Team Collaboration

Merge Request Integration

# .gitlab-ci.yml - MR Integration

# MR-specific jobs
mr:preview:
  stage: deploy
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  environment:
    name: preview/mr-${CI_MERGE_REQUEST_IID}
    url: https://mr-${CI_MERGE_REQUEST_IID}.preview.example.com
    on_stop: mr:preview:stop
  script:
    - ./deploy-preview.sh $CI_MERGE_REQUEST_IID

mr:preview:stop:
  stage: deploy
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: manual
  environment:
    name: preview/mr-${CI_MERGE_REQUEST_IID}
    action: stop
  script:
    - ./cleanup-preview.sh $CI_MERGE_REQUEST_IID

# Report results to MR
report:coverage:
  stage: .post
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - |
      curl -X POST "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes" \
        -H "PRIVATE-TOKEN: $GITLAB_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{"body": "## 📊 Coverage Report\n\n**Coverage:** 85%\n\n[View Full Report]('"$CI_PAGES_URL"'/coverage)"}'

Pipeline Templates สำหรับทีม

Template Structure
ci-templates/
├── node-app.yml
├── react-app.yml
├── docker-build.yml
└── kubernetes-deploy.yml
Usage
include:
  - project: 'org/templates'
    file: '/node-app.yml'

Documentation Best Practices

# .gitlab-ci.yml Documentation Template

# ============================================
# PROJECT: My Awesome App
# DESCRIPTION: CI/CD Pipeline for Node.js app
# MAINTAINER: DevOps Team
# LAST UPDATED: 2026-02-16
# ============================================
#
# WORKFLOW:
# 1. On MR: Run lint, test, preview deploy
# 2. On main: Run full test suite, deploy staging
# 3. On tag: Deploy to production
#
# REQUIRED VARIABLES (set in GitLab UI):
# - AWS_ACCESS_KEY_ID
# - AWS_SECRET_ACCESS_KEY
# - DOCKER_REGISTRY_TOKEN
#
# OPTIONAL VARIABLES:
# - SKIP_E2E: Set to "true" to skip E2E tests
# ============================================

stages:
  - lint
  - test
  - build
  - deploy

# ... rest of pipeline

8. Common Mistakes to Avoid

1

Hardcoding Secrets

❌ ปัญหา: ใส่ passwords, API keys ใน code

API_KEY=sk-abc123...

✅ แก้ไข: ใช้ GitLab CI/CD Variables

API_KEY=$API_KEY
2

Not Using Cache

❌ ปัญหา: npm install ทุกครั้ง +3-5 min/build

✅ แก้ไข: เปิดใช้ cache สำหรับ node_modules, vendor

3

Running All Tests Sequentially

❌ ปัญหา: รัน test ทีละอัน เสียเวลานาน

✅ แก้ไข: ใช้ parallel, matrix, หรือ needs:

4

No Pipeline for Draft MRs

❌ ปัญหา: รัน pipeline ทุก MR แม้ยังไม่พร้อม

✅ แก้ไข: Skip draft MRs ด้วย workflow rules

5

Overly Large Docker Images

❌ ปัญหา: ใช้ image ใหญ่ เช่น node:20 (1GB+)

✅ แก้ไข: ใช้ alpine/slim versions (200MB)

6

No Fail Fast Strategy

❌ ปัญหา: รันต่อแม้ lint fail

✅ แก้ไข: ตั้ง allow_failure: false สำหรับ critical jobs

7

No Resource Limits

❌ ปัญหา: Jobs รันได้นานไม่จำกัด

✅ แก้ไข: ตั้ง timeout สำหรับแต่ละ job

8

Missing Quality Gates

❌ ปัญหา: merge code ได้โดยไม่ต้องผ่าน tests

✅ แก้ไข: ตั้ง "Pipelines must succeed" ใน MR settings

9

Not Using DAG Pipelines

❌ ปัญหา: รอทุก job ใน stage เสร็จก่อน stage ถัดไป

✅ แก้ไข: ใช้ needs: เพื่อ start jobs ทันทีที่ dependencies พร้อม

10

No Security Scanning

❌ ปัญหา: Deploy code ที่มี vulnerabilities

✅ แก้ไข: เปิด SAST, Dependency Scanning, Container Scanning

9. CI/CD Maturity Model

CI/CD Maturity Model ช่วยประเมินระดับความพร้อมของกระบวนการ CI/CD ในองค์กร และวางแผนพัฒนาได้อย่างเป็นระบบ

CI/CD Maturity Model - 5 Levels Level 1: Initial 1 Characteristics: • Manual deployments • No automation • Frequent errors • No documentation Deployment Freq: < 1/week Level 2: Managed 2 Characteristics: • Basic CI pipeline • Automated tests • Manual deploys • Basic docs Deployment Freq: 1-2/week Level 3: Defined 3 Characteristics: • CI/CD pipeline • Auto staging deploys • Code quality gates • Team standards Deployment Freq: 1-2/day Level 4: Measured 4 Characteristics: • Full automation • Metrics & monitoring • Security scanning • Performance gates Deployment Freq: Multiple/day Level 5: Optimizing 5 Characteristics: • Continuous optim. • AI/ML enhancements • Predictive analytics • Self-healing Deployment Freq: On-demand Maturity Progression 📋 Self-Assessment Checklist ✓ Automation ☐ Build automation ☐ Test automation ☐ Deploy automation ☐ Infrastructure as Code ✓ Quality ☐ Code review ☐ Quality gates ☐ Coverage tracking ☐ Security scanning ✓ Process ☐ Documentation ☐ Team training ☐ Incident response ☐ Continuous improvement Scoring Guide 0-3 items: Level 1-2 4-6 items: Level 2-3 7-9 items: Level 3-4 10-12 items: Level 4-5 🎯 🚀 Level Progression Path Level 1 → 2: • Setup basic CI pipeline • Add automated tests Level 2 → 3: • Implement CD pipeline • Add quality gates Level 3 → 4: • Add metrics & monitoring • Implement security scanning Level 4 → 5: • Continuous optimization • AI/ML integration 💡 Tip: Focus on one level at a time. Each level takes 3-6 months.
Criteria Level 1 Level 2 Level 3 Level 4 Level 5
Build Process Manual Semi-auto Automated Optimized Intelligent
Testing Ad-hoc Unit tests Full suite Gated AI-driven
Deployment Manual Scripts CD Pipeline Blue-green Canary+AI
Monitoring None Basic logs Dashboards Alerts Predictive
Security None Manual Scanning Gated Shift-left

สรุป (Summary)

🎯 Key Takeaways

  • Optimize pipeline performance ด้วย caching, parallelization
  • ใช้ YAML best practices: anchors, extends, includes
  • Security first: ไม่ hardcode, ใช้ protected variables
  • Cost optimization: auto-cancel, resource limits
  • Quality gates: lint, test, coverage, security

📚 Next Steps

  • 1 ประเมิน CI/CD maturity level ปัจจุบัน
  • 2 เลือก 2-3 best practices มา implement ก่อน
  • 3 วัดผลและปรับปรุงอย่างต่อเนื่อง
  • 4 อ่าน Part 5: Advanced Topics