Tech Stack ของ ExxonMobil — บริษัทน้ำมันแห่งหนึ่ง ที่ไม่ใช่ TechCompany @2020

Tanat Lokejaroenlarb
NonTechCompany
Published in
5 min readJun 23, 2020

เนื่องจากปกติผมก็ชอบที่จะติดตามข่าวคราวของวงการ IT ไทย ผ่าน Facebook feed เป็นประจำอยู่เเล้ว เเละหัวข้อนึงที่ผมชอบอ่านมากเป็นพิเศษก็คือ Tech Stack ของบริษัทอื่นเค้ามีอะไรกันบ้าง

ซึ่งล่าสุดผมกับน้อง Chan Suttichujit developer ในทีมก็ได้ไปอ่าน Tech Stack ของ Wongnai มาแล้วก็เกิดไอเดีย อยากทำ Tech Stack ของบริษัทเรามาแชร์บ้าง

เกริ่นสั้นๆ บริษัทเราชื่อว่า ExxonMobil Limited ซึ่งคนส่วนมากน่าจะคุ้นเคย หรือรู้จักกันว่า มันคือบริษัท Energy ชื่อดังของอเมริกาใช่มั้ยครับ แต่จริงๆเเล้ว พวกเราก็มีเหล่า Developers ที่ทำ Software ใช้กันภายในเหมือนกัน (ถึงเราจะไม่ใช่ “Tech Company” ก็ตาม)

ใครสนใจเพิ่มเติมว่าบริษัทเราทำอะไร ตามไปอ่านกันต่อได้ที่ https://www.blognone.com/node/111196

ExxonMobil เราเองก็มี Developer ทั่วโลกอยู่น่าจะหลักหลายร้อยคน ซึ่งแต่ละทีมก็จะมี Technology / Tech stack ที่แตกต่างหลากหลายกันมากมาย ถ้าเอามาเล่าเป็นวันก็คงไม่จบ ผมเลยจะมาแชร์ TechStack เฉพาะของทีมที่ผมทำงานอยู่ ซึ่งอยู่ภายใต้ Digital Transformation Organization เป็นหลัก

ผมขอแบ่ง Tech Stack หลักๆออกเป็น 2 ส่วน คือ Cloud Stack และ On-Prem Stack

Cloud Stack

https://stackshare.io/InsomniaCoder/cloud?utm_source=embed_stack

Infrastructure

เนื่องจากบริษัทเราเป็น Partner กับ Microsoft ดังนั้น Cloud Provider ที่เราใช้เลยหนีไม่พ้น Microsoft Azure

Kubernetes [AKS]

เราตั้งเป้าที่จะทำให้ App ของเราเป็น Cloud-ready ตั้งแต่ต้น ก่อนที่จะเริ่มย้ายมาเริ่ม Cloud Journey ดังนั้น App ของเราเลยสร้างมาแบบ Containerized และทำตามหลักการของ 12 Factors พอเราย้ายมา Cloud เราเลยสามารถยก app มาลงบน Kubernetes ได้ไม่ยาก ซึ่งการที่เราใช้ Kubernetes มันทำให้เรามีอิสระที่จะลง Operator ต่างๆใน Cluster ของเราเอง เพื่อช่วยในการ Automate task

Terraform

เราอยากที่จะจัดการกับ Infrastructure ด้วย code (Infrastructure as a Code) เพื่อประหยัดแรง และลดข้อผิดพลาด เราจึงเลือกใช้ Terraform มาช่วยในการสร้าง Infrastructure ของเราจาก code แบบอัตโนมัติ เวลาเราอยากจะแก้ Infra สิ่งที่เราต้องทำก็มีเพียงแค่เขียนหรือแก้ code จากนั้น change จะถูก trigger ผ่าน Azure DevOps pipeline ได้เลย โดยที่เราไม่ต้อง log in เข้าไปใน server แล้วทำการแก้แบบ manual แบบเดิมๆ

ตัวอย่าง Terraform script
เมื่อเราตรวจสอบการแก้ไขแล้ว เราแค่ approve เพื่อเปลี่ยน Infrastructure แบบอัตโนมัติ

