Xây dựng các serverless API riêng tư với AWS Lambda và Amazon VPC Lattice

Bài đăng này được viết bởi Josh Kahn, Trưởng nhóm công nghệ Serverless.

Amazon VPC Lattice là một dịch vụ ứng dụng mạng mới, có tính sẵn sàng nhằm đơn giản hóa khả năng kết nối giữa các dịch vụ. Các nhà phát triển có thể kết nối, bảo mật và giám sát các dịch vụ trên các instances, container hoặc các dịch vụ điện toán không máy chủ một cách đơn giản và nhất quán.

VPC Lattice hỗ trợ các hàm AWS Lambda vừa là mục tiêu nhận dữ liệu vừa là dịch vụ sử dụng các dịch vụ khác. Bài đăng này sẽ khám phá cách kết hợp VPC Lattice vào serverless workload của bạn để đơn giản hóa việc truy cập riêng tư (private access) vào các HTTP API được xây dựng bằng Lambda.

I. Tổng quan

VPC Lattice là dịch vụ mạng cho phép các dịch vụ khám phá và kết nối đến các dịch vụ khác trên các VPC và các tài khoản AWS khác. VPC Lattice bao gồm các tính năng cho phép nhà phát triển định nghĩa các chính về sách truy cập mạng, quản lý và giám sát lưu lượng. Nó cũng hỗ trợ gán tên miền tùy chỉnh cho các private endpoint.

VPC Lattice gồm một số thành phần chính như:

  • Dịch vụ mạng – một cơ chế nhóm theo logic tập hợp các dịch vụ mà bạn có thể áp dụng các chính sách chung. Gán vào một hoặc nhiều VPC để cho phép các dịch vụ trong VPC đó truy cập vào mạng dịch vụ.
  • Dịch vụ – một đơn vị phần mềm thực hiện một nhiệm vụ hoặc một chức năng cụ thể. Các dịch vụ sử dụng VPC Lattice có thể chạy trên instance, container hoặc các dich vụ điện toán không máy chủ. Bài viết này sẽ tập trung vào các dịch vụ được xây dựng bằng hàm Lambda.
  • Nhóm các mục tiêu (Target group) – trong ứng dụng theo mô hình serverless, hàm Lambda thực hiện logic nghiệp vụ để phản hồi các yêu cầu. Các quy tắc định tuyến trong dịch vụ sẽ điều hướng các yêu cầu đến nhóm các mục tiêu thích hợp.
  • Chính sách xác thực – chính sách tài nguyên của AWS Identity and Access Management (IAM) có thể được gán vào dịch vụ mạng và các dịch vụ xác định quyền truy cập vào các dịch vụ đó.

VPC Lattice cho phép kết nối xuyên suốt giữa các VPC và các tài khoản, đồng thời giảm bớt sự phức tạp của tầng mạng bên dưới. Nó hỗ trợ các giao thức HTTP/HTTPS và gRPC, mặc dù gRPC hiện không áp dụng được cho các nhóm mục tiêu là Lambda.

II. VPC Lattice và Lambda

Lambda là một trong những lựa chọn để xây dựng dịch vụ VPC Lattice. AWS Lambda console hỗ trợ VPC Lattice như là một trình kích hoạt (trigger), tương tự như các trình kích hoạt đã tồn tại như Amazon API Gateway và Amazon EventBridge. Bạn cũng có thể dùng VPC Lattice dưới dạng nguồn sự kiện bằng cách sử dụng công cụ cơ sở hạ tầng dưới dạng mã, chẳng hạn như AWS CloudFormationTerraform.

Để cấu hình VPC Lattice như một trình kích hoạt cho hàm Lambda trong Bảng điều khiển, hãy chọnn hàm mong muốn và chọn tab Configuration. Chọn menu Triggers ở bên trái rồi chọn Add trigger.

