Architecture Overview / ภาพรวมสถาปัตยกรรม
1 บทนำ - GitLab CI/CD Components คืออะไร
GitLab CI/CD Components คือ reusable units ของ CI/CD configuration ที่สามารถนำกลับมาใช้ใหม่ได้ในหลายๆ project โดยไม่ต้อง copy-paste YAML ซ้ำๆ เป็น feature ใหม่ใน GitLab 16+ และปรับปรุงมากขึ้นใน GitLab 18+
Component คืออะไร
เป็น single YAML file ที่อยู่ในโฟลเดอร์ templates/ ของ project ประกอบด้วย jobs, scripts, variables ที่สามารถ reuse ได้
Catalog คืออะไร
เป็น centralized registry ของ components ที่คุณสามารถค้นหา, browse และ include เข้ามาใช้ใน project ของคุณได้
ประโยชน์หลัก
- • DRY Principle - ไม่ต้อง repeat code ซ้ำ
- • Easy Maintenance - แก้ไขที่เดียว ใช้ได้ทุกที่
- • Version Control - จัดการ version ได้ชัดเจน
- • Share & Reuse - แชร์ระหว่างทีมหรือ public ได้
2 ทำไมต้องใช้ Components (แทน copy-paste YAML)
ปัญหาใหญ่ของการทำ CI/CD แบบดั้งเดิมคือการ copy-paste YAML ระหว่าง projects ทำให้เกิดปัญหาตามมามากมาย
Copy-Paste
50 projects = แก้ 50 ครั้ง
Components
50 projects = แก้ 1 ครั้ง
Efficiency
ลดเวลา 80%
3 การสร้าง Component ของตัวเอง
การสร้าง Component ต้องมีโครงสร้างโฟลเดอร์ที่ถูกต้องและ syntax เฉพาะ
โครงสร้างโฟลเดอร์
my-component-project/
├── templates/
│ ├── secret-detection.yml # Component 1
│ ├── docker-build.yml # Component 2
│ └── deploy-k8s.yml # Component 3
├── README.md # Documentation
└── .gitlab-ci.yml # Test pipeline
ตัวอย่าง Component File
# templates/docker-build.yml
# ระบุ spec สำหรับ inputs
spec:
inputs:
stage:
default: build
description: "Stage ที่จะ run job"
image-name:
default: $CI_REGISTRY_IMAGE
description: "ชื่อ Docker image"
dockerfile:
default: Dockerfile
description: "Path ไป Dockerfile"
tags:
default: ["docker"]
type: array
description: "Runner tags"
---
# Component implementation
build-image:
stage: $[[ inputs.stage ]]
image: docker:24
services:
- docker:24-dind
tags: $[[ inputs.tags ]]
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $[[ inputs.image-name ]]:$CI_COMMIT_SHA -f $[[ inputs.dockerfile ]] .
- docker push $[[ inputs.image-name ]]:$CI_COMMIT_SHA
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
สิ่งสำคัญ: Component file ต้องขึ้นต้นด้วย spec: block และมี --- separator ก่อน implementation
4 CI/CD Catalog - ค้นหาและใช้งาน
CI/CD Catalog เป็น centralized place สำหรับค้นหาและใช้ components ที่คนอื่นสร้างไว้ สามารถเข้าถึงได้ที่ gitlab.com/explore/catalog
วิธีใช้ Component จาก Catalog
# .gitlab-ci.yml
include:
# Include component จาก GitLab Catalog
- component: $CI_SERVER_FQDN/components/secret-detection@1.0.0
inputs:
stage: security
# Include component จาก private project
- component: $CI_SERVER_FQDN/my-org/shared-components/docker-build@2.1.0
inputs:
stage: build
image-name: $CI_REGISTRY_IMAGE/app
dockerfile: Dockerfile.prod
stages:
- security
- build
- test
- deploy
Public Catalog
Components จาก GitLab และ community ที่เข้าถึงได้ฟรี
Private Catalog
Components ภายในองค์กรที่ share ระหว่าง projects
5 Component Inputs และ Parameters
Inputs ทำให้ components มีความยืดหยุ่น สามารถปรับแต่งได้ตามความต้องการของแต่ละ project
ประเภทของ Inputs
# templates/deploy.yml
spec:
inputs:
# String input พร้อม default
stage:
default: deploy
description: "Stage name for deployment"
# String ที่จำเป็นต้องระบุ
environment:
description: "Target environment (required)"
# Array input
tags:
type: array
default: ["kubernetes"]
# Boolean input
enable-cache:
type: boolean
default: true
# Number input
replicas:
type: number
default: 2
# Options (enum)
strategy:
type: string
options:
- rolling
- blue-green
- canary
default: rolling
---
deploy:
stage: $[[ inputs.stage ]]
tags: $[[ inputs.tags ]]
script:
- kubectl set image deployment/app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- kubectl scale deployment/app --replicas=$[[ inputs.replicas ]]
environment:
name: $[[ inputs.environment ]]
การใช้งาน Inputs
# .gitlab-ci.yml ของ project ที่ใช้ component
include:
- component: $CI_SERVER_FQDN/my-org/deploy-component@1.0.0
inputs:
stage: deploy-prod
environment: production
replicas: 5
strategy: blue-green
tags:
- kubernetes
- production
enable-cache: false
Tip: ใช้ $[[ inputs.name ]] syntax เพื่ออ้างถึง input values ใน component
6 ตัวอย่าง Components ยอดนิยม
Components ที่ใช้บ่อยในโปรเจคส่วนใหญ่
Secret Detection
ตรวจจับ secrets ที่ leak
include:
- component: $CI_SERVER_FQDN/components/secret-detection@1.0.0
inputs:
stage: security
Docker Build
Build และ push Docker images
include:
- component: $CI_SERVER_FQDN/components/docker-build@2.0.0
inputs:
stage: build
image-name: $CI_REGISTRY_IMAGE
SAST
Static Application Security Testing
include:
- component: $CI_SERVER_FQDN/components/sast@1.0.0
inputs:
stage: test
Kubernetes Deploy
Deploy ไปยัง Kubernetes cluster
include:
- component: $CI_SERVER_FQDN/components/k8s-deploy@1.0.0
inputs:
stage: deploy
namespace: production
7 Best Practices
Semantic Versioning
ใช้ semantic versioning (1.0.0, 1.1.0, 2.0.0) สำหรับ components เพื่อให้ผู้ใช้สามารถ lock version ได้
# แนะนำ: lock version
- component: .../my-component@1.2.3
# หรือใช้ major version only
- component: .../my-component@1
# หลีกเลี่ยง: ไม่ lock version
- component: .../my-component # อันตราย!
Documentation ครบถ้วน
เขียน README.md ที่อธิบาย inputs, outputs, และตัวอย่างการใช้งาน
Default Values
กำหนด default values สำหรับ inputs ที่ไม่จำเป็นต้องระบุ เพื่อให้ใช้งานง่าย
Test Components
สร้าง test pipeline ใน component project เพื่อทดสอบว่า component ทำงานถูกต้อง
Single Responsibility
แต่ละ component ควรทำหน้าที่เดียว เช่น build, test, deploy แยกกัน
8 การใช้งานในองค์กรไทย
สำหรับองค์กรในประเทศไทย สามารถประยุกต์ใช้ Components ได้หลายแบบ
ตัวอย่าง Components สำหรับองค์กรไทย
# templates/line-notify.yml - ส่ง notification ไป LINE
spec:
inputs:
stage:
default: notify
message:
description: "ข้อความที่จะส่ง"
token-variable:
default: LINE_NOTIFY_TOKEN
description: "Environment variable ที่เก็บ token"
---
notify-line:
stage: $[[ inputs.stage ]]
image: curlimages/curl
script:
- |
curl -X POST https://notify-api.line.me/api/notify \
-H "Authorization: Bearer ${$[[ inputs.token-variable ]]}" \
-d "message=$[[ inputs.message ]]"
rules:
- when: on_success
ทำไมต้องมี
- • มาตรฐานเดียวกัน
- • สอบบัญชีง่าย
- • PDPA compliant
ตัวอย่าง
- • line-notify
- • thaicompliance-check
- • slack-thai-msg
เริ่มต้น
- • สร้าง shared repo
- • เขียน components
- • Share ทั้งองค์กร
9 Troubleshooting / แก้ไขปัญหาที่พบบ่อย
Component not found
สาเหตุ: Path หรือ version ไม่ถูกต้อง
# ตรวจสอบ format
- component: $CI_SERVER_FQDN/group/project/component-name@version
# ตัวอย่างที่ถูกต้อง
- component: gitlab.com/my-org/components/docker-build@1.0.0
Input validation error
สาเหตุ: Input type ไม่ตรงกับที่กำหนด
# ผิด: number input รับ string
replicas: "5" # ❌
# ถูก: number input รับ number
replicas: 5 # ✓
Permission denied
สาเหตุ: ไม่มีสิทธิ์เข้าถึง component project
แก้ไข: ตรวจสอบว่า CI/CD token มีสิทธิ์ read หรือเพิ่ม project เป็น allowed project
Component conflicts
สาเหตุ: หลาย components ใช้ชื่อ job เดียวกัน
# แก้ไข: ใช้ input เพื่อ override job name
include:
- component: .../docker-build@1.0.0
inputs:
job-name: build-api
- component: .../docker-build@1.0.0
inputs:
job-name: build-worker
Debug Tips
- ใช้
CI_DEBUG_TRACE: "true"เพื่อดู full pipeline debug - ตรวจสอบ component ใน GitLab UI → CI/CD → Editor
- ใช้
include: localเพื่อ test component ก่อน publish
สรุป
สิ่งที่เรียนรู้
- ✅ Component คืออะไร และทำไมต้องใช้
- ✅ การสร้าง Component ของตัวเอง
- ✅ การใช้งาน CI/CD Catalog
- ✅ Inputs และ Parameters
- ✅ Best Practices
- ✅ การประยุกต์ใช้ในองค์กรไทย