Shared Terraform Module

Strategy ของเราคือ เราจะมีทีมกลางทีมนึง ที่คอยจัดการกับ Terraform module เพื่อที่จะใส่ Best practices และ Security policy ที่บริษัทกำหนด ใส่เข้าไปใน module เพื่อให้แต่ละ developmet team สามารถนำไปใช้ได้เลย โดยไม่ต้องเสียเวลา set up หรือไป implement policy ที่ทุกคนต้องทำซ้ำๆ และได้ของที่มี best practice พร้อมนำไปใช้งาน เพื่อให้ development team focus กับการ deliver business value

โดยตัว module หลักของเราคือ Azure Kubernetes Service เราก็ได้ทำการลง Operator ต่างๆ ที่ใช้ช่วย automate task ที่ปกติทุกๆทีมต้องทำแบบ manual เพื่อช่วยลดเวลาการทำงาน ยกตัวอย่าง บาง Operator เช่น

Twistlock -> เพื่อช่วยจัดการเรื่อง container security

ICE (NGINX Ingress Controller + Cert Manager + External DNS) -> เมื่อทีมต้องการ expose API สิ่งที่ทีมต้องทำก็แค่สร้าง Ingress Object ที่ใช้ระบุ URL และ service ขึ้นมา หลังจากนั้นทีมก็จะได้ URL ที่มี DNS และ Certificate ที่ Signed เเละRenewed แบบอัตโนมัติ ซึ่งโดยปกติทีมต้องเปิด ticket เเละใช้เวลารอนานมากในการทำ process นี้

Kured -> สำหรับช่วย Restart Cluster ตอนทำ Security Patch เพื่อลด manual work และอัพเดท patch อย่างสม่ำเสมอ

นอกจากนี้ยังมี Module อื่นๆ ที่เราสร้างเอาไว้ให้ development team สามารถนำไปใช้ใน Infrastructure ของแต่ละทีมเอง

module ที่เรามีตอนนี้ เเละยังสร้างเพิ่มอย่างต่อเนื่อง

Application

Java + Spring Boot

Java และ Spring Boot เป็นภาษาและ Framework หลักที่เราใช้สร้าง Service ทั้งตัว API และ service อื่นๆ เนื่องจากตอนที่เราเริ่มที่จะทำ Microservice เมื่อหลายปีก่อน Spring boot ค่อนข้างที่จะมี contributor เยอะใน industry และการทำ Microservice เราจึงยังใช้ Java และ Spring boot ต่อเนื่องมา

Helm

เราใช้ Helm ในการ template และ deploy Kubernetes app ของเราเนื่องจาก เราเลือกใช้ Kubernetes เป็น Platform หลัก เเละการใช้ Helm ก็ช่วยให้เราประหยัดเวลาในการ configure app รวมถึงช่วยให้เราสามารถ deploy app version ใหม่ได้ด้วย command เดียว ซึ่งถือว่าสะดวกมาก รวมถึงเรายังใช้ Helm ในการลง Opertor ต่างๆอย่างง่ายดาย ไม่ต้องมาไล่ configure customized object จำนวนมากด้วยตัวเอง

Data

Kafka — EventHub

เรามีการแบ่งทีมออกเป็นทีมย่อยๆ แต่ละทีมที่เรียกว่า Domain team ซึ่งมีหน้าที่ในการจัดการกับ core data ของบริษัท ยกตัวอย่างเช่น Customer data, Order data, Delivery data โดยเรา design platform ด้วย Event driven architecture ซึ่งแต่ละ domain team จะทำการ abstract ข้อมูลเเละ publish เป็น event ลง EventHub ผ่าน Kafka client และทีมที่สนใจในข้อมูลหลักเหล่านี้ก็สามารถที่จะมา subscribe event เพื่อนำไปใช้งานต่อได้

ตอนนี้เรากำลังทำ spike เพื่อหา Kafka provider เจ้าอื่นเพื่อเป็น option มาแทน EventHub เนื่องจากข้อจำกัดบางอย่างของ EventHub ที่ทำให้เราไม่สามารถมี single event stream platform เพื่อให้ทุก domain team มา publish event ในที่เดียวกัน

