Bài đăng này được viết bởi Pal Patel, Solutions Architect, and Saud ul Khalid, Sr. Cloud Support Engineer.
Các ứng dụng serverless thường dựa vào AWS Systems Manager Parameter Store hoặc AWS Secrets Manager để lưu trữ dữ liệu cấu hình, mật khẩu được mã hóa hoặc chi tiết kết nối cho cơ sở dữ liệu hoặc dịch vụ API.
Trước đây, bạn phải thực hiện các lệnh gọi API đến AWS Parameter Store hoặc AWS Secrets Manager mỗi khi bạn muốn truy xuất một tham số hoặc một bí mật bên trong môi trường thực thi của hàm AWS Lambda. Điều này liên quan đến việc định cấu hình và khởi tạo ứng dụng khách AWS SDK cũng như quản lý thời điểm lưu trữ các giá trị trong bộ nhớ để tối ưu hóa thời lượng của chức năng, đồng thời tránh độ trễ và chi phí không cần thiết.
Tiện ích mở rộng AWS Parameters and Secrets Lambda mới cung cấp bộ nhớ đệm bí mật và tham số được quản lý cho các hàm Lambda. Tiện ích mở rộng được phân phối dưới dạng Lambda layer cung cấp bộ đệm trong bộ nhớ cho các tham số và bí mật. Nó cho phép các hàm duy trì các giá trị trong suốt vòng đời thực thi Lambda và cung cấp cài đặt thời gian tồn tại (TTL) có thể định cấu hình.
Khi bạn yêu cầu một parameter or secret trong Lambda, tiện ích mở rộng sẽ truy xuất dữ liệu từ bộ nhớ đệm trong bộ nhớ cục bộ, nếu có. Nếu dữ liệu không có trong bộ đệm hoặc đã cũ thì tiện ích mở rộng sẽ tìm nạp parameter or secret được yêu cầu từ dịch vụ tương ứng. Điều này giúp giảm các lệnh gọi API bên ngoài, có thể cải thiện hiệu suất ứng dụng và giảm chi phí. Bài đăng trên blog này cho biết cách sử dụng tiện ích mở rộng.
Tổng quan
Sơ đồ sau đây cung cấp cái nhìn tổng thể về các thành phần liên quan.
Tiện ích mở rộng có thể được thêm vào Lambda mới hoặc hiện có. Nó hoạt động bằng cách hiển thị điểm cuối HTTP cục bộ cho môi trường Lambda, môi trường này cung cấp bộ nhớ đệm trong bộ nhớ cho các parameters and secrets. Khi truy xuất một parameters hoặc secrets, trước tiên tiện ích mở rộng sẽ truy vấn bộ đệm để tìm mục nhập có liên quan. Nếu một mục nhập tồn tại, truy vấn sẽ kiểm tra xem thời gian đã trôi qua kể từ lần đầu tiên mục nhập đó được đưa vào bộ nhớ đệm và trả về mục nhập đó nếu thời gian đã trôi qua nhỏ hơn TTL bộ nhớ đệm đã định cấu hình. Nếu mục nhập cũ thì mục đó sẽ không hợp lệ và dữ liệu mới sẽ được truy xuất từ Parameter Store hoặc Secrets Manager.
Tiện ích mở rộng sử dụng cùng các quyền của vai trò thực thi Lambda IAM để truy cập vào Parameter Store và Secrets Manager, do đó, bạn phải đảm bảo rằng chính sách IAM được định cấu hình với quyền truy cập thích hợp. Quyền cũng có thể được yêu cầu đối với AWS Key Management Service (AWS KMS) nếu bạn đang sử dụng dịch vụ này. Bạn có thể tìm thấy chính sách mẫu trong AWS SAM template.
Hướng dẫn
Hãy xem xét một ứng dụng không có máy chủ cơ bản có chức năng Lambda kết nối với Amazon Relational Database Service (Amazon RDS). Ứng dụng tải cấu hình được lưu trữ trong Parameter Store và kết nối với cơ sở dữ liệu. Chuỗi kết nối cơ sở dữ liệu (bao gồm tên người dùng và mật khẩu) được lưu trữ trong Secrets Manager.
Hướng dẫn ví dụ này bao gồm:
- Lambda function
- VPC
- Multi-AZ Amazon RDS Instance running MySQL.
- AWS Secrets Manager chứa kết nối cơ sở dữ liệu.
- AWS Systems Manager Parameter Store chứa cấu hình ứng dụng.
- IAM roles
Lambda function
Python code cho thấy cách truy xuất các secrets and parameters bằng tiện ích mở rộng.
| import pymysqlimport urllib3import osimport json ### Load in Lambda environment variablesport = os.environ[‘PARAMETERS_SECRETS_EXTENSION_HTTP_PORT’]aws_session_token = os.environ[‘AWS_SESSION_TOKEN’]env = os.environ[‘ENV’]app_config_path = os.environ[‘APP_CONFIG_PATH’]creds_path = os.environ[‘CREDS_PATH’]full_config_path = ‘/’ + env + ‘/’ + app_config_pathhttp = urllib3.PoolManager() ### Define function to retrieve values from extension local HTTP server cachcedef retrieve_extension_value(url): url = (‘http://localhost:’ + port + url) headers = { “X-Aws-Parameters-Secrets-Token”: os.environ.get(‘AWS_SESSION_TOKEN’) } response = http.request(“GET”, url, headers=headers) response = json.loads(response.data) return response def lambda_handler(event, context): ### Load Parameter Store values from extension print(“Loading AWS Systems Manager Parameter Store values from ” + full_config_path) parameter_url = (‘/systemsmanager/parameters/get/?name=’ + full_config_path) config_values = retrieve_extension_value(parameter_url)[‘Parameter’][‘Value’] print(“Found config values: ” + json.dumps(config_values)) ### Load Secrets Manager values from extension print(“Loading AWS Secrets Manager values from ” + creds_path) secrets_url = (‘/secretsmanager/get?secretId=’ + creds_path) secret_string = json.loads(retrieve_extension_value(secrets_url)[‘SecretString’]) #print(“Found secret values: ” + json.dumps(secret_string)) rds_host = secret_string[‘host’] rds_db_name = secret_string[‘dbname’] rds_username = secret_string[‘username’] rds_password = secret_string[‘password’] ### Connect to RDS MySQL database try: conn = pymysql.connect(host=rds_host, user=rds_username, passwd=rds_password, db=rds_db_name, connect_timeout=5) except: raise Exception(“An error occurred when connecting to the database!”) return “DemoApp sucessfully loaded config ” + config_values + ” and connected to RDS database ” + rds_db_name + “!” |
Trong phạm vi toàn cầu, biến môi trường PARAMETERS_SECRETS_EXTENSION_HTTP_PORT được truy xuất, biến này xác định cổng mà máy chủ HTTP mở rộng đang chạy. Mặc định là 2773.
Hàm Retrieve_extension_value gọi máy chủ HTTP cục bộ của tiện ích mở rộng, truyền X-Aws-Parameters-Secrets-Token làm header. Đây là header bắt buộc sử dụng giá trị AWS_SESSION_TOKEN, giá trị này có trong môi trường thực thi Lambda theo mặc định.
Lambda handler sử dụng bộ đệm mở rộng trên mỗi lệnh gọi Lambda để lấy dữ liệu cấu hình từ Parameter Store and secret data từ Secrets Manager. Dữ liệu này được sử dụng để tạo kết nối đến cơ sở dữ liệu RDS MySQL.
Điều kiện tiên quyết
- Git
- AWS CLI
Triển khai tài nguyên
- Clone repo và cd đến repo vừa clon
git clone https://github.com/aws-samples/parameters-secrets-lambda-extension-
Sample.git
- Build và deploy bằng câu lệnh sau
sam build
sam deploy –guided
Template này có các tham số sau:
- pVpcCIDR – IP range (CIDR notation) cho VPC. Mặc định là 172.31.0.0/16
- pPublicSubnetCIDR – IP range cho public subnet. Mặc định là 172.31.3.0/24
- pPrivateSubnetACIDR – IP range cho private subnet A. Mặc định là 172.31.2.0/24
- pPrivateSubnetBCIDR – IP range cho private subnet B. Mặc định là 172.31.1.0/24
- pDatabaseName – database name cho môi trường dev. Mặc định là devDB
- pDatabaseUsername – database username cho môi trường dev. Mặc định là myadmin
- pDBEngineVersion – phiên bản MySQL đang sử dụng
Thêm tiện ích mở rộng Lambda Parameter Store và Secrets Manager
Để thêm tiện ích,
- Điều hướng đến Lambda console và mở Lambda mà bạn đã tạo.
- Trong tab Function Overview. chọn Layers rồi chọn Add a layer\
- Trong ngăn Choose a layer, giữ nguyên lựa chọn mặc định của AWS layers và trong danh sách thả xuống, hãy chọn AWS Parameters and Secrets Lambda Extension.
- Chọn phiên bản mới nhất có sẵn và chọn Add
Tiện ích mở rộng hỗ trợ một số tùy chọn có thể định cấu hình có thể được thiết lập dưới dạng biến môi trường Lambda.
Ví dụ này đặt rõ ràng một cổng mở rộng và giá trị TTL:
Kiểm tra ứng dụng
Để kiểm tra,
- Điều hướng đến hàm được tạo trong Lambda console và chọn tab Test
- Đặt tên cho event, giữ nguyên giá trị mặc định rồi chọn Create
- Chọn Test. Hàm đã chạy thành công
Để đánh giá lợi ích về hiệu suất của bộ đệm mở rộng Lambda, 3 test đã được chạy bằng cách sử dụng công cụ nguồn mở Artillery để tải thử Lambda. Điều này có thể sử dụng URL Lambda để gọi hàm. Artillery configuration hiển thị thời lượng và yêu cầu mỗi giây cho bài kiểm tra:
config:
target: “https://lambda.us-east-1.amazonaws.com”
phases:
–
duration: 60
arrivalRate: 10
rampTo: 40
scenarios:
–
flow:
–
post:
url: “https://abcdefghijjklmnopqrst.lambda-url.us-east-1.on.aws/“
- Test 1: Bộ đệm mở rộng bị tắt bằng cách đặt biến môi trường TTL thành 0. Điều này dẫn đến 1650 lệnh gọi API GetParameter đến Parameter Store trong hơn 60 giây.
- Test 2: Bộ đệm mở rộng được bật với TTL là 1 giây. Điều này dẫn đến 106 lệnh gọi API GetParameter trong hơn 60 giây.
- Test 3: Tiện ích mở rộng được bật với giá trị TTL là 300 giây. Điều này dẫn đến chỉ 18 lệnh gọi API GetParameter trong 60 giây.
Trong test 3, giá trị TTL dài hơn thời gian thử nghiệm. 18 lệnh gọi GetParameter tương ứng với số lượng môi trường thực thi Lambda do Lambda tạo để chạy các yêu cầu song song. Mỗi môi trường thực thi có bộ đệm trong bộ nhớ riêng và do đó, mỗi môi trường cần thực hiện lệnh gọi API GetParameter.
Trong thử nghiệm này, việc sử dụng tiện ích mở rộng đã giảm số lượng lệnh gọi API xuống ~98%. Giảm lệnh gọi API giúp giảm thời gian thực hiện chức năng và do đó giảm chi phí.
Dọn dẹp
Sau khi bạn kiểm tra ví dụ này, hãy xóa các tài nguyên do template tạo bằng cách sử dụng các lệnh sau từ cùng thư mục dự án để tránh tiếp tục bị tính phí vào tài khoản của bạn.
sam delete
Kết luận
Bộ nhớ đệm dữ liệu được truy xuất từ các dịch vụ bên ngoài là một cách hiệu quả để cải thiện hiệu suất của hàm Lambda và giảm chi phí. Việc triển khai lớp bộ nhớ đệm đã trở nên đơn giản hơn nhờ tiện ích mở rộng Lambda do AWS quản lý này.