Trình hướng dẫn cấu hình trình kích hoạt (trigger) cho phép bạn định nghĩa một dịch vụ VPC Lattice mới do hàm Lambda cung cấp hoặc thêm vào dịch vụ đang sẵn có. Khi thêm một dịch vụ hiện có, trình hướng dẫn cho phép cấu hình định tuyến dựa trên đường dẫn (path-base) để gửi yêu cầu đến nhóm mục tiêu (target group) có chứa hàm đó. Cơ chế định tuyến dựa trên đường dẫn và các cơ chế định tuyến khác có sẵn từ VPC Lattice sẽ rất hữu ích trong các tình huống cần migrate.

Ví dụ này thể hiện việc tạo mới một dịch vụ. Cung cấp tên độc nhất cho dịch vụ và chọn dịch vụ VPC Lattice mong muốn. Nếu bạn chưa tạo mạng dịch vụ (service network), hãy nhấp vào liên kết để tạo mạng dịch vụ mới trong Bảng điều khiển củaVPC (để tạo mạng dịch vụ mới, hãy đọc tài liệu VPC Lattice).

Cấu hình listener cho phép bạn cấu hình giao thức và cổng mà dịch vụ có thể truy cập được. HTTPS (cổng 443) là cấu hình mặc định, mặc dù bạn cũng có thể định cấu hình listener cho HTTP (cổng 80). Hãy lưu ý rằng việc cấu hình listener cho HTTP không làm thay đổi hành vi của Lambda: nó vẫn được VPC Lattice gọi qua HTTPS endpoint, nhưng endpoint dịch vụ cũng sẵn sàng dưới dạng HTTP. Chọn Add để hoàn tất thiết lập.

Ngoài việc định cấu hình target group và dịch vụ VPC Lattice, Lambda wizard còn bổ sung chính sách tài nguyên (resource policy) vào hàm cho phép nhóm mục tiêu (target group) VPC Lattice gọi hàm.

III. Tích hơp VPC Lattice

Khi một client gửi yêu cầu đến dịch vụ VPC Lattice được hỗ trợ bởi nhóm mục tiêu Lambda, VPC Lattice sẽ gọi hàm Lambda đích theo một cách đồng bộ. Trong quá trình gọi đồng bộ, máy client chờ kết quả của hàm và tất cả việc xử lý gửi lại được máy client thực hiện. VPC Lattice có idle timeout là một phút và connection timeout là mười phút đối với cả client và mục tiêu.

Payload của sự kiện mà hàm Lambda nhận được khi VPC Lattice gọi sẽ tương tự như ví dụ sau. Lưu ý rằng mã hóa theo base64 sẽ phụ thuộc vào loại nội dung trong body.

{    “body”: “{ “\userId\”: 1234, \”orderId\”: \”5C71D3EB-3B8A-457B-961D\” }”,    “headers”: {        “accept”: “application/json, text/plain, */*”,        “content-length”: “156”,        “user-agent”: “axios/1.3.4”,        “host”: “myvpclattice-service-xxxx.xxxx.vpc-lattice-svcs.us-east-2.on.aws”,        “x-forwarded-for”: “10.0.129.151”    },    “is_base64_encoded”: false,    “method”: “PUT”,    “query_string_parameters”: {        “action”: “add”    },    “raw_path”: “/points?action=add”}

Payload của phản hồi được hàm Lambda trả về bao gồm mã trạng thái (status code), tiêu đề, mã hóa base64 và phần nội dung tùy chọn như trong ví dụ sau. Payload phản hồi không đáp ứng được yêu cầu nhất định sẽ dẫn đến lỗi. Để trả về nội dung nhị phân, bạn phải đặt isBase64Encoded thành true.

{    “isBase64Encoded”: false,    “statusCode”: 200,    “statusDescription”: “200 OK”,    “headers”: {        “Set-Cookie”: “cookies”,        “Content-Type”: “application/json”    },    “body”: “Hello from Lambda (optional)”}

Để biết thêm chi tiết về việc tích hợp giữa VPC Lattice và Lambda, hãy truy cập tài liệu của Lambda.

IV. Gọi dịch vụ VPC Lattice từ Lambda

Các dịch vụ VPC Lattice hỗ trợ kết nối qua giao thức HTTP/HTTPS và gRPC cũng như quyền truy cập hoặc ủy quyền thông qua IAM. Để gọi dịch vụ VPC Lattice, hàm Lambda phải được gắn vào VPC đã được gán với dịch vụ VPC Lattice:

Mặc dù hàm gọi dịch vụ VPC Lattice phải được gán với một VPC thích hợp, nhưng hàm Lambda thuộc nhóm mục tiêu (target group) của dịch vụ Lattice không cần phải được gắn vào VPC. Hãy nhớ rằng các hàm Lambda luôn được gọi thông qua AWS endpoint với quyền truy cập do AWS IAM kiểm soát.

Lệnh gọi đến dịch vụ VPC Lattice tương tự như gửi yêu cầu đến các dịch vụ HTTP/HTTPS khác. VPC Lattice cho phép người phát triển định nghĩa các chính sách xác thực tuỳ chỉnh để thực thi việc xác thực và thực hiện ủy quyền theo ngữ cảnh cụ thể cũng như triển khai các biện pháp kiểm soát ở cấp mạng cho các security groups. Nguồn gọi dịch vụ phải đáp ứng các yêu cầu về kết nối mạng và ủy quyền để truy cập dịch vụ. VPC Lattice chặn lưu lượng truy cập nếu nó không đáp ứng đầy đủ tất cả các điều kiện trước khi hàm của bạn được gọi.

Hàm Lambda gọi dịch vụ VPC Lattice phải có quyền cần thiết để gọi dịch vụ đó, trừ khi auth type cho dịch vụ đó là NONE. Bạn cung cấp quyền đó thông qua policy gắn liền với execution role của hàm Lambda, ví dụ:

{    “Action”: “vpc-lattice-svcs:Invoke”,    “Resource”: “arn:aws:vpc-lattice:us-east-2:123456789012:service/svc-123abc/*”,    “Effect”: “Allow”}

Nếu chính sách xác thực được gắn với mạng dịch vụ hoặc dịch vụ của bạn bắt buộc các yêu cầu (request) xác thực thì mọi yêu cầu được gửi tới dịch vụ đó phải chứa chữ ký yêu cầu (request signature) hợp lệ được tạo ra bởi Chữ ký Phiên bản 4 (SigV4). Bạn có thể tìm thấy ví dụ về Tính toán tạo chữ ký SigV4 trong tài liệu VPC Lattice. Hiện tại, VPC Lattice không hỗ trợ việc ký payload. Trong TypeScript, bạn có thể ký các request bằng AWS SDK và thư viện Axios như sau:

const signedRequest = await sigv4.sign({    method: “PUT”,    hostname: endpointUrl.host,    path: endpointUrl.pathname,    protocol: endpointUrl.protocol,    headers: {        ‘Content-Type’: ‘application/json’,        host: endpointUrl.hostname,        // Include following header as VPC Lattice does not support signed payloads        “x-amz-content-sha256”: “UNSIGNED-PAYLOAD”    }  });      const { data } = await axios({    …signedRequest,    data: {        // some data    },    url: VPC_LATTICE_SERVICE_ENDPOINT  });

VPC Lattice cung cấp nhiều lớp kiểm soát bảo mật, bao gồm các chính sách xác thực và chính sách ở tầng mạng, cho phép (hoặc từ chối) quyền truy cập từ client vào dịch vụ của bạn. Các biện pháp kiểm soát này có thể được triển khai tại mạng dịch vụ, áp dụng các biện pháp kiểm soát đó trên tất cả các dịch vụ trong mạng.

V. Kết nối đến dịch vụ VPC Lattice bất kỳ

VPC Lattice hỗ trợ các dịch vụ được tạo trên Amazon EKSAmazon EC2 ngoài Lambda. Việc gọi các dịch vụ được xây dựng trên các dịch vụ điện toán này tương tự như mẫu trong ví dụ bên trên. VPC Lattice cung cấp một điểm cuối “làm mờ” cách triển khai thực sự phía sau của dịch vụ này.

Một hàm Lambda được cấu hình để truy cập tài nguyên trong một VPC có khả năng truy cập các dịch vụ VPC Lattice trong mạng dịch vụ được liên kết với VPC đó. Quyền từ IAM, chính sách xác thực gắn liền với dịch vụ và ecurity groups cũng có thể ảnh hưởng đến việc hàm có thể gọi dịch vụ hay không (xem tài liệu VPC Lattice để biết chi tiết về cách bảo mật dịch vụ của bạn).

Các dịch vụ được triển khai trên cụm Amazon EKS cũng có thể gọi các hàm Lambda dưới dạng dịch vụ VPC Lattice bằng cách sử dụng ngữ nghĩa từ Kubernetes. Chúng có thể sử dụng tên miền do VPC Lattice tạo hoặc tên miền tùy chỉnh đã cấu hình từ trước để gọi hàm Lambda thay vì API Gateway hoặc Application Load Balancer (ALB). Tham khảo bài đăng này trên Blog AWS Container để biết chi tiết về cách dịch vụ Amazon EKS gọi dịch vụ VPC Lattice khi bật kiểm soát truy cập (access control).

VI. Xây dựng private serverless APIs

Với việc ra mắt VPC Lattice, AWS hiện cung cấp một số tùy chọn để xây dựng các API không có máy chủ chỉ có thể truy cập được trong VPC khách hàng của bạn. Các tùy chọn này bao gồm API Gateway, ALB và VPC Lattice. Mỗi dịch vụ này đều cung cấp một bộ tính năng riêng biệt và có những đánh đổi riêng có thể giúp một dịch vụ phù hợp hơn với khối lượng công việc của bạn so với những dịch vụ khác.

Private API sử dụng API Gateway cung cấp một bộ tính năng phong phú, bao gồm điều chỉnh, lưu vào bộ nhớ đệm và cung cấp API key. API Gateway cũng cung cấp nhiều tùy chọn định tuyến và ủy quyền phong phú. Kiến thức chi tiết về mạng và DNS có thể được yêu cầu trong các môi trường phức tạp. Cả hai điều khiển chính sách tài nguyên và cấp độ mạng đều có sẵn để kiểm soát quyền truy cập và đặc tả OpenAPI cho phép chia sẻ lược đồ.

Cân bằng tải ứng dụng cung cấp tính linh hoạt và bộ tùy chọn định tuyến phong phú, bao gồm nhiều mục tiêu khác nhau. ALB cũng có thể cung cấp địa chỉ IP tĩnh thông qua AWS Global Accelerator. Cần có kiến thức mạng chi tiết để định cấu hình kết nối tài khoản/VPC chéo. ALB dựa vào các điều khiển cấp độ mạng.

Mạng dịch vụ trong VPC Lattice đơn giản hóa việc truy cập vào các dịch vụ trên EC2, EKS và Lambda trên VPC và tài khoản mà không yêu cầu kiến thức chi tiết về mạng và DNS. VPC Lattice cung cấp một phương tiện tập trung để quản lý kiểm soát truy cập và các biện pháp bảo vệ cho hoạt động liên lạc giữa các dịch vụ. VPC Lattice cũng sẵn sàng hỗ trợ các tên miền tùy chỉnh và tính năng định tuyến (đường dẫn, phương thức, tiêu đề) cho phép khách hàng xây dựng các API riêng phức tạp mà không cần quản lý mạng phức tạp. VPC Lattice có thể được sử dụng để cung cấp liên lạc liên dịch vụ đông-tây kết hợp với API Gateway và AWS AppSync nhằm cung cấp điểm cuối công cộng cho dịch vụ của bạn.

VII. Kết luận

Chúng tôi rất vui mừng về khả năng kết nối đơn giản hóa hiện có trong VPC Lattice. Người xây dựng có thể tập trung vào việc tạo ra giá trị cho khách hàng và các tính năng khác biệt thay vì kết nối mạng phức tạp giống như cách Lambda cho phép bạn tập trung vào viết mã. Nếu bạn muốn tìm hiểu thêm về VPC Lattice, chúng tôi khuyên bạn nên sử dụng Hướng dẫn sử dụng VPC Lattice.