Redis

เราใช้ Redis ในการ store cache ที่ได้จากการ subscribe event มาเก็บไว้ใน service เเละใช้ข้อมูลจาก Redis แทนการ call API ของอีก service ตรงๆทุกครั้งที่ต้องการใช้ เพื่อที่จะสามารถ decouple service ออกจากกัน ถ้าอีก service นึงล่มไป service ที่ dependent ก็ยังสามารถรันได้ โดยใช้ข้อมูลใน Redis ที่ cache ไว้

PostgreSQL

สำหรับ Relational DB เราเลือกใช้ PostgreSQL ที่เป็น Opensource db

Cosmos DB

สำหรับบาง use case ที่เราต้องทำ aggregation บางอย่าง หรือบางทีมที่มี Data structure ที่ซับซ้อนและไม่เหมาะกับ Relational เราก็มีการใช้ Cosmos DB เก็บเป็น Document-based data (MongoDB) เช่นกัน

Testing

SonarQube

ใน CI/CD Pipeline ของเรา เราได้ทำการ integrate SonarQube ซึ่งเรา Spin ขึ้นมาใช้เองเพื่อตรวจ Code Quality โดยมีทีมกลาง เพื่อกำหนด Quality Profile โดยทุกๆทีมต้อง integrate SonarQube ใน pipeline ถ้า code coverage ไม่ถึงเกณฑ์ หรือมี bad code pipeline ก็จะ break และไม่สามารถ build ต่อได้

Gatling

เรามีการนำ Gatling ซึ่งเขียนด้วย Scala มา integrate เข้ากับ CI/CD pipeline ของเราเพื่อทำ Performance Test โดยเราสามารถกำหนด threshold ที่ต้องการ ถ้า response time ต่ำกว่าที่ต้องการ เราสามารถ break pipeline ของเราได้ถ้าต้องการ

RestAssured

ด้วย Service ของเราเขียนด้วย Spring boot อยู่เเล้ว เราเลยเลือกใช้ RestAssured มาเพื่อทำการเขียน API test เพื่อทดสอบความถูกต้องของ API หลังจาก Deploy

ArchUnit

ถึงแม้จะยังไม่ได้นำมาใช้อย่างจริงจัง แต่เราก็ได้ลองเอา ArchUnit มาลองใช้บ้าง โดยมันสามารถช่วยให้เรา validate code ของเราได้ระดับนึง ยกตัวอย่างเช่น เราได้ break layered-architecture รึเปล่า เป็นต้น

Monitoring

Datadog

เราใช้ Datadog เป็น monitoring tool ซึ่งเราได้ทำการลง Datadog agent เอาไว้ใน cluster ของเราเพื่อทำการ Feed Application metrics, Events, Logs, และ Trace เพื่อนำไปแสดงผลใน Datadog รวมถึงมีการสร้าง Alert ใน Datadog เพื่อรายงานปัญหาเข้ามาเเจ้งเตือนใน communication channel ที่เราทำงานอยู่

On-Prem Stack

สำหรับ On-premise ในตัว ภาษา และ Framework ที่ใช้ยังคงเป็น Java และ Spring boot และ CI/CD practice ก็มีความใกล้เคียงกัน แต่ในตัว platform มีความแตกต่างกันเล็กน้อย

Platform

สำหรับภายใน เราซื้อ Redhat OpenShift Cloud Platform มาใช้เป็น Private Cloud ซึ่ง OpenShift เป็น PaaS ดังนั้นเราจึงไม่จำเป็นต้องจัดการกับ Infrastructure เหมือนกับบน Cloud โดย Development team สามารถเริ่มสร้าง App ได้เลยบน Platform

