Phát triển ứng dụng serverless Slack bằng AWS Step Funtions và AWS Lambda

Bởi Eric Johnson | 24 MAY 2023 | AWS Lambda, AWS Step Functions, Serverless

Bài đăng này được viết bởi Sam Wilson, Cloud Application Architect và John Lopez, Cloud Application Architect

Slack, một dịch vụ cộng tác và giao tiếp nội bộ dành cho doanh nghiệp, mở ra cơ hội cho các nhà phát triển cải thiện hiệu quả thông qua việc triển khai các Ứng dụng Slack (apps) được viết riêng. Một lợi ích nổi bật là cho phép tổ chức của bạn tận dụng các tài nguyên AWS hiện có mà không cần nhân viên của bạn phải truy cập Bảng điều khiển quản lý AWS (AWS Management Console) hoặc AWS CLI.

Ví dụ, một thành viên trong nhóm phân tích dữ liệu của bạn cần kích hoạt (trigger) luồng công việc (workflow) AWS Step Functions để xử lý lại một tác vụ dữ liệu hàng loạt. Thay vì cấp cho người dùng quyền truy cập trực tiếp tới luồng công việc của Step Functions trong Bảng điều khiển quản lý AWS hoặc AWS CLI, bạn có thể cung cấp quyền truy cập để gọi luồng công việc từ trong Slack channel được chỉ định.

Bài viết này đề cập đến cách kiến trúc serverless cho phép người dùng Slack gọi các tài nguyên AWS như AWS Lambda functions và Step Functions thông qua giao diện người dùng máy tính (Slack Desktop UI) và giao diện người dùng di động (Mobile UI) bằng ứng dụng Slack. Kiến trúc serverless là lựa chọn lý tưởng cho ứng dụng Slack nhờ khả năng mở rộng linh hoạt của nó. Nó có thể xử lý hàng ngàn yêu cầu đồng thời từ người dùng Slack mà không cần gánh nặng quản lý chi phí vận hành.

Ví dụ này hỗ trợ việc tích hợp với các tài nguyên AWS khác thông qua Step Functions. Truy cập tài liệu để biết thêm thông tin về việc tích hợp với các tài nguyên AWS khác.

Bài viết này giải thích về kiến trúc mẫu của serverless và hướng dẫn chi tiết cách triển khai mẫu này trong tài khoản AWS của bạn. Bài viết cũng đưa ra ví dụ và phân tích những hạn chế được phát hiện trong quá trình phát triển.

Tổng quan

Mã (code) có trong bài viết này tạo ra một ứng dụng Slack được xây dựng với nhiều dịch vụ AWS serverless:

  • Amazon API Gateway nhận tất cả các yêu cầu đến từ Slack. Step Functions điều phối các hoạt động yêu cầu như xác thực người dùng, truy xuất cấu hình, định tuyến yêu cầu và định dạng phản hồi.
  • Lambda Function gọi chức năng xác thực dành riêng cho Slack và gửi phải hồi đến giao diện người dùng Slack.
  • Amazon EventBridge đóng vai trò như một bộ tích hợp theo mô hình pub-sub giữa yêu cầu và bộ xử lý yêu cầu.
  • Amazon DynamoDB lưu trữ các quyền hạn của từng người dùng Slack để đảm bảo họ chỉ có thể truy cập đến tài tài nguyên bạn chỉ định.
  • AWS Systems Manager lưu trữ Slack channel cụ thể nơi bạn sử dụng ứng dụng Slack.
  • AWS Secrets Manager lưu trữ khóa bí mật xác thực (signing secret) và mã thông báo bot (bot token) của ứng dụng Slack.

AWS Cloud Development Kit (AWS CDK) triển khai các tài nguyên AWS. Ví dụ này có thể cắm vào bất kỳ nền tảng CI/CD hiện có nào mà bạn chọn.

Kiến trúc tổng quan

  1. Người dùng Slack trên máy tính để bàn hoặc điện thoại di động bắt đầu yêu cầu bằng cách sử dụng lệnh gạch chéo /my-slack-bot hoặc bằng cách tương tác với thành phần giao diện người dùng (UI) Slack Block Kit.
  2. API Gateway trung gian (proxy) cho yêu cầu và chuyển đổi dữ liệu (payload) thành định dạng phù hợp với luồng công việc xác thực yêu cầu của Step Functions.
  3. Trình xác thực yêu cầu kích hoạt Lambda function xác thực Slack để kiểm tra xem yêu cầu có thực sự đến từ tổ chức Slack đã được cấu hình không. Lambda function này sử dụng thư viện Slack Bot cho TypeScript để thực hiện yêu cầu xác thực và trích xuất chi tiết yêu cầu thành một dữ liệu (payload) thống nhất. Ngoài ra, Secrets Manager còn lưu trữ khóa bí mật xác thực (signing secret) mà Slack Bolt API sử dụng trong quá trình xác thực.
  4. Trình xác thực yêu cầu truy vấn bảng Authorized Users DynamoDB với tên người dùng được trích xuất từ dữ liệu trong yêu cầu (request).
  5. Trình xác thực yêu cầu truy xuất channel ID được phép và so sánh nó với channel ID có trong yêu cầu. Nếu 2 channel ID không trùng nhau, yêu cầu kết thúc với phản hồi không được ủy quyền.
  6. Trình xác thực gửi yêu cầu tới Command event bus trong EventBridge.
  7. Command event bus sử dụng thuộc tính “action” (hành động) của yêu cầu để định tuyến yêu cầu đến luồng công việc xử lý yêu cầu của Step Functions.
  8. Mỗi luồng công việc xử lý của Step Functions có thể xây dựng các thành phần giao diện người dùng (UI) Block Kit cho Slack, gửi bản cập nhập đến các thành phần giao diện hiện có, hoặc gọi Lambda functions hiện có và các luồng công việc của Step Functions.
  9. Ứng dụng di động hoặc máy tính để bàn Slack hiển thị giao diện người dùng mới hoặc cập nhật giao diện cho yêu cầu đang được xử lý.

Kiến trúc ứng dụng này có khả năng mở rộng để đáp ứng khối lượng công việc lớn trong môi trường thực tế (production), cung cấp khả năng xử lý hàng ngàn người dùng Slack đồng thời (thông qua chính nền tảng Slack), loại bỏ yêu cầu truy cập trực tiếp vào Bảng điều khiển quản lý AWS. Kiến trúc này cung cấp khả năng mở rộng dễ dàng cho ứng dụng trò chuyện để hỗ trợ các lệnh mới khi nhu cầu của người dùng phát sinh.

Cuối cùng, kiến trúc và cách triển khai của ứng dụng tuân theo các khuyến nghị của AWS Well-Architected về vận hành xuất sắc (Operational Excellence), bảo mật (Security), độ tin cậy (Reliability) và hiệu quả hoạt động (Performance Efficiency).

Step Functions phù hợp với ví dụ này vì dịch vụ này hỗ trợ tích hợp với nhiều dịch vụ AWS khác. Step Functions cho phép ví dụ này phối hợp tương tác với các Lambda function, các bảng DynamoDB và các EventBridge event busses với mã (code) tối thiểu.

Ví dụ này tận dụng Step Functions Express Workflows để hỗ trợ khối lượng lớn các hành động theo sự kiện do ứng dụng Slack tạo ra. Sử dụng Express Workflows của Step Functions giúp tạo ra bộ xử lý yêu cầu đáp ứng nhanh, có khả năng mở rộng, có thể xử lý hàng chục nghìn yêu cầu mỗi giây. Để tìm hiểu thêm, hãy xem lại sự khác biệt giữa standard and Express Workflows.

Ví dụ này sử dụng AWS Secrets Manager để lưu trữ và truy xuất an toàn các thông tin xác thực của ứng dụng. AWS Secrets Manager cung cấp các lợi ích sau:

  • Lưu trữ an toàn, tập trung các bí mật thông qua mã hóa lưu trữ (encryption-at-rest).
  • Dễ dàng quản lý quyền truy cập thông qua các chính sách quyền của AWS Identity và Access Management (IAM).
  • Hỗ trợ tích hợp sẵn với tất cả các dịch vụ AWS cấu thành kiến trúc.

Ngoài ra, ví dụ này sử dụng dịch vụ AWS Systems Manager Parameter Store để duy trì dữ liệu cấu hình của ứng dụng cho Slack Channel ID. Trong số các lợi ích được cung cấp bởi AWS System Manager, ví dụ này tận dụng tính năng lưu trữ dữ liệu cấu hình được mã hóa và hỗ trợ kiểm soát phiên bản.

Ví dụ này mô tả nhiều tương tác khác nhau cho ứng dụng Slack trên máy tính để bàn hoặc điện thoại di động, bao gồm hiển thị màn hình chào mừng, nhập thông tin biểu mẫu, và báo cáo trạng thái tiến trình. EventBridge cho phép ví dụ này định tuyến các yêu cầu từ Request Validator Step Function sử dụng serverless Event Bus và tách từng hành động ra khỏi nhau. Chúng ta cấu hình Rules để liên kết một sự kiện với Step Function của bộ xử lý yêu cầu.

Hướng dẫn

Là điều kiện tiên quyết, bạn cần những điều sau:

  • AWS CDK phiên bản 2.19.0 hoặc cao hơn.
  • Node phiên bản 16+.
  • Docker-cli.
  • Git.
  • Một tài khoản Slack cá nhân hoặc công ty có quyền tạo ứng dụng
  • Channel ID Slack của một channel trong Workspace của bạn để tích hợp với ứng dụng Slack

Chi tiết Slack channel

Để lấy Channel ID, mở menu ngữ cảnh (context menu) trên Slack channel và chọn View channel details. Bảng hiển thị Channel ID của bạn ở phía dưới:

Chi tiết Slack bot channel

Để tìm hiểu thêm, hãy truy cập trang Getting Started with Bolt for JavaScript của Slack.

Tài liệu README cho GitHub Repository có tiêu đề, Amazon Interactive Slack App Starter Kit, chứa hướng dẫn toàn diện, bao gồm các bước chi tiết cho:

  • Cấu hình Slack API
  • Triển khai ứng dụng thông qua AWS Cloud Development Kit (CDK)
  • Các bản cập nhật bắt buộc cho AWS Systems Manager Parameters and secrets

Thử nghiệm ứng dụng Slack

  1. Khởi động ứng dụng Slack bằng cách gọi câu lệnh /my-slack-bot.

Bắt đầu lệnh gọi sample Lambda

  1. Từ menu tác vụ My Slack Bot, chọn Sample Lambda.

Chọn sample Lambda

  1. Nhập lệnh đầu vào, chọn Submit, sau đó quan sát phản hồi (giá trị đầu vào này áp dụng cho sample Lambda function).

Gửi Sample Lambda 

Kết quả Sample Lambda

  1. Khởi động ứng dụng Slack bằng cách gọi lệnh /my-slack-bot, sau đó chọn Sample State Machine:

Bắt đầu gọi Sample State Machine

Chọn Sample State Machine

  1. Nhập lệnh đầu vào, chọn Submit, sau đó quan sát phản hồi (giá trị đầu vào này áp dụng cho trạng thái máy phía dưới).

Gửi Sample state machine

Kết quả của Sample state machine

Những hạn chế trong ví dụ này

Slack có những hạn chế trong việc gửi và nhận yêu cầu, nhưng các mẫu ánh xạ của API Gateway cung cấp cơ chế tích hợp với nhiều ràng buộc khác nhau.

Slack sử dụng application/x-www-form-urlencoded để gửi yêu cầu tới một URL tùy chỉnh. Chúng tôi đã thiết kế một mẫu yêu cầu để định dạng đầu vào từ Slack thành định dạng nhất quán cho  Request Validator Step Function. Các tiêu đề như X-Slack-Signature và X-Slack-Request-Timestamp cần được truyền kèm theo để đảm bảo yêu cầu từ Slack là hợp lệ.

Dưới đây là mẫu ảnh xạ yêu cầu cần thiết cho việc tích hợp:

{
  “stateMachineArn”: “arn:aws:states:us-east-1:827819197510:stateMachine:RequestValidatorB6FDBF18-FACc7f2PzNAv”,
  “input”: “{\”body\”: \”$input.path(‘$’)\”, \”headers\”: {\”X-Slack-Signature\”: \”$input.params().header.get(‘X-Slack-Signature’)\”, \”X-Slack-Request-Timestamp\”: \”$input.params().header.get(‘X-Slack-Request-Timestamp’)\”, \”Content-Type\”: \”application/x-www-form-urlencoded\”}}”
}

Slack gửi payload tin nhắn ở hai định dạng khác nhau: URL-encoded và JSON. May mắn thay, thư viện Slack Bolt for JavaScript có thể hợp nhất hai định này yêu cầu thành một JSON payload duy nhất và xử lý việc xác minh .

Slack yêu cầu một phản hồi trạng thái 204 cùng với phần nội dung trống để nhận biết rằng yêu cầu đã thành công. Mẫu phản hồi tích hợp ghi đè (override) phản hồi của Step Functions thành định dạng mà Slack chấp nhận.

Dưới đây là mẫu ảnh xạ yêu cầu cần thiết cho việc tích hợp:

#set($context.responseOverride.status = 204)
{}

Phần kết luận

Trong bài viết này, bạn đã tìm hiểu cách có thể cho phép người dùng Slack trong tổ chức của bạn có khả năng gọi các tài nguyên AWS hiện có mà không cần truy cập Bảng điều khiển quản lý AWS hoặc AWS CLI. Ví dụ serverless này cho phép bạn xây dựng luồng công việc tùy chỉnh của riêng mình để đáp ứng nhu cầu của tổ chức.

Để tìm hiểu thêm về các khái niệm được thảo luận trong bài viết này, hãy truy cập:

Để biết thêm tài nguyên học tập về serverless, truy cập Serverless Land.

TAGS: contributed, serverless

Leave a comment