in Technology

4 วิธีจัดการ Versioning และ Environment ของ AWS Lambda Function โดยไม่ต้องแก้ไขโค้ด

เป็นเรื่องสำคัญที่เรามักมองข้ามไป ว่าจะจัดการ Lambda Function อย่างไรให้ใช้ได้กับ Environment ต่างๆ เช่น Development, UAT, Production และต้องไม่กระทบกับการใช้งานของผู้ใช้ด้วย ดังนั้น สิ่งที่ต้องดูต่อ คือ เราต้องกำหนด Lambda Function Version ให้แต่ละ Environment ด้วยใช่หรือไม่?

จากที่ผมลองเล่นดู พบอยู่ 4 วิธี ที่กำลังจะเขียนแชร์ในบล็อกนี้เอง มันมีทั้งข้อดีและข้อเสีย ซึ่งผู้อ่านคงต้องนำไปพิจารณาและตัดสินใจใช้ตามความเหมาะสมกันเอง

คำแนะนำ: วิธีการที่ผมเสนอในบล็อกนี้ จะไม่ได้พูดถึงวิธีการที่ต้องมีการแก้โค้ดนะครับ รวมไปถึง ผู้อ่านควรต้องเข้าใจเรื่อง AWS API Gateway และ AWS Lambda อยู่แล้ว

1. ปรับ Version ที่ Integration Request ใน API Gateway

วิธีนี้เหมาะสำหรับ

  • ผู้ใช้ API Gateway เป็น Event Trigger เรียกใช้งาน Lambda Function
  • มี Lambda Function จำนวนน้อย
  • ทำไว้ใช้บน Test Environment เท่านั้น
  • ไม่ได้ต้องการทำ Version ให้กับ Lambda Function ทุกตัว
  • ถ้าใช้ AWS API Gateway วิธีการนี้ จะสามารถใช้งานสิ่งที่เราปรับเปลี่ยนได้ก็ต่อเมื่อมีการกดปุ่ม Deploy API

ปัญหาที่พบในวิธีนี้

  • ถ้าไม่ใช้ API Gateway จะทำแบบนี้ไม่ได้
  • ถ้ามี Lambda Function จำนวนมากๆ ต้องไล่เปลี่ยนทีละตัว ก็จะเป็นงานหนักมาก

วิธีนี้เป็นวิธี basic ที่สุดสำหรับ ผู้ใช้ API Gateway เป็น Event Trigger เรียกใช้งาน Lambda Function ซึ่งตอนผมลองเล่นแรกๆก็ทำแบบนี้แหละ

ในตัวอย่าง บนหน้าของ AWS API Gateway เมื่อเราสร้าง Resource และ Method แล้ว จะมีส่วนของ Integration Request

ในหน้าของ Integration Request เราสามารถแก้ไขการเรียกใช้งาน Lambda Function โดยระบุ Version ได้จากที่นี่เลย

2. สร้าง Version URL ใน API Gateway

วิธีนี้เหมาะสำหรับ

  • ผู้ใช้ API Gateway เป็น Event Trigger เรียกใช้งาน Lambda Function
  • ต้องการให้ผู้ใช้ API เดิมยังใช้งานได้ตามปกติ และผู้ใช้ใหม่ก็สามารถใช้ API ใหม่ได้ (หรือจะกำหนด Permission ของกลุ่มผู้ใช้เพิ่มด้วยก็ได้)
  • มี Lambda Function จำนวนไม่มากนัก
  • สามารถ Custom Lambda ในแต่ละ URL Version ได้ โดยไม่กระทบกับ URL Version อื่น
  • ถ้าใช้ AWS API Gateway วิธีการนี้ จะสามารถใช้งานสิ่งที่เราปรับเปลี่ยนได้ก็ต่อเมื่อมีการกดปุ่ม Deploy API

ปัญหาที่พบในวิธีนี้

  • ถ้าไม่ใช้ API Gateway หรือ Middleware ที่สามารถจัดการ Router ได้ จะทำแบบนี้ไม่ได้
  • จะงานหนักทันที ถ้ามี Lambda Function จำนวนมากๆ และต้องสร้าง URL Gateway ใหม่อีกชุดหนึ่ง และกำหนด Version ใหม่ (แต่ใช้ Tools จำพวก Infrastructure as code ช่วยปั๊มได้)

วิธีนี้เพิ่มมิติของการทำ Versioning โดยการกำหนด URL Version ไปด้วย ทำให้แยกกลุ่มของผู้ใช้งานได้ โดยไม่กระทบกัน

มีหลายแบรนด์ดังที่ใช้วิธีการแบบนี้ เช่น

อ้างอิง: https://mathieu.fenniak.net/aint-nobody-got-time-for-that-api-versioning/

ในตัวอย่าง บนหน้าของ AWS API Gateway คือให้เราสร้าง Resource เป็น Version ไว้เลย

จากนั้นในแต่ละ Method ใน Resource Version ต่างๆ ให้เรากำหนด Version ใน Integration Request เหมือนเดิมแบบวิธีแรก

3. สร้าง Version และกำหนด Alias ให้กับ Lambda Function

