Tại sao Shopify quyết định viết Terraform Provider riêng cho Twilio

Mọi người làm DevOps hay SRE chắc đã gặp cảnh phải quản lý hạ tầng ngày càng phình to. Hồi xưa thì có vài con servers, giờ thì cả một hệ sinh thái từ cloud services, CDN, cho tới các dịch vụ bên thứ ba. Chuyện click tay trên giao diện web để cấu hình ban đầu có thể nhanh, nhưng khi hệ thống lớn lên thì nó thực sự khá là nhọc. Không có history, không review được, sai một ly là đi một dặm thật sự.

Nay mình có nghiên cứu thấy được một case study thấy khá hay của Shopify, cho thấy tư duy Infrastructure as Code (IaC) có thể áp dụng rộng hơn nhiều so với việc chỉ quản lý server hay Kubernetes cluster. Họ đã dùng Terraform để quản lý một thứ tưởng chừng không liên quan đó là hệ thống tổng đài của Twilio.

Thật sự khá là hay ho về tư duy sáng tạo của họ khi đã hiểu được bản chất của công cụ không phải bị dính vào khuôn mẫu là “Công cụ A phải thế này, công cụ B phải thế kia”

Hậu quả của việc cấu hình tay

Đây là một sự việc về đội Contact Center ở Shopify chịu trách nhiệm xây dựng công cụ cho các bạn chăm sóc khách hàng. Một trong những công cụ lõi họ dùng là Twilio TaskRouter, một dịch vụ của Twilio giúp định tuyến các cuộc gọi, tin nhắn chat tới đúng nhân viên hỗ trợ. Ví dụ, khách hàng ở Việt Nam sẽ được chuyển tới team hỗ trợ tiếng Việt, khách hàng VIP sẽ được ưu tiên.

Ban đầu, mọi rule định tuyến này đều được cấu hình thủ công trên website của Twilio. Mọi thứ vẫn ổn cho tới khi logic nghiệp vụ ngày càng phức tạp. Việc quản lý các rule này trở thành gánh nặng:

  • Phụ thuộc vào một vài người: Chỉ vài kỹ sư nắm rõ logic và có quyền thay đổi, tạo ra bottleneck.
  • Không có review: Một người vào chỉnh sửa, không có ai kiểm tra lại. Lỡ cấu hình sai một rule có thể ảnh hưởng đến cả luồng hỗ trợ khách hàng.
  • Không có lịch sử thay đổi: Khi có sự cố, việc truy vết xem ai đã thay đổi gì, thay đổi khi nào, và tại sao lại thay đổi là cực kỳ khó khăn. Việc rollback về cấu hình cũ gần như là không thể một cách an toàn.

Nghe quen không anh em? Đây chính là lúc họ quyết định phải tìm một giải pháp bền vững hơn và Infrastructure đó là Code với Terraform.

Giải pháp biến mọi cấu hình thành code

Ý tưởng của team Shopify rất đơn giản: nếu đã quản lý server bằng code được, tại sao không quản lý rule của Twilio bằng code? Để làm được điều này với Terraform, có 3 yêu cầu cốt lõi:

  1. API đáng tin cậy: Dịch vụ mà anh em muốn quản lý (ở đây là Twilio) phải cung cấp một bộ API đủ mạnh và ổn định để thực hiện các thao tác CRUD . Nếu service đó chỉ cho phép cấu hình qua giao diện web thì đành bó tay. May mắn là Twilio có một bộ API rất tốt.
  2. Terraform Provider: Terraform cần một plugin gọi là Provider để giao tiếp được với API của dịch vụ. Provider này giống như một trình thông dịch, nó định nghĩa các resource (ví dụ: twilio_taskrouter_workflow, twilio_taskrouter_queue) và dịch từ cú pháp HCL của Terraform ra các lệnh gọi API tương ứng. Các ông lớn như AWS, GCP, Azure đều tự viết và duy trì provider cho sản phẩm của họ.
  3. Client Library: Thay vì để provider tự gọi API trực tiếp, cách làm tốt nhất là xây dựng một thư viện client riêng biệt. Provider sẽ gọi qua thư viện này. Việc này giúp tách biệt logic, dễ bảo trì và tái sử dụng hơn.

