มาทำ Versioning + GitOps + K8s บน Monorepo กันเถอะ! Part III

Versioning and GitOps pipeline

For English version, please visit the link https://github.com/saenyakorn/monorepo-versioning-gitops/

ความเดิมตอนที่แล้ว

เราได้คุยกันเรื่อง

  1. มาทำความรู้จักกับ semantic version กันเถอะ!
  2. สร้าง Monorepo แบบ minimal
  3. มาลอง setup Changesets บน Monorepo กัน
  4. มาลอง bump version แบบง่าย ๆ บน local

ถ้าใครยังไม่ได้อ่าน ย้อนกลับไปอ่านก่อนได้นะ 🥺

📜 เนื้อหาวันนี้

โดยรวมตอนนี้จะเป็นการเล่าถึงเรื่อง development process และ workflow ทั้งหมดสำหรับการทำ versioning และ deploy แบบ automated (ซึ่งจะสาธิตให้ดูในตอนถัดไป) เนื้อหาตอนนี้มีดังนี้

  1. Gitflow คืออะไรล่ะ?
  2. Workflow ทั้งหมดตั้งแต่ต้นยันจบ บน Monorepo
  3. ArgoCD มาช่วยอะไร?
  4. บทส่งท้าย
  5. ตัวอย่างตอนต่อไป! (เริ่มลงมือ implement automated workflow)

❓ Gitflow คืออะไรล่ะ?

Gitflow เป็น branching model ที่ใช้กันมาอย่างยาวนานตั้งแต่สมัยคุณปู่ ซึ่ง concept หลักของ Gitflow คือแบ่งหน้าที่ชัดเจนไปเลยว่า branch ไหนสำหรับ environment อะไร เช่น production อยู่ main branch และ staging อยู่ staging branch เป็นต้น

ในส่วนของการพัฒนา feature เราก็จะแยก branch ออกมาจาก branch ใด branch หนึ่งใน Gitflow เช่น main หรือ staging (อันนี้แล้วแต่บริบทของบริษัท)

ในส่วนของการสาธิตในบทความนี้จะขอใช้ Gitflow หน้าตาอย่างงี้

  1. Production environment — อยู่ใน main branch จะเป้น environment ที่ user ทั่วไปใช้กัน
  2. Beta environment — อยู่ใน beta branch ซึ่งจะเป็น environment ที่เอาไว้ทดสอบโดยฝั่ง product และ QA ก่อนขึ้นสู่ production
  3. Dev environment — อยู่ใน dev branch ซึ่งจะเป็น environment ที่เอาไว้ให้ developer ทดสอบระบบกันเองก่อน

นอกจากนี้ยังมี feature branch ที่แยกตัวออกมาจาก beta เพื่อให้ developer พัฒนา feature ของตัวเองก่อนเปิด PR เข้า beta (ส่วน dev คือมีเอาไว้ใช้เป็น preview เฉย ๆ)

ถ้าวาดเป็น diagram ออกมาจะหน้าตาประมาณนี้

Gitflow ที่จะใช้ในบทความนี้

🌈 Workflow ทั้งหมดตั้งแต่ต้นยันจบ บน Monorepo

ถ้าจะเล่าทั้งหมดรวดเดียวเลยคงค่อนข้างยาว เพราะฉะนั้นเดี๋ยวจะตัดออกเป็น scenario ละกันนะ

Scenario 1: Developer ต้องการ deploy ขึ้น dev environment

เนื่องจากเราจะใช้ dev environment เป็น preview ดังนั้นการ deploy ขึ้น dev จึงไม่จำเป็นต้องมี versioning และไม่ต้องเปิด pull request (merge ตรง ๆ ได้เลย) ดังนั้น scenario นี้จะเป็น scenario ง่าย ๆ ทั่วไป แต่ผนวกเข้ากับ GitOps concept แล้ว เริ่มที่

  1. Developer แตก branch feature ออกมาจาก beta
  2. เมื่อพัฒนาไปได้สักพักหนึ่งแล้วอยากจะ deploy ขึ้น dev โดยการ merge feature into dev ก่อนเปิด PR ที่ GitHub เพื่อให้ reviewer คนอื่นมาดูงานเราบน dev ได้
  3. เมื่อ branch dev ถูก push GitHub Action จะทำการหา affected apps and packages (apps หรือ packages ไหนที่มีถูกแก้ใน changes นี้) ก่อนที่จะเริ่มทำอะไร
  4. GitHub Action จะ build Docker image เฉพาะ affected apps จากนั้น tag ด้วย git commit id แล้ว publish ขึ้น Docker registry (Release Stage)
  5. GitHub Action จะ checkout ไปที่ GitOps repository จากนั้นทำการ update kustomize ด้วย tag ใหม่ แล้วทำการ commit and push changes นั้นขึ้น GitOps repository (Deployment Stage)
  6. เย้! เท่านี้ dev environment ของคุณ ก็ถูก update เรียบร้อยแล้ว

ซึ่งสามารถวาด diagram คร่าว ๆ ได้ประมาณนี้

overview pipeline for deploying to dev environment

ในส่วนของ deployment เดี๋ยวจะอธิบายต่อไปว่าแค่แก้ kustomize manifest files แล้วทำไม service ใหม่ถึงถูก deploy

Scenario 2: Developer เปิด PR เข้า beta

  1. Developer ต้องใส่ Changesets file เพื่อ describe ว่า changes ทั้งหมดนี้โดยสรุปแล้วมันคืออะไร
  2. Developer ได้รับการ approve และ merge feature branch into beta
  3. GitHub Action ใช้ Changesets Action ในการ summarize changes ทั้งหมดจาก Changesets file และทำการเปิด PR ที่ชื่อว่า “Version Packages (Beta)”
ตัวอย่าง pull request “Version Packages (Beta)”

Scenario 3: Developer ต้องการ pre-release apps and packages

  1. Developer กด merge “Version Packages (Beta)”
  2. GitHub Action ทำการ pre-release affected apps and packages โดยจะ update GitHub Release Notes และ CHANGELOG รวมถึง bump version ของ packages ด้วย
  3. GitHub Action ทำการ build Docker images และ tag ด้วย version ใหม่ที่เพิ่ม bump มา จากนั้น publish ขึ้น registry
  4. GitHub Action จะ checkout ไปยัง GitOps repository จากนั้น update kustomize ด้วย tag version ใหม่ จากนั้น commit and push ขึ้น GitOps repository
  5. เย้! เท่านี้ beta environment ของคุณก็ถูก update แล้ว แถมยังมี CHANGELOG และ tag version ให้ด้วย โดยที่คุณแทบไม่ต้องทำอะไรเลย

ถ้าวาด diagram ของ scenario 2 และ 3 รวมกันจะได้ประมาณนี้

overview pipeline for scenario 2 & 3

จะสังเกตว่าจุดที่ต่างกันจริง ๆ จะเป็นช่วงแรก ๆ ช่วงที่ summarize changes และช่วงทำการ bump version นอกนั้น workflow คล้าย ๆ กันหมดเลข คือ build docker แล้วก็แก้ kustomize manifest file

จุดที่น่าสนใจคือ หากมี feature branch merge เข้า beta เยอะ ๆ ตัว PR “Version Packages (Beta)” จะคอยทำการ update PR description ให้เองเลย มันจะไม่เปิด PR ใหม่พร่ำเพื่อ

Scenario 4: Developer ขึ้น production ด้วยการเปิด PR จาก beta เข้า main

  1. เหมือนกับ scenario 2 เลย ต่างกันตรงที่ว่ารอบนี้เราไม่ต้องเพิ่ม Changesets files
  2. ส่วน PR ที่เปิดขึ้นมาหลังจาก merge beta branch เข้า main คือ “Version Packages”

Scenario 5: Developer ต้องการ release apps and packages

  1. Workflow ทั้งหมดเหมือนของ scenario 3 เลย
  2. ต่างกันที่ ในตอนสุดท้ายที่ GitHub Action checkout ไปที่ GitOps repository และ update kustomize มันจะทำการเปิด Pull Request “Update GitOps” ไปที่ GitOps repository แทนที่จะ commit and push เพื่อให้ developer เป็นคนยืนยันอีกทีว่าต้องการขึ้น production จริง ๆ (ที่ทำสีชมพูแดงไว้)
  3. หาก developer merge PR “Update GitOps” แล้วจะเป็นการ deploy apps ขึ้น production จริง ๆ แล้ว เย้!
overview pipeline for deploying to main

แม้ว่า workflow มันดูยุ่งเหยิงแล้วก็ดูทำอะไรก็ไม่รู้เต็มไปหมด แต่จะสังเกตว่าในฐานะ developer เราแทบไม่ต้องทำอะไรเลยนอกจากกด merge กับเพิ่ม Changeset file

แล้วก็อย่าเพิ่งตกใจไปว่า “ขนาดวาด diagram คร่าว ๆ ยังยากขนาดนี้ และ implement จริงจะยากขนาดไหน” ซึ่งบอกก่อนเลยว่าไม่ยากอย่างที่คิด เดี๋ยวตอนหน้ามีคำตอบ!

⭐️ ArgoCD มาช่วยอะไร?

อยู่ ๆ มาพูดถึง ArgoCD ตรงนี้แล้วก็คงรู้สึกแปลก ๆ หน่อย ๆ ฮ่า ๆ แต่ถ้าพูดถึง GitOps แล้วยังไงก็ไม่พูดถึง ArgoCD ไม่ได้

ArgoCD เป็น tools ที่ช่วยให้เราสามารถทำ GitOps ได้อย่างถูกต้อง โดย ArgoCD จะคอยจับตาดู Git repository ของคุณว่ามี commit ใหม่หรือไม่ ถ้ามีมันจะพยายาม update Kubernetes Cluster ให้ตรงกับ declaration ที่เราประกาศไว้ใน Kubernetes manifest files ที่อยู่ใน repository (ซึ่งในที่นี้เราจะใช้ kustomize กัน)

Thanks image from https://argo-cd.readthedocs.io/en/stable/

นั่นเป็นเหตุผลว่าทำไมการทำ deployment ใน workflow ด้านบนถึงทำแค่แก้ kustomize file ก็เพียงพอแล้ว

จริง ๆ แล้ว ArgoCD ยังสามารถทำอะไรได้อีกเยอะมากกก ถ้าใครสนใจสามารถมาอ่าน blog “มาลอง Setup Gitops ด้วย ArgoCD + Kustomize กันเถอะ” ได้เลย (เป็น blog ของรุ่นน้อง // ขายของ)

🙏 บทส่งท้าย

วันนี้เราได้คุยเรื่อง

  1. Gitflow คืออะไรล่ะ? — Development process รุ่นคุณปู่ ที่แบ่งหน้าที่ชัดเจนว่า branch ไหรสำหรับ environment อะไร
  2. Workflow ทั้งหมดตั้งแต่ต้นยันจบ บน Monorepo — ยาวเหยียดเลยล่ะ สรุปไม่ถูก 55555
  3. ArgoCD มาช่วยอะไร? — ช่วยทำให้เราสามารถ update system ที่อยู่บน Cloud ได้เพียงแค่แก้ manifest file

หวังว่าเพื่อน ๆ ที่อ่านมาจนถึงตอนนี้จะยังไม่หงุดหงิดว่า “มีแต่ concept แล้ว implementation อยู่ไหนล่ะ!” อยู่นะครับ ฮ่า ๆๆ ในตอนถัดไป เราจะพาเพื่อน ๆ ไปลงมือ implement จริง ๆ แล้ว! พร้อมคำอธิบายอย่างละเอียด โปรดติดตามตอนต่อไปได้เลย!

Appendix

ทั้งนี้ถ้าใครใจร้อนอยากเห็น full implementation แล้วสามารถแวะมาดูได้ที่นี่เลย https://github.com/saenyakorn/monorepo-versioning-gitops ซึ่งก็มีเขียนอธิบายพอสังเขปบวกกับวิธีการ setup แล้วเรียบร้อย feel free ที่จะก๊อปโค๊ตได้เลยนะครับ ตามอัธยาศัย

ปล. ถ้าชอบก็อย่าลืมกด Star ใน GitHub เป็นกำลังใจให้ด้วยนะครับ 🫠

--

--