วิธีนี้เหมาะสำหรับ

  • ทุกคนที่จะนำ Lambda Function ไปใช้งาน
  • มี Lambda Function จำนวนน้อยจนถึงมากๆ
  • ใช้ได้กับทุก Environment ไม่ว่าจะ Test หรือ Production
  • มีการกำหนด Version ให้กับ Lambda Function อยู่เสมอ

ปัญหาที่พบในวิธีนี้

  • ต้องระบุ Description ใน Version ให้ดี เพื่อที่จะได้รู้ว่า แต่ละตัว มีการปรับเปลี่ยนอะไร
  • การเปลี่ยน Verion ใน Alias Name จะทำให้การทำงานไปใช้ Lambda Version นั้นทันที ไม่หมือนกับตอนทำกับ API Gateway ที่ทดสอบก่อนได้ แล้วค่อยกดปุ่ม Deploy API (แต่ทั้งนีก็สามารถ Rollback ได้ทันที)

เป็นวิธีที่ซับซ้อนขึ้นอีกนิดจากข้างต้น แต่มีประสิทธิภาพ และทาง Amazon เองก็แนะนำให้ทำแบบนี้ (AWS Lambda Function Versioning and Aliases)

โปรแกรมเมอร์เองจะต้องมีการกำหนดเวอร์ชั่นภายในทีมให้ชัดเจนว่า เมื่อไรถึงจะต้อง publish version ออกมา และนำไปลิงค์เข้าใน Alias Name เพราะการกำหนดแบบนี้จะทำให้การทำงานของ lambda เปลี่ยนทันที ไม่มีการผ่าน Deploy API

ตัวอย่างมี 2 Environment และเมื่อทำบน Development Env. เสร็จ ต้องการนำไปใช้บน Prodution Env.
อ้างอิง https://docs.aws.amazon.com/lambda/latest/dg/versioning-aliases.html
ตัวอย่างมี 3 Environment และปรับให้มีการใช้ Lambda ร่วมกัน
อ้างอิง https://docs.aws.amazon.com/lambda/latest/dg/aliases-intro.html
ตัวอย่างมี 3 Environment และมีการใช้ Lambda Version ของใครของมัน (การทำงานจริง น่าจะเป็นภาพนี้)
อ้างอิง https://docs.aws.amazon.com/lambda/latest/dg/aliases-intro.html

วิธีการทำ คือ เมื่อเรามี Version ของ Lambda อยู่แล้ว ให้ทำการสร้าง Alias Name และทำการเชื่อมกันว่า ชื่อ Alias ไหน ชี้ไป Version ไหน

ถ้าต้องการเปลี่ยน Version ก็สามารถคลิกที่ชื่อ Alias แล้วเลื่อนลงมาแก้ไข Config ได้ภายหลัง, รูปนี้ตัวอย่างของ Alias ชื่อ Prod ชี้ไปหาฟังก์ชั่น simple-hello Version 1

รูปนี้ตัวอย่างของ Alias ชื่อ Dev ชี้ไปหาฟังก์ชั่น simple-hello Version $LATEST

ในตัวอย่าง บนหน้าของ AWS API Gateway คือให้เราสร้าง Resource และกำหนดให้ Integration Request ของ Method ชี้ไปหา Alias ชื่อว่า Prod (แต่เดิมเราชี้ไปหาเลข Version, ตอนนี้ชี้ไปหาชื่อ Alias แทน) จากนั้นผม Deploy API ไปหา prod stage รอบหนึ่งก่อน เพื่อให้จำค่านั้น แล้วผมก็กลับมาเปลี่ยน Method ให้ชี้ไปหา Alias ชื่อว่า Dev และทำการ Deploy API ไปหา dev stage อีกครั้ง

ผลที่ได้จากการทำวิธีนี้

4. สร้าง Version และกำหนด Alias ให้กับ Lambda Function พร้อมกับทำ URL Verioning

วิธีนี้คือการผสมข้อ 3 และ 4 เข้าด้วยกัน กล่าวคือ ใช้ Alias Name ด้วย เพื่อให้แก้ไข Version ที่ตัว Lambda Function ได้เองเลย พร้อมกับทำ URL กำหนด Version ไว้ เพื่อป้องกันผลกระทบ กรณี เปลี่ยน Version ใน Lambda Function ผิด

สรุป

วิธีการระบุ API Version มีหลายวิธีการให้เลือกใช้ พยายามหา Best Practice ก็อาจจะเจอหลายๆแบบ แล้วแต่ว่าคนเขียนเคยทำแบบไหนแล้วเหมาะกับงานของเขา

แถม

อย่างที่ผมกล่าวข้างต้น ในบล็อกนี้มันเป็นวิธีทำที่เราไม่ต้องไปแก้ไขโค้ดใดๆ ส่วนวิธีการอย่างอื่น ก็มีอีกหลายแบบ ซึ่งลองดูรูปด้านล่างประกอบได้ครับ

ส่วนข้อดีข้อเสีย มีเทียบไว้ให้เข้าใจง่ายๆ

อ้างอิง https://www.icapps.com/blog/api-versioning-overview

อ้างอิง

  • https://docs.aws.amazon.com/lambda/latest/dg/versioning-aliases.html
  • https://docs.aws.amazon.com/lambda/latest/dg/aliases-intro.html
  • https://mathieu.fenniak.net/aint-nobody-got-time-for-that-api-versioning/
  • https://www.icapps.com/blog/api-versioning-overview