本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
教學課程:使用 Amazon OpenSearch Service 建立一個搜尋應用程式
使用 Amazon OpenSearch Service 建立搜尋應用程式的常見方法是使用 web 表單將使用者查詢傳送到伺服器。接著,您可以授權伺服器直接呼叫 OpenSearch API 並讓伺服器將請求傳送至 OpenSearch Service。但是如果您想要編寫不依賴伺服器的用戶端程式碼,您應彌補安全性和效能風險。允許對 OpenSearch API 的未簽署、公開存取是不明智的做法。使用者可能會透過過於廣泛的查詢 (或太多查詢) 存取不安全的端點或影響叢集效能。
本章提供解決方案:使用 Amazon API Gateway 將使用者限制為 OpenSearch APIs的子集 AWS Lambda ,以及簽署從 API Gateway 到 OpenSearch Service 的請求。

注意
標準 API Gateway 和 Lambda 定價適用,但在此教學課程的限制使用量之內,成本應微乎其微。
先決條件
此教學的先決條件是 OpenSearch Service 網域。如果沒有,請遵循建立 OpenSearch Service 網域中的步驟建立一個。
步驟 1:索引範例資料
下載 sample-movies.zip、進行解壓縮,然後使用 _bulkmovies
索引:
POST https://search-my-domain
.us-west-1
.es.amazonaws.com/_bulk
{ "index": { "_index": "movies", "_id": "tt1979320" } }
{"directors":["Ron Howard"],"release_date":"2013-09-02T00:00:00Z","rating":8.3,"genres":["Action","Biography","Drama","Sport"],"image_url":"http://ia.media-imdb.com/images/M/MV5BMTQyMDE0MTY0OV5BMl5BanBnXkFtZTcwMjI2OTI0OQ@@._V1_SX400_.jpg","plot":"A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.","title":"Rush","rank":2,"running_time_secs":7380,"actors":["Daniel Brühl","Chris Hemsworth","Olivia Wilde"],"year":2013,"id":"tt1979320","type":"add"}
{ "index": { "_index": "movies", "_id": "tt1951264" } }
{"directors":["Francis Lawrence"],"release_date":"2013-11-11T00:00:00Z","genres":["Action","Adventure","Sci-Fi","Thriller"],"image_url":"http://ia.media-imdb.com/images/M/MV5BMTAyMjQ3OTAxMzNeQTJeQWpwZ15BbWU4MDU0NzA1MzAx._V1_SX400_.jpg","plot":"Katniss Everdeen and Peeta Mellark become targets of the Capitol after their victory in the 74th Hunger Games sparks a rebellion in the Districts of Panem.","title":"The Hunger Games: Catching Fire","rank":4,"running_time_secs":8760,"actors":["Jennifer Lawrence","Josh Hutcherson","Liam Hemsworth"],"year":2013,"id":"tt1951264","type":"add"}
...
請注意,上述是具有一小部分可用資料的範例命令。若要執行 _bulk
操作,您需要複製並貼上sample-movies
檔案的完整內容。如需進一步說明,請參閱 選項 2:上傳多個文件。
您也可以使用下列 curl 命令來達成相同的結果:
curl -XPOST -u '
master-user
:master-user-password
' 'domain-endpoint/_bulk' --data-binary @bulk_movies.json -H 'Content-Type: application/json'
步驟 2:建立和部署 Lambda 函數
在 API Gateway 中建立 API 之前,請先建立傳遞請求的 Lambda 函數。
建立 Lambda 函式
在此解決方案中,API Gateway 會將請求傳遞至 Lambda 函數,該函數會查詢 OpenSearch Service 並傳回結果。由於此範例函數使用外部程式庫,您需要建立部署套件並將其上傳至 Lambda。
建立部署套件
-
開啟命令提示字元並建立
my-opensearch-function
專案目錄。例如,在 macOS 上:mkdir my-opensearch-function
-
導覽至
my-sourcecode-function
專案目錄。cd my-opensearch-function
-
複製下列範例 Python 程式碼的內容,並將其儲存在名為 的新檔案中
opensearch-lambda.py
。將您的區域和主機端點新增至 檔案。import boto3 import json import requests from requests_aws4auth import AWS4Auth
region
= '' # For example, us-west-1 service = 'es' credentials = boto3.Session().get_credentials() awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)host
= '' # The OpenSearch domain endpoint with https:// and without a trailing slash index = 'movies' url = host + '/' + index + '/_search' # Lambda execution starts here def lambda_handler(event, context): # Put the user query into the query DSL for more accurate search results. # Note that certain fields are boosted (^). query = { "size": 25, "query": { "multi_match": { "query": event['queryStringParameters']['q'], "fields": ["title^4", "plot^2", "actors", "directors"] } } } # Elasticsearch 6.x requires an explicit Content-Type header headers = { "Content-Type": "application/json" } # Make the signed HTTP request r = requests.get(url, auth=awsauth, headers=headers, data=json.dumps(query)) # Create the response and add some extra content to support CORS response = { "statusCode": 200, "headers": { "Access-Control-Allow-Origin": '*' }, "isBase64Encoded": False } # Add the search results to the response response['body'] = r.text return response -
將外部程式庫安裝到新的
package
目錄。pip3 install --target ./package boto3 pip3 install --target ./package requests pip3 install --target ./package requests_aws4auth
-
在根目錄中使用已安裝的程式庫建立部署套件。下列命令會在您的專案目錄中產生
my-deployment-package.zip
檔案。cd package zip -r ../my-deployment-package.zip .
-
將
opensearch-lambda.py
檔案新增至 zip 檔案的根目錄。cd .. zip my-deployment-package.zip opensearch-lambda.py
如需建立 Lambda 函數和部署套件的詳細資訊,請參閱 AWS Lambda 開發人員指南中的使用 .zip 封存檔部署 Python Lambda 函數以及本指南中的 建立 Lambda 部署套件。
使用 Lambda 主控台建立函數
-
導覽至位於 https://https://console.aws.amazon.com/lambda/home
的 Lambda 主控台。在左側導覽窗格中,選擇函數。 -
選取 Create function (建立函式)。
-
設定下列欄位:
-
函數名稱:openearch-function
-
執行時間:Python 3.9
-
架構:x86_64
保留所有其他預設選項,然後選擇建立函數。
-
-
在函數摘要頁面的程式碼來源區段中,選擇從下拉式清單上傳,然後選取 .zip 檔案。找到您建立
my-deployment-package.zip
的檔案,然後選擇儲存。 -
處理常式是函數程式碼中處理事件的方法。在執行時間設定下,根據 Lambda 函數所在的部署套件中的檔案名稱,選擇編輯和變更處理常式名稱。由於您的檔案名為
opensearch-lambda.py
,請將處理常式重新命名為
。如需詳細資訊,請參閱 Python 中的 Lambda 函數處理常式。opensearch-lambda
.lambda_handler
步驟 3:在 API Gateway 中建立 API
使用 API Gateway 來建立更為有限的 API 並簡化與 OpenSearch _search
API 互動的程序。API Gateway 可啟用安全性功能,例如 Amazon Cognito 身分驗證和請求調節。請執行下列步驟,來建立和部署 API:
建立和設定 API
若要使用 API Gateway 主控台建立 API
-
導覽至 API Gateway 主控台,網址為 https://https://console.aws.amazon.com/apigateway/home
。在左側導覽窗格中,選擇 APIs。 -
找到 REST API (非私有) 並選擇 Build (建置)。
-
在下列頁面上,找到建立新 API 區段,並確認已選取新 API。
-
設定下列欄位:
-
API 名稱:opensearch-api
-
描述:搜尋 Amazon OpenSearch Service 網域的公有 API
-
端點類型:區域
-
-
選擇建立 API。
-
選擇 Actions (動作) 和 Create Method (建立方法)。
-
在下拉式選單中選擇 GET,然後按一下核取記號以確認。
-
進行下列設定,然後選擇 Save (儲存):
設定 | Value |
---|---|
整合類型 | Lambda 函數 |
使用 Lambda 代理整合 | 是 |
Lambda 區域 | us-west-1 |
Lambda 函數 | opensearch-lambda |
使用預設逾時 | 是 |
設定方法請求
選擇 Method Request (方法請求),然後進行下列設定:
設定 | Value |
---|---|
授權 | NONE |
請求驗證程式 |
驗證查詢字串參數與標頭 |
需要 API 金鑰 | false |
在 URL 查詢字串參數下,選擇新增查詢字串並設定下列參數:
設定 | Value |
---|---|
名稱 | q |
必要 |
是 |
部署 API 並設定階段
API Gateway 主控台可讓您透過建立部署並將它與全新或現有階段建立關聯來部署 API。
-
選擇 Actions (動作) 和 Deploy API (部署 API)。
-
對於 Deployment stage (部署階段),選擇 New Stage (新增階段) 並將階段命名為
opensearch-api-test
。 -
選擇部署。
-
在階段編輯器中進行下列設定,然後選擇 Save Changes (儲存變更):
設定 | Value |
---|---|
啟用調節 | 是 |
速率 |
1000 |
爆量 | 500 |
這些設定會設定僅有一個方法的 API:GET
對端點根進行要求 (https://
)。要求需要單一參數 (some-id
.execute-api.us-west-1
.amazonaws.com/search-es-api-testq
),要搜尋的查詢字串。呼叫時,方法會將請求傳遞至 Lambda,它會執行 opensearch-lambda
函數。如需詳細資訊,請參閱在 Amazon API Gateway 中建立 API 和在 Amazon API Gateway 中部署 REST API。
步驟 4:(選用) 修改網域存取政策
OpenSearch Service 網域必須允許 Lambda 函數對 movies
索引進行 GET
請求。如果您的網域具有啟用了精細存取控制的開放存取政策,可以保持原樣:
或者,您可以選擇使網域存取政策更精細。例如,下列最低政策提供對 movies
索引的 opensearch-lambda-role
(透過 Lambda 建立) 讀取存取權:若要取得 Lambda 自動建立之角色的確切名稱,請前往 AWS Identity and Access Management (IAM) 主控台,選擇角色,然後搜尋「lambda」。
重要
如果您為網域啟用了精細存取控制,則還需要在 OpenSearch Dashboards 中將角色映射至使用者,否則您將看到許可錯誤。
設定 Lambda 執行角色許可
除了設定網域存取政策之外,您還必須確保 Lambda 執行角色具有存取 OpenSearch Service 網域所需的 IAM 許可。Lambda 函數需要特定許可,取決於您使用的是受管網域或 OpenSearch Service Serverless 集合。
對於受管 OpenSearch Service 網域:
將下列 IAM 政策連接至 Lambda 執行角色,以允許其向 OpenSearch Service 網域提出請求:
對於 OpenSearch Service Serverless 集合:
如果您使用的是 OpenSearch Service Serverless,請將下列 IAM 政策連接至 Lambda 執行角色:
若要將這些政策連接至 Lambda 執行角色:
-
導覽至 IAM 主控台,網址為 https://console.aws.amazon.com/iam/
。 -
選擇角色並搜尋您的 Lambda 執行角色 (通常名為
opensearch-lambda-role-
)。xxxxxxxx
-
選擇新增許可,然後選擇建立內嵌政策。
-
選擇 JSON 索引標籤,然後從上方貼上適當的政策,將預留位置值取代為您的實際資源 ARNs。
-
選擇檢閱政策,提供類似 的名稱
OpenSearchAccess
,然後選擇建立政策。
注意
如果沒有這些 IAM 許可,即使網域存取政策允許請求,您的 Lambda 函數仍會在嘗試查詢 OpenSearch Service 網域時收到「存取遭拒」錯誤。
如需存取政策的詳細資訊,請參閱設定存取政策。
映射 Lambda 角色 (如果使用精細存取控制)
精細存取控制會在您可以測試應用程式之前引進額外的步驟。即使您將 HTTP 基本身分驗證用於所有其他目的,您也需要將 Lambda 角色映射至使用者,否則您會看到許可錯誤。
-
導覽至網域的 OpenSearch Dashboards URL。
-
從主功能表中,選擇安全性、角色,然後選取 的連結
all_access
,這是您需要映射 Lambda 角色的角色。 -
選擇 Mapped users (已映射的使用者)、Manage mapping (管理映射)。
-
在 Backend roles (後端角色) 下方,新增 Lambda 角色的 Amazon Resource Name (ARN)。ARN 應該採用 的形式
arn:aws:iam::
。123456789123
:role/service-role/opensearch-lambda-role-1abcdefg
-
選擇 Map (映射),並確認使用者或角色顯示在 Mapped users (已映射的使用者) 中。
步驟 5:測試 Web 應用程式
若要測試 web 應用程式
-
下載 sample-site.zip,將其解壓縮並使用您最愛的文字編輯器將
scripts/search.js
開啟。 -
更新
apigatewayendpoint
變數以指向您的 API Gateway 端點,並將反斜線新增至指定路徑的結尾。您可以透過選擇 Stages (階段),然後選取 API 的名稱,在 API Gateway 中快速找到端點。apigatewayendpoint
變數應該採用https://
/ 的形式。some-id
.execute-api.us-west-1
.amazonaws.com/opensearch-api-test -
開啟
index.html
並嘗試對 thor、house 和一些其他術語執行搜尋。
對 CORS 錯誤進行疑難排解
即使 Lambda 函數在回應中包含支援 CORS 的內容,仍可能會看到以下錯誤:
Access to XMLHttpRequest at '<api-gateway-endpoint>' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present in the requested resource.
如果發生此情況,請嘗試下列操作:
-
在 GET 資源上啟用 CORS。在 Advanced (進階) 下,將 Access-Control-Allow-Credentials 設定為
'true'
。 -
在 API Gateway 中重新部署 API (Actions (動作)、Deploy API (部署 API))。
-
刪除並重新新增您的 Lambda 函數觸發程序。新增重新新增,選擇新增觸發並建立叫用函數的 HTTP 端點。觸發必須具有以下組態:
觸發條件 API 部署階段 安全 API Gateway opensearch-api opensearch-api-test 開啟
後續步驟
本章只是展縣概念的起點。您可以考慮以下修改:
-
將自己的資料新增到 OpenSearch Service 網域。
-
將方法新增至 API
-
在 Lambda 函數中,修改搜尋查詢或提升不同的欄位。
-
樣式結果不同或修改
search.js
來向使用者顯示不同的欄位。