12 Factors App : Methodology for building software-as-a-service (Part 1)

เมื่อวานพึ่งเคยได้ยินเรื่อง 12 Factors App จาก SCK Dojo เขาคุยอะไรกันสักอย่าง และดูเหมือนว่าประเด็นสำคัญนั้น มีเนื้อหาอยู่ในเรื่อง 12 Factors ด้วยความอยากรู้อยากเห็น ว่ามันคืออะไรกัน ทำไมมันถึงสำคัญมาก ๆ กลับมาบ้านเลยรีบใช้ Goggling Skills ที่มี หาจากใน Net ซึ่งแน่นอนว่าผมใส่ Keyword “ไทย” เข้าไปด้วย ไม่งั้นต้องมาเจอภาษาอังกฤษเต็มหน้าจอไปหมด กังวลว่าจะเวียนหัวหลับไปซะก่อน โชคดีที่มีคนแปลและเขียน Blog (https://www.babelcoder.com/blog/posts/12-factor) ไว้ให้อ่านอย่างละเอียดเลย ซึ่งแน่นอนว่าเป็นที่พอใจแก่ข้าเป็นอย่างยิ่ง กลายเป็นว่าในการไปเรียน Whole Team Appoarch วันสุดท้าย ตอนเย็นเขาก็มีการพูดถึงเรื่องนี้อีก ผมเลยแอบฟังอย่างเงียบ ๆ เพื่อเก็บความรู้ สิ่งที่ผมเจอคือวิธีการอธิบายที่ทำให้รู้ถึงที่มาที่ไป และเหตุผลของ Factor แต่ละข้อ ผมไม่อยากให้ตัวเองลืมเรื่องนี้ เลยคิดว่าเอามา Note ไว้หน่อยน่าจะดีเผื่อว่าตัวเองจะได้มีโอกาสใช้มัน

After work with “Twelve-Factor App Methodology” by อจอ. Nathawat Thumthiwong

ก่อนจะเล่า

หลังจากผมแอบนั่งฟังประเด็นเรื่อง 12 Factors อยู่ได้สักพักปะติดปะต่อไม่ค่อยจะได้ อาจารย์อู๋แห่ง สยามชำนาญกิจ ก็ออกมาวาดลวดลาย อธิบายเรื่อง 12 Factors ให้ทุกคนในที่นั่นฟัง ซึ่งเป็นธรรมดาของ สยามชำนาญกิจ ที่มีหลักการสำคัญที่เหมือนจะเป็นวัฒนธรรมของเขาก็คือ ก่อนจะทำอะไรต้องเจอกับคำถามว่าทำไมเสมอ เพราะงั้นการเล่าเรื่อง 12 Factors จึงเริ่มต้นด้วยคำถามว่า “ทำไมจึงต้อง 12 Factors”

ที่มาที่ไปของ 12 Factors

อาจารย์อู๋ เริ่มต้นด้วยการอธิบายว่าการมาของ Technology ที่ชื่อว่า Cloud (จริง ๆ ผมเคยได้ยินเรื่อง Cloud Computing มาตั้งแต่เรียนแล้ว แต่เหมือนเคยได้ยินว่า Cloud เดี๋ยวนี้มันไม่เหมือนกันกับเมื่อก่อน ช่างเหอะบ่นไปงั้น) การมาของ Cloud ทำให้กระทบกับกลุ่มคนอยู่ 2 กลุ่ม นั่นก็คือ Developer กับ Infrastructure (จุดนี้ผมจำได้ไม่ชัดว่าทั้ง 2 กลุ่มคนมีมุมมองเกี่ยวกับ Cloud ต่างกันอย่างไร) แต่การมาของมันนั้นมาเพื่อตอบโจทย์ประเด็นทั้งหมด 3 ประเด็น นั่นก็คือ

  1. Elastic หรือความยืดหยุ่นซึ่งหมายถึงการทำ Scaling
  2. On-demand คืออยากใช้ต้องได้ใช้ทันตามความต้องการ
  3. Pay as you go หรือจ่ายเท่าที่ใช้จริง

ฟังดูแล้วมันแทบจะเป็น Infrastructure ในฝันของใครหลาย ๆ คน หรือหลาย ๆ องค์กร เพราะองค์กรส่วนใหญ่มักจะเจอว่าต้องซื้อเครื่องใหญ่ ๆ มาเพื่อรองรับ Load เยอะ ๆ ทั้ง ๆ ที่มีช่วงโหลดแค่พริบตา ส่วนเวลาที่เหลือก็ต้องมาหาทางจัดสรรงานอื่น ๆ เข้ามาใช้ให้คุ้มกับที่ลงทุนไป แต่ถ้าเกิดว่า Request ที่เข้ามามันเยอะกว่าที่ประเมินไว้ก็ไม่สามารถทำอะไรได้

ไม่ต้อง Cloud หรอกมีเครื่องก็ Scale ขึ้นไปได้

ประเด็นทั้ง 3 ที่ Cloud สามารถ Serve ได้ก็ไม่ใช่ว่าเราจะสามารถใช้ Software ที่เรามีอยู่ ให้สามารถทำงานแล้วใช้ประสิทธิภาพตามทั้ง 3 ได้ อย่างเช่น การที่มี Load เข้ามาเยอะ ๆ เรามักจะพูดถึงการ Scale ซึ่งการขยายแหล่งประมวณผลแบบแรกเราเรียกมันว่า Scale Up (ขยายเครื่องให้ใหญ่ขึ้น) การทำ Scale Up ไม่ได้หมายถึงอยากจะขยายก็สามารถขยายได้ทันที เท่าที่ผมเคยเจอมาการขยายเครื่อง ถ้าเป็นการเพิ่ม CPU เข้ามาช่วยประมวลผล Virtual Machine หลาย ๆ เจ้าก็สามารถทำได้เลยโดยไม่กระทบกับการทำงานที่ทำอยู่ (ถ้ามี CPU เหลือนะ) แต่ถ้าต้องการเพิ่ม RAM จำเป็นจะต้อง Restart Machine นั้นเสียก่อน ซึ่งการ Restart Server ในช่วง Load เยอะ ๆ ก็ไม่ต่างกับการยอมลงไปเดินลุยไฟในนรกนั่นเอง ทั้งเรื่อง Request ที่อาจจะหลุดไป หรือความเสี่ยงที่จะเอากลับมาไม่ได้ จากเหตุผลนี้ การ Scale Up จึงยังมีประเด็นที่ไม่ตอบโจทย์ทางด้าน Business อยู่

ถ้างั้นก็ Scale Out แล้วกัน

อีกหลักการนึงของการทำ Scale คือการขยายไปด้านข้าง หรือการ Scale Out พูดง่าย ๆ ก็คือถ้าเครื่องเดียวรันไม่ไหวก็หาเครื่องที่ 2, 3 และ 4 มาช่วยแบ่งโหลดการประมวลผลไปสิ แหม … ก็ดูเหมือนจะตอบโจทย์นะ เพราะเครื่องเก่าก็ยังทำงาน เครื่องใหม่ขึ้นมาก็สามารถช่วยงานได้ทันที แทบจะไม่มี Downtime ให้เห็นเลย แต่สำหรับคนที่เคยทำเรื่อง Scale ก็น่าจะพอรู้ว่าโลกมันไม่ได้สวยงามแบบนั้น เรื่องแรกคือ Traffic ที่จะเข้าเป็น Request มานั้นต้องมีคนมาจัดการ เพื่อแบ่งโหลดที่เคยอยู่บนเครื่องที่ 1 ไปยังเครื่องที่ 2 เพื่อช่วยกันทำงาน ยังไม่รวมการที่ Application ของเราบางครั้งก็มีการเก็บข้อมูลบางอย่างอยู่ที่เครื่องที่ 1 (เก็บแบบชั่วคราวอย่าง HTTP Session) การ Scale Out ออกไปเครื่องที่ 2 ข้อมูลนั้น ๆ จะตามไปยังเครื่องที่ 2 ได้เลยไหม หรือจะทำอย่างไรให้ลูกค้าคนเดิมไปยังเครื่องเดิม เอ๋ … ถ้าทุกคนยังไปเครื่องเดิมมันจะเป็นการแบ่ง Load ได้ยังไงหล่ะ

นอกจากนั้นการทีเรามีเครื่องหลาย ๆ เครื่องนั้น ประเด็นที่สำคัญอีกอย่างคือ เราจะมั่นใจได้อย่างไรว่า Software ที่รันอยู่บนเครื่องใหม่ จะสามารถทำงานได้เหมือนกับเครื่องที่ทำงานอยู่ ไม่ว่าจะเป็น Software/Middle Version หรือ Configuration ถูกต้องตามที่ควรจะเป็นหรือไม่ อย่างที่ 2 คือการหาตัวจัดการที่เหมาะสมมาแบ่ง Load เช่น Load Balancer ดี ๆ สักตัวก็ใช่จะหาได้ง่าย นี่ยังไม่รวมไปถึง Software Application ที่เราพัฒนาสามารถรองรับกรณีมีเครื่องใหม่มาช่วยทำงานหรือไม่ (อย่างเคส HTTP Session ของ HTTP Protocal )

12 Factors ข้อกำหนดในการพัฒนาระบบให้สามารถใช้ประสิทธิภาพของ Cloud ได้

จากปัญหาดังกล่าว Heroku Plaform ซึ่งเป็น Platform ที่ให้บริการ Cloud เจ้าใหญ่ จึงออกข้อกำหนดในการพัฒนาระบบ เพื่อให้ระบบที่ถูกพัฒนาขึ้นมานั้น สามารถใช้งาน Cloud ได้อย่างเต็มประสิทธิภาพตรงตามเป้าหมาย โดยข้อกำหนดดังกล่าวมีทั้งหมด 12 ข้อ ซึ่งจากที่ผมฟัง ดูเหมือนจะสามารถแบ่งกลุ่มออกมาได้ 3 กลุ่มคือ ข้อที่ 1–5 จะสามารถทำให้เกิด Build Pipeline และใช้ความสามารถ On-Demand บน Cloud ได้ ข้อ 6–9 เป็นสิ่งที่เมื่อทำตามแล้วจะทำให้เราใช้ความสามารถทางด้าน Elastic (Scaling) ได้ ส่วน 3 ข้อสุดท้ายผมเข้าใจเอาเองว่าสามารถทำให้เราดูแลรักษาระบบเราต่อไปได้อย่างราบรื่น ซึ่งทั้ง 12 ข้อประกอบไปด้วย

  1. Code Base
  2. Dependency
  3. Config
  4. Backing Service
  5. Build /Release /Run
  6. Processes
  7. Port Blinding
  8. Concurrency
  9. Disposability
  10. Dev/prod parity
  11. Logs
  12. Admin Processes

1. Code Base นั้นสำคัญไฉน

ประเด็นของเรื่อง Code Base กล่าวว่า Application ของเราอาจจะมี Environment ได้หลาย Environment แต่ทุก ๆ Env จะต้องเกิดจากการ Code Base เดียวกันเท่านั้น ห้ามให้ Developer copy Source Code จากเครื่องของตัวเองไปยัง Environment ต่าง ๆ โดยเด็ดขาด ถ้าจะต้องการ Deploy Application ต้องทำการเอาสิ่งที่แก้เก็บกลับเข้าไปยัง Code Base ก่อนแล้วจึงดึง Source Code จาก Code Base ไป Deploy การที่ต้องเอา Source Code ทุกอย่างไปเก็บที่ Code Base เพื่อทำให้ Code Base เป็นปัจจุบัน และพร้อมสำหรับการ Deploy ตลอดเวลา

การที่จะทำให้ Code Base พร้อมสำหรับการ Deploy อยู่ตลอดเวลา ไม่ใช่แค่การให้ Developer เอา Source Code ไปใส่ยัง Code Base เท่านั้น แต่ Developer เองต้องมีวินัย และมีความั่นใจพอว่า Source Code ที่จะใส่ไปยัง Code Base จะต้องไม่ไปทำให้การทำงานเดิมของ Application ที่เคยทำได้มีปัญหา มาถึงจุดนี้ Practice ที่จำเป็นจะต้องใช้ในการทำให้เรามั่นใจใน Code Base ก็คือการทำ Test ในแต่ละ Level ก่อนที่ Commit Source Code ขึ้นไปยัง Code Base ซึ่งการทำการทดสอบ Source Code บ่อย ๆ เพื่อสร้างความมั่นใจนี้เองจะ Lead ให้เกิด Practice ในแนวของ Automate Testing เพื่อลดเวลาในการทดสอบ ก่อน Commit Code และเพื่อความมั่นใจในการ เอา Code Base ไป Deploy ยัง Environment การทำ Integration บ่อย ๆ จาก Practice Continuous Integration ก็จะทำให้เรามั่นใจในกระบวนการการ Deploy มากยิ่งขึ้น

การใช้ Code Base ที่พร้อมจะ Deploy อยู่ตลอดเวลา จะส่งเสริมให้เราสามารถใช้ On-Demand Feature บน Cloud ได้อย่างมีประสิทธิภาพ เนื่องจากการที่จะทำให้เครื่องพร้อมรองรับกับความต้องการที่เพิ่มขึ้นสิ่งที่สำคัญคือเครื่องใหม่ที่เกิดขึ้นจำเป็นจะต้องติดตั้งระบบของเราลงไป การที่ยังมีการเอา Source Code จาก Development Machine มา FTP โดยตรง จะทำให้เราไม่สามารถมั่นใจได้เลยว่าระบบของเราที่ติดตั้งบนเครื่องที่สร้างขึ้นมาใหม่นั้น เป็นระบบที่เป็น Version ล่าสุดจริง ๆ และยิ่งสั่นคลอนความมั่นใจ ที่ว่า “ระบบสามารถใช้งานได้จริง ๆ ตามที่คิดหรือไม่”

2. Dependency : แยก Env Dependency ออกจาก Code Base

ในการทำงาน หลาย ๆ ครั้งมีความเป็นไปได้ที่ Environment ที่เรามีอยู่อาจะไม่สามารถสร้างขึ้นมาให้เหมือนกับ Product ได้ เช่นเราคงไม่เอา Server ขนาดใหญ่มาใช้ในการ Develop Software เราอาจจะต้องใช้ Environment ที่ต่างกันในแต่ละ Stage เช่น Developer Machine เป็น Windows/Mac OS แต่เครื่องสำหรับ Test และ UAT เป็น Linux แถมซ้ำร้าย Production ก็อาจจะเป็น Unix ก็ได้

การที่ Environment แต่ละตัวอาจจะมีพื้นฐานที่ไม่เหมือนกัน ทำให้ความยุ่งยากในการดูแลอาจจะยุ่งยากขึ้น เพราะอาจจะมี Library ของบางภาษาที่มีการแยกกันระหว่าง Library for Windows ซึ่งไม่สามารถใช้กับ Unix ที่เป็น Production ได้ เพราะฉะนั้นการที่เราเอา Library ดังกล่าวใส่ไว้ใน Code Base แล้ว Deploy ไปพร้อมกับ Application ของเรา ก็อาจจะทำให้ Application นั้นไม่สามารถรันบน Unix ซึ่งเป็น Production ได้ ซึ่งปัจจุบันไม่ได้มีเพียง Library เท่านั้น Middle War บางตัวก็มีปัญหานี้เช่นกัน เราจึงจำเป็นต้องนำแนวคิดของ Library/Middle Ware Repository มาใช้ เพื่อให้ Environment แต่ละที่สามารถไปดึง Library/Middle Ware ที่เหมาะสมกับ Platform ของตัวเองมาใช้งานได้ Practice นึงที่ถูกนำมาพูดถึงหรือใช้งานกัน อาจจะเป็นพวก Software as a Code หรือการ Defined ว่า Environment ที่เราต้องการจะประกอบไปด้วย Library หรือ Middle Ware อะไรบ้าง แล้วใช้ Package Installer/Library Dependency อย่าง Maven, NPM มาช่วยในการติดตั้ง Library ที่ต้องการ หรือถ้าเป็น Middle Ware ก็อาจจะใช้ Puppet เข้ามาช่วยในการติดตั้ง Middle Ware ที่ต้องการลงใน Env นั้น ๆ ได้ (หรือจะเป็น Docker, Docker Compose นะ)

การแยก Dependency ของ Env ออกจาก Code Base สร้างความคล่องตัวในการ Deploy Application บน Platform ต่าง ๆ ซึ่งส่งเสริมให้เกิดหลักการ On-Demand ได้ดียิ่งขึ้น

3. Config : ต้องไม่เป็นส่วนนึงของ Source Code

ผมเป็นคนนึงที่คุ้นเคยกับการทำ Configuration File เพื่อเป็นการเก็บค่าต่าง ๆ ที่ Application จะใช้ ซึ่งใน Methodology นี้ เขาบอกว่าให้ลืมเรื่อง Config File ไปได้เลย Application ควรจะอ่านค่าต่าง ๆ จาก Environment Variable ซึ่งเป็นที่ ๆ ทุกคนสามารถ Access มันได้ มาถึงตรงนี้ ผมมีคำถามฉุกขึ้นมาว่า แบบนี้เราต้องเอา Config ทั้งหลายออกจาก Source Code หมดเลยหรือเปล่า ได้คำตอบมาว่า โดยปกติแล้ว Config ของระบบเรามักจะแบ่งเป็น 2 ส่วน คือ Application Config คือ Configuration บางอย่างที่ใช้ร่วมกันในหลาย ๆ ส่วนของ Application เช่น ถ้าระบบมีการคำนวณภาษีมูลค่าเพิ่ม ก็อาจจะมีการเก็บค่า Vat=7% ไว้ที่ใดสักที่ ซึ่งส่วนนี้ยังยอมรับได้ที่จะเก็บเป็น Config File (อยู่ใน Code Base ร่วมกับ Source Code อื่น ๆ) แต่อีกส่วนนึงหรือก็คือ Environment Config ซึ่งค่าต่าง ๆ ใน Config จะเปลี่ยนไปตาม Env ที่เราติดตั้ง เช่น Development Machine กำหนดให้ Write Log File ใน Level Debug และเก็บไว้ใน c:\app\application.log และ Product ซึ่งเป็น Unix อาจจะเก็บไว้ที่ /var/log ก็เป็นได้ ซึ่งส่วนนี้แหละที่เป็นส่วนที่อย่างไรก็ต้องอยู่ใน Environment Variables คำถามต่อมาที่ผมคิดคือทำไม ทำไมต้องเก็บพวกนี้ไว้ใน Env Variable คำตอบแบบกำปั้นทุบดินก็คงจะประมาณ ก็พวกนี้มันเป็นตัวแปรของ environment แต่ละตัวไง คนที่ทำหน้าที่สร้าง/ดูแล env จะต้องรู้ว่า env ดังกล่าวมีค่าที่จะถูกใช้โดย application อะไรบ้าง และใน env นี้จะต้อง set อย่างไร นอกจากนั้นการเก็บ Environment Config ไว้ใน Code Base จะทำให้เราไม่สามารถเอา Code Base ไป Deploy โดยตรงกับ ทุก ๆ Env ได้ รวมถึงการที่จะมีการปรับ Environment Config บางอย่างเราจำเป็นต้องแก้ Source Code ของเราตาม Env ที่เปลี่ยนไป ซึ่งในการทำงานของ Cloud เราไม่สามารถทราบได้เลยว่า Application ของเราจะไปรันอยู่บน Env ไหน การเปลี่ยนไปเปลี่ยนมาแบบนี้กลายเป็นว่าเราต้องแก้ Code แล้ว Deploy ทุกครั้งที่มีการเปลี่ยน Env ซึ่งไม่น่าจะสนุกนัก

4. Backing Service :

เนื่องจากกการที่ระบบ ๆ นึงจะเกิดขึ้นได้ มักจะประกอบไปด้วยองค์ประกอบหลาย ๆ ส่วนเข้ามาทำงานร่วมกัน เช่น Web/API/Database รวมไปถึง External Service ต่าง ๆ อีกมากมาย และโดยปกติการเชื่อมต่อ Component ต่าง ๆ เข้าด้วยกันมักจะ Specific ตามแต่ที่ Component เหล่านั้น Privide ให้ แต่ถ้าเราสามารถเปลี่ยนมุงมองใหม่โดยถือว่า Component เหล่านั้นเป็น Service อีก 1 Service ที่เราต้องเชื่อมต่อด้วย แล้วพยายามให้มันเป็นชิ้นส่วนที่เราสามารถถอดเข้าออก หรือเปลี่ยนเป็น Component อื่น ๆ ที่ทำหน้าที่แบบเดียวกันได้ ก็จะทำให้ Application ของเรามีความยืดหยุ่นมากขึ้น ยกตัวอย่างเช่น การเชื่อมต่อจาก Application ไปยัง Database ถ้าเรามองว่ามันเป็น Data Store Service เราสามารถปรับให้ส่วนที่ไปต่อกับ Service นี้มีความ Generic มากขึ้น อาจจะมากพอที่จะเปลี่ยนเป็น Data Store Service อื่น ๆ มา Plug แทนกัน หรืออย่างน้อย ถ้ามมองว่าเป็น Database Service แล้วใช้ Connection String ในการเชื่อมต่อ เราก็สามารถที่จะเปลี่ยน Connection String เพื่อให้ Application ของเราสามารถเชื่อมต่อไปยัง Database ก้อนอื่น ๆ ยี่ห้ออื่น ๆ ได้ผ่านการเปลี่ยน Connection String นั่นเอง ซึ่งแน่นอนว่าการเก็บ Connection String ซึ่งเป็น Environment Config ก็ต้อเก็บไว้ใน Environment Variable ตามที่พูดถึงในหัวข้อก่อนหน้านี้

5. Build / Release / Run : Build ครั้งเดียวพร้อมใช้ในทุก Environment

ผมเป็นคนนึงซึ่งมีประสบการณ์ลองนำ Continuous Integration หรือ การ Integration บ่อย ๆ เข้ามาลองใช้ แต่ด้วยความเข้าใจผิดในหลาย ๆ เรื่อง กลายเป็นว่าที่ผมทำมาทั้งหมด ก็แค่ One Click Package and Deploy System (เอา Jenkins มาดึง Source Code มา Build สร้าง Package Software และกดอีก 1 ที เพื่อเอาไป Deploy บน Server สิ่งที่ผมเจอในตอนนั้น คือ Env ของผมมีหลายตัวมาก แต่ละตัวก็มี Env Config ไม่เหมือนกัน แถมผมยังเอา Env Config เก็บไว้ใน Code Base อีกต่างหาก การทำแบบนั้นของผมจึงเกิดสิ่งที่เรียกว่า Builder per Environment ขึ้นมา Builder per Env หมายถึงอะไรหน่ะเหรอ

มันหมายถึงเมื่อผมต้องการ Build Software เพื่อไป Deploy บนเครื่อง Dev ผมก็จะมี Script 1 ชุดที่ทำหน้าที่เอา Source Code จาก Code Base ลงมา Overwrite Config ด้วย Dev Config แล้วจึง Package Software ดังกล่าวก่อนที่จะเอา Packaged Software ตัวนั้นไป Deploy บน Dev Environment แน่นอนว่า Packaged Software ตัวนี้ไม่สามารถเอาไป Deploy บน Environment อื่นอย่าง Test/UAT/Production Environment ได้ เพราะกระบวนการที่ทำให้เกิดการเลือก Config อยู่ที่การ Build นั่นเอง จริง ๆ ตอนที่ผมทำผมก็ไม่ได้คิดว่ามีปัญหาอะไรหรอกนะครับ แต่จากที่อจารย์อู๋มาช่วยเคาะกระโหลกด้วยคำถามที่ว่า “คุณจะมั่นใจได้อย่างไรว่า Build แต่ละครั้งได้เหมือนกัน” หรือ “จะรู้ได้อย่างไรว่า Script ที่ถูกใช้ในการ Build แต่ละ Env มันทำงานเหมือนกันแก้ตามกันอย่างถูกต้อง” ซึ่งการใช้ Practice Continuous Integration แบบผิดของผมนี้ มันขัดกับหลักการ Build / Release / Run ของ 12 Factors อย่างแรง (ไม่นับรวมที่ทำ Build/Package แบบไม่มี Test ด้วยเนี่ย ยิ่งทำให้รู้สึกว่า “กูทำอะไรลงไปนะ”)

หลักการ Build / Release / Run ของ 12 Factors พูดถึงการแยก Step การ Build และ Package software ออกจากปัญหาเรื่อง Environment โดยให้เกิดการ Build / Package Software เพียงครั้งเดียว และเมื่อจะเอา Packaged Software ตัวนั้นไปใช้ในแต่ละ Environment ค่อยทำการ Inject Dependency เข้าไป โดยยังต้องมั่นใจว่า “ผลการทำงานที่ได้จาก Package นั้น ๆ ในแต่ Env ต้องทำงานได้เหมือน ๆ กัน” เพื่อให้มั่นใจว่า Packaged Software ที่เราทำนั้นสามารถใช้งานได้ถึงแม้จะไปรันบน Env ไหน (แน่นอนว่า Practice เกียวกับ Automate Test จะเข้ามามีส่วนกับแนวคิดนี้อย่างแรง)

ถึงตอนนี้ จาก 5 ข้อแรกใน 12 Factors เราได้อะไรมาแล้วบ้าง ?

จากที่ผมเกริ่นไว้ตอนต้นของ Blog นี้ว่า “12 Factors ใน ข้อที่ 1–5 จะสามารถทำให้เกิด Build Pipeline และใช้ความสามารถ On-Demand บน Cloud ได้” ผมเลยมานึกทบทวนว่ามันได้เรื่อง Build Pipeline ยังไงนะ และถ้ามันจะมองเป็นภาพ Implement ด้วย Practices ต่าง ๆ การทำงานจริง ๆ จะออกมาเป็นภาพไหน ส่วนแรกที่เราควรสนใจ คือ เราจำเป็นจะต้องมี Code Base เป็นจุดเริ่มต้นของการทำงานทั้งหมด Developer จะต้องทำการ Develop และ Test กับ Code Base อย่างสม่ำเสมอ การจะ Build หรือ Package Software เพื่อนำไปติดตั้ง ต้องทำผ่าน Source Code จาก Code Base เท่านั้น (Developer Check-in) โดยสามารถเอามา Integrate กันบ่อย ๆ ผ่าน Continuous Integration จุดนี้สิ่งที่ขาดไม่ได้เลย คือเราจะต้องมีการทำ Test ใน Level ต่าง ๆ เพื่อให้สามารถมั่นใจได้ว่า Application ที่เราทำสามารถใช้งานได้อย่างต่อเนื่อง ซึ่งหลังจากทำการ Build และ Package เพื่อเอาไปติดตั้ง บน Environment ต่าง ๆ จะสามารถทำได้เลย เพราะเราจะมีการแยก Environment Configuration ออกจาก Code Base นอกจากนั้นในแต่ละ Level หรือในแต่ละ Environment ยังสามารถตัด Concern ของ แต่ละ Component ออกจากกันได้ จากการที่ปรับ Service หลังบ้านต่าง ๆ ออกไปเป็น Backing Service ซึ่งใน Level ของ Integration เราอาจจะใช้วิธี Mocking Service เหล่านั้น จนสุดท้ายเราก็สามารถเอา Package Software ของเราไป Deploy ยัง Production ได้อย่างถูกต้องนั่นเอง

ถึงตอนนี้เริ่มรู้สึกว่าการ Release Blog นี้ ควรจะตัดจบเพื่อให้ได้ Feedback Loop ซะบ้างแล้วครับ (เหนื่อยแล้ว … เขียนยาว) ใน Blog ต่อไป ผมคงจะมาเล่าให้ฟังถึง 12 Factors ข้อที่เหลือ ซึ่งจะมีผลถึงเรื่องการ Scale Software และสามารถใช้ Feature ของ Cloud ได้อย่างเต็มที่ วันนี้พอหล่ะ #อรุณสวัสดิ์