ทีมกลางของเราได้เตรียมสิ่งที่เรียกว่า Starter kit Generator เอาไว้ให้ทีมอื่นๆใช้ โดยหลักการของเจ้า Starter kit ถ้าใครเคยใช้ Spring ให้ลองคิดภาพ Spring Initializer โดยทีมในบริษัทสามารถเข้ามาระบุ parameter เช่นชื่อ project ประเภทของ project จากนั้นเมื่อกด Generate ทีมก็จะได้ ตัวอย่างของ source code ที่มี best practice มีวิธีต่อกับระบบต่างๆ มี CI/CD Pipeline ที่มี Testing และ Security baked in มาให้พร้อม Development team สามารถเริ่ม Develop business feature ได้เลยโดยไม่ต้องกังวลหรือลงทุนกับ Fundamental

Frontend

Angular

สำหรับ Frontend Application ที่เรา develop in-house เราใช้ Angular เป็น framework หลัก เนื่องจาก feature Typescript ตอนที่ออกมาใหม่ๆของ Angular

Experimental Stack

High availability

จากการที่เราใช้ Terraform ในการสร้าง Infrastruture ของเราอยู่เเล้ว ดังนั้นการ deploy Infrastructure ของเราในหลายๆ Region บน Azure จึงไม่ใช่เรื่องยาก หรือเปลืองแรง เราสามารถใช้ code เดิมในการสร้าง Infra ที่หน้าตาเหมือนกันในหลาย Regions โดย Spike ล่าสุดเราได้ลองเอา Azure Front Door มาใช้เพื่อ implement High availability ในกรณีที่ service ใน Region นึง fail traffic ของ user จะถูก route ไปอีก region โดยอัตโนมัติ และในกรณีปกติ Front Door จะส่ง traffic ของ user ไปหา cluster ใน region ที่ไกล้ customer มากที่สุดเพื่อลด latency

Flux / Argo CD

แต่ในการทำ High availability การ manage หลายๆ cluster พร้อมกันค่อนข้างที่จะลำบาก เนื่องจาก Terraform ใช้ push model ในการแปลง configuration เป็น Infra แต่ไม่ได้ sync กันตลอดเวลา เราเลยกำลังที่จะลองนำ GitOps practice มาลองใช้ เพื่อช่วยในการ manage หลายๆ cluster ซึ่งเราก็กำลังศึกษา Flux กับ Argo เป็น option ในการทำ GitOps

DAST & SAST

ในส่วนของ Security scanning ทั้ง Static และ Dynamic ปัจจุบันเราก็มี internal tool ที่เราใช้ในการ scan code และ service ของเราใส่ไว้ใน Pipeline เช่นกัน แต่เรากำลังมองไปที่ OWASP tool ที่ตรงกับ Industry standard มากกว่า เช่น ZAP Tool เป็นต้น

Summary

Stack ที่เห็นยังคงเป็น Stack ที่ค่อนข้างใหม่ เพราะองค์กรของเราก็พึ่งอยู่ในช่วงเริ่มต้นของ Digital Transformation หลายๆ tool ที่เห็นก็พึ่งจะเริ่มนำเข้ามา เรียนรู้และทดลองใช้ในต้นปีนี้กับบางทีมเท่านั้น ยังไม่ใช่ภาพรวมของทั้งองค์กร สิ่งที่เรายังต้องทำคือการสร้าง Digital Platform ให้ Mature ภายในองค์กรเอง และด้วย Pace ของ Technology ในปัจจุบัน เป็นไปได้สูงว่าหลายๆอย่างจะถูกเปลี่ยนอีกในเร็วๆนี้ ยังไงผมก็จะพยายามหาเวลามาเขียน update อีกทีถ้ามี significate change ที่น่าสนใจในอนาคต

ในตอนต่อไปผมจะมาอธิบายเพิ่มเติมในส่วนของ Domain Services ที่เราออกแบบ รวมถึง Starter Kit platform ที่เราได้สร้างขึ้นมาใช้ในองค์กรเพื่อ boost initial ของการ develop software ในองค์กรขนาดใหญ่ที่ไม่ใช่ technology company

สุดท้ายเเล้ว ขอบคุณทุกคนที่สละเวลาอ่าน หวังว่าบทความนี้จะมีประโยชน์หรือน่าสนใจสำหรับ industry ครับ ขอบคุณครับ

--

--