สร้าง CI/CD ด้วย Azure Pipelines

Azure Pipelines คือเครื่องมือในการทำ CI/CD ที่ระบุ Task ต่างๆโดยเขียนลงในไฟล์ YAML ซึ่ง Pipeline จะแบ่งออกเป็น 2 ประเภทคือ
- Classic เป็นการสร้าง Pipeline จากหน้า Portal(Web GUI)
- YAML เป็นการสร้าง Pipeline โดยการเขียน Text ไฟล์ที่มีนามสกุล .yaml หรือ .yml
แนะนำให้สร้าง Pipeline ผ่านทาง YAML ดีกว่า เพราะจะยืดหยุ่นกว่าและ Manage Version ที่เดียวกับ Source Code
ประเภทของ Pipelines
เราสามารถแบ่งประเภทของ Pipelines ออกเป็น 2 ประเภท
Build Pipeline
ทำหน้าที่ Build Software ออกมา โดยที่ Software ที่ได้จะต้องพร้อมสำหรับการส่งมอบและได้คุณภาพตามที่เราต้องการ
Release Pipeline
หลังจากที่เรา Product ที่ Build ออกมาจาก Build Pipeline เรียบร้อยแล้วถ้าเราต้องการนำ Product นี้ไป Deploy ลงบน Cloud Service, Kubernetes หรือ Platform อื่นๆ เราจะต้องสร้าง Release Pipeline มาเพื่อทำงานนี้
โดยที่ Release Pipeline จะสามารถแยก Environment ออกมาเป็น Stages ต่างๆได้ เช่น
- Development
- Testing
- Staging หรือ Pre-Production
- Production
เราสามารถกำหนดวิธีการ Approve ของแต่ละ Stage ได้ด้วย เช่น ก่อนขึ้น Production จะต้องมีคนมา Approve ก่อน
โครงสร้างของ YAML
1. Triggers
Pipeline จะถูกเรียกใช้งานตอนไหนขึ้นอยู่กับ สิ่งที่เรา Set ไว้ใน Trigger
- none ถ้าเรากำหนด Trigger เป็น none จะหมายถึงไม่มี Trigger เราจะต้องกด Run pipeline ด้วยตัวเองเท่านั้น(Manual)
- schedule เราจะตั้งเวลาให้ Pipeline ทำงาน โดยกำหนดด้วย Cron Syntax
schedules: - cron: '0 0 * * *' displayName: Daily midnight build branches: include: - main
- pipeline เราจะ run pipeline นี้เมื่อ pipeline ก่อนหน้าทำงานเสร็จเรียบร้อย
resources: pipelines: - pipeline: buildProject # ชื่อของ Pipeline ที่ต้องเสร็จก่อน source: build-project-ci # ชื่อไฟล์ของ Pipeline ที่ต้องเสร็จก่อน trigger: true # Run Pipeline นี้หลังจากที่ build-project-ci.yml เสร็จเรียบร้อย steps: - bash: echo "app-ci runs after security-lib-ci completes"
2. Stages
Stages คือกลุ่มของ Jobs ที่เป็นงานเรื่องเดียวกัน สิ่งที่ต้องพิจารณาในการวาง Job ไว้ใน Stage เดียวกันคือ
- Stage สามารถ run พร้อมๆกันได้(Parallel)
- Stage สามารถเลือกลงไปใน Agent(เครื่องที่รัน Job) ที่ต้องการได้
- ถ้ามี Error ใน Job ใด Job 1 จะถือว่า Stage นั้น Fail
ซึ่งโดยทั่วไปเราจะแยกตามขั้นตอนการทำงานหลักๆ ดังนี้
- Build
- Test
- Infrastructure deployment
- Code deployment
ตัวอย่างของ Stages
stages:
- stage: Build
jobs:
....
- stage: Test
jobs:
....
- stage: Deploy
jobs:
....
3. Jobs
Job จะเป็น unit of work ของ Pipeline นั่นคือจะเป็นหน่วยย่อยที่จะถูกส่งไปทำงานใน Agent(เครื่องที่ถูกกำหนดไว้ให้ทำงานเฉพาะอย่างเช่น Build หรือ Deply)
Job จะมี DependsOn(ลำดับของการทำงาน) และ Condition(เลือกที่จะ Run หรือไม่ Run) คอยควบคุมการทำงาน นอกจากนี้เรายังสามารถใช้ Metrix Job ในการ Copy Job ออกมาแล้วปรับเปลี่ยน Input หรือ Configuration ของ Job นั้น เพื่อทดสอบ Job นี้ในหลายๆ OS หรือหลายๆ Configuration

3. Script and Task
เป็นคำสั่งที่ทำงานที่ต้องการจริงๆ ซึ่งเป็น Script หรือ Task ก็ได้ ซึ่งความแตกต่างๆระหว่าง Script และ Task ตือ
- Script คือ command ที่เราระบุเข้าไปตรงๆเช่น
steps: - script: npm install - script: npm test
- Task คืิอชุดของ Command สำเร็จรูปที่เราจะกำหนด parameters เข้าไปแล้ว Task นั้นก็จะทำงานอัตโนมัติ ซึ่งจะมีทั้ง Task ที่มาจาก Azure เองและมาจาก Third-party
steps: - task: Npm@1 inputs: command: 'install'
Variables
เราสามารถกำหนดตัวแปรไว้เพื่อให้เราสามารถเปลี่ยนแปลง Pipeline ได้ง่าย ถ้ามีการปรับเปลี่ยนค่าจะได้เปลี่ยนค่าใน Variable แล้วมีผลกับทั้ง Pipeline
variables:
- name: projectName
value: azure-devops
steps:
- bash: echo $(projectName)
- powershell: echo $(projectName)
- script: echo $(projectName)
Parameters
ในกรณีที่เราต้องการให้มีการส่ง Input เข้ามาใน Pipeline เราจะใช้ Parameters ซึ่งต้องกำหนด Parameter ไว้ใน Pipeline แบบนี้
parameters:
- name: image
displayName: Pool Image
type: string
default: ubuntu-latest
values:
- windows-latest
- ubuntu-latest
- macOS-latest
trigger: none
jobs:
- job: build
displayName: build
pool:
vmImage: ${{ parameters.image }}
steps:
- script: echo building with ${{ parameters.image }}
ในตัวอย่างนี้จะเป็นการกำหนดให้เลือก Image โดยมีทางเลือกอยู่ 3 ทางคือ
- windows-latest
- ubuntu-latest
- macOS-latest
Azure pipeline parameter
แล้วหลังจากนั้น Job นี้จะใช้ Agent ที่มี OS ตามที่เราเลือก ซึ่งข้อดีของการใช้ parameter คือ
- Script และ Task ต่างๆสามารถเปลี่ยนแปลงได้ตามความต้องการ
- กำหนด Types และช่วงของข้อมูลที่จะส่งเข้ามาได้
- สามารถนำ Parameter ไปเลือก Job และ Stage ที่ต้อง Run ได้
Agents and Agent Pools
Azure Pipeline จะแบ่งงานออกเป็น 2 ประเภทคือ
- แบบใช้ Agent
- แบบไม่ใช้ Agent(Agentless)
Agent
ในการทำงานประเภทนี้ Azure Pipeline จะกระจายงานลงไปใน Agent ซึ่ง Agent ก็จะมาได้จาก 2 วิธีนี้
-
MS-Hosted เป็น Agent ที่สร้างขึ้นและดูแลโดย Microsoft ซึ่งจะอยู่ใน Agent Pool ชื่อ Azure Pipelines การใช้งาน Agent ประเภทนี้เราจะกำหนดรายละเอียดของ Environment ไม่ได้ ซึ่ง Microsoft จะเตรียม OS ไว้ให้เราตังนี้
-
Self-Hosted เป็น Agent ที่เราต้องติดตั้ง OS และ Service ต่างๆเข้าไปเอง แล้วหลังจากนั้นก็นำ Agent register เข้าไปใน Agent Pool(เราต้องสร้าง Agent pool ขึ้นมาใหม่) ซึ่งข้อดีของ Agent ประเภทนี้ตือเรากำหนด Environment ได้เองหมดทุกอย่าง แต่ข้อเสียก็คือเราต้องคอยดูแล Agent แต่ละต้วเอง
Agentless
สำหรับ Jobs ที่อยู่ใน List ด้านล่างนี้ Azure Pipeline จะไม่นำไปส่งให้ Agent แต่จะใช้ resource ของ Azure DevOps Server นั่นแหละ run Job เหล่านี้ ซึ่งเราจะเรียก Job เหล่านี้ว่า Agentless Job
- Delay task
- Invoke Azure Function task
- Invoke REST API task
- Manual Validation task
- Publish To Azure Service Bus task
- Query Azure Monitor Alerts task
- Query Work Items task
เราจะใช้ pool เป็น server เพื่อบอกให้ Job นี้เป็น Agentless
jobs:
- job: demo-agentless
pool: server
Template
เราสามารถนำ Stage ไปแยกไว้ใน Template(ไฟล์ .yml) เพื่อให้สามารถ Reuse ใช้ซ้ำได้ ยกตัวอย่าง เช่น เราจะสร้าง Template(ตั้งชื่อเป็น install-angular.yml แล้วเก็บไว้ใน folder templates) ใหม่ สำหรับติดต้ัง Angular
|
|
หลังจากนั้นเราสามารถนำไปเรียกใช้ได้แบบนี้
|
|