Vào thời điểm đó, chưa có Terraform Provider chính thức cho Twilio TaskRouter. Khó khăn nhưng đội ngũ của Shopify đã quyết định tự xây dựng một cái.

Họ định nghĩa các resource cần quản lý, viết logic CRUD cho từng loại, và quan trọng là xây dựng cả chức năng import. Chức năng này cực kỳ hữu ích, nó cho phép Terraform có thể tiếp nhận những tài nguyên đã được tạo bằng tay từ trước, để từ đó chúng được quản lý bằng code mà không cần phải xóa đi tạo lại.

Sau khi có provider, việc cấu hình một rule định tuyến phức tạp trông sẽ gọn gàng như thế này trong code HCL:

# File: workflows.tf
# Ví dụ minh họa cách định nghĩa một workflow định tuyến trong Twilio

provider "twilio" {
  account_sid = var.twilio_account_sid
  auth_token  = var.twilio_auth_token
}

resource "twilio_taskrouter_workflow" "support_task_routing" {
  friendly_name = "Support Task Routing v2"
  workspace_sid = "WSxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

  configuration = jsonencode({
    task_routing = {
      filters = [
        {
          friendly_name = "VIP customers to Tier-1 Support"
          expression    = "customer_priority == 'high'"
          targets = [
            {
              queue    = "WQxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # Tier-1 Queue SID
              priority = 10
              timeout  = 300
            }
          ]
        },
        {
          friendly_name = "General customers to Tier-2 Support"
          expression    = "1==1" # Rule bắt tất cả các trường hợp còn lại
          targets = [
            {
              queue    = "WQyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" # Tier-2 Queue SID
              priority = 1
            }
          ]
        }
      ]
      default_filter = {
        queue = "WQzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" # Default Queue SID
      }
    }
  })
}

Nhìn vào file config trên, mọi người có thể thấy ngay logic định tuyến: khách VIP thì vào queue ưu tiên, còn lại thì vào queue thường. Mọi thứ rõ ràng, minh bạch.

Việc áp dụng Terraform đã thay đổi hoàn toàn quy trình làm việc của team

  • Minh bạch và có kiểm soát: Mọi thay đổi về rule đều phải đi qua một quy trình chuẩn: tạo Pull Request, có người review, chạy CI/CD để kiểm tra cú pháp rồi mới được apply. Lịch sử thay đổi được lưu lại toàn bộ trên Git.
  • Giảm thiểu lỗi con người: Không còn cảnh click nhầm trên giao diện. Mọi thứ đều là code, có thể kiểm tra và lường trước được tác động.
  • Trao quyền cho các team khác: Đây là lợi ích lớn nhất. Giờ đây, các team nghiệp vụ hay team support nếu muốn thay đổi một rule nhỏ, họ không cần phải tạo ticket chờ developer làm nữa. Họ có thể tự vào sửa file HCL, tạo một Pull Request, và đội kỹ thuật chỉ cần vào review và duyệt. Việc này giúp giải phóng thời gian cho developer và tăng tốc độ phản ứng của cả công ty.

Cuối cùng

Câu chuyện của Shopify cho thấy một bài học quan trọng: tư duy Infrastructure đó là Code không nên bị giới hạn trong phạm vi của cloud provider. Bất kỳ dịch vụ nào, dù là SaaS của bên thứ ba, miễn là nó có một bộ API đủ tốt, chúng ta đều có thể và nên quản lý nó bằng code.

Lần tới khi team mọi người phải vật lộn với việc cấu hình thủ công một công cụ nào đó, hãy thử đặt câu hỏi: Liệu nó có API không? Liệu đã có Terraform provider cho nó chưa? Nếu chưa, liệu việc tự xây dựng một cái có đáng để đầu tư không?

Quản lý mọi thứ bằng code không chỉ giúp hệ thống ổn định, an toàn hơn mà còn thay đổi cả văn hóa làm việc, giúp mọi người cộng tác hiệu quả hơn khá nhiều đấy.

Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận