本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
設定 OpenSearch UI 應用程式的易記 URL (自助式)
OpenSearch UI 應用程式具有自動產生的 URLs例如 https://application-。這些 URLs很長且難以記住。您可以設定易記的 URL (例如 name-id.Region.opensearch.amazonaws.comhttps://prod.example.com)。此 URL 會重新導向至您的應用程式,因此您可以直接存取儀表板,而無需透過 AWS 管理主控台導覽。
運作方式
此解決方案使用 CloudFront 將請求從易記 URL 重新導向至 OpenSearch UI 應用程式端點。架構包含下列元件:
-
ACM 憑證 – 為您的易記 URL 提供 HTTPS 加密。
-
CloudFront KeyValueStore – 存放子網域名稱和應用程式 URLs之間的映射。
-
CloudFront 函數 – 讀取 KeyValueStore,並將 302 重新導向傳回正確的應用程式 URL。
-
CloudFront 分佈 – 使用 TLS 為您的易記 URL 提供服務,並透過 函數路由請求。
-
Route 53 DNS 記錄 – 將您的易記 URL 指向 CloudFront 分佈。
當您造訪易記的 URL (例如 https://prod.example.com) 時,CloudFront 函數會查詢對應的應用程式 URL,並將您的瀏覽器重新導向至該 URL。應用程式會直接處理身分驗證。
先決條件
-
一或多個 OpenSearch UI 應用程式及其端點 URLs。
-
您擁有的網域名稱 (例如
example.com)。 -
Route 53 中網域的公有託管區域。如果您沒有 ,如需詳細資訊,請參閱 不使用 Route 53 進行設定 (手動組態)。
-
存放應用程式 URL 映射檔案的 Amazon S3 儲存貯體。
使用 部署 AWS CloudFormation
使用下列程序,使用 CloudFormation 範本部署易記的 URL 重新導向基礎設施。
為您的 OpenSearch UI 應用程式設定易記的 URL
-
建立將您的易記名稱映射至應用程式 URLs JSON 檔案。每個金鑰都會變成子網域 (例如,金鑰
prod會變成https://prod.example.com)。{ "data": [ {"key": "prod", "value": "https://application-prod-abc123.us-west-2.opensearch.amazonaws.com"}, {"key": "staging", "value": "https://application-staging-def456.us-east-1.opensearch.amazonaws.com"}, {"key": "analytics", "value": "https://application-analytics-ghi789.eu-west-1.opensearch.amazonaws.com"} ] }將此檔案儲存為
opensearch-ui-friendly-url-app-mappings-v1.json。v1尾碼會將此識別為映射的第一個版本。當您更新映射時,會遞增此版本。 -
將映射檔案上傳至您帳戶中的 Amazon S3 儲存貯體:
aws s3 cp opensearch-ui-friendly-url-app-mappings-v1.json \ s3://your-bucket-name/opensearch-ui-friendly-url-app-mappings-v1.json -
新增儲存貯體政策,授予 CloudFront 讀取映射檔案的許可。將
your-bucket-name和your-account-id取代為您的值:aws s3api put-bucket-policy \ --bucketyour-bucket-name\ --policy '{ "Version": "2012-10-17", "Statement": [{ "Sid": "AllowCloudFrontKVSImport", "Effect": "Allow", "Principal": {"Service": "cloudfront.amazonaws.com"}, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::your-bucket-name/*", "Condition": {"StringEquals": {"aws:SourceAccount": "your-account-id"}} }] }'注意
此儲存貯體政策允許 CloudFront 在建立 KeyValueStore 期間讀取映射檔案。如果沒有它,堆疊部署會失敗,並出現「SourceARN 無法存取」錯誤。
-
使用下列其中一個選項部署 CloudFormation 堆疊:
選項 1:啟動堆疊 (建議)
複製下列 URL 並貼到您的瀏覽器,以開啟預先載入範本的 AWS CloudFormation 快速建立頁面。填寫參數,然後選擇建立堆疊。
https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/quickcreate?templateURL=https://opensearch-ui-quickstart-sample-cfn-templates.s3.us-west-2.amazonaws.com/opensearch-ui-friendly-url/main.yaml&stackName=opensearch-ui-friendly-url¶m_MappingsVersion=v1選項 2: AWS CLI
將預留位置值取代為您自己的值:
aws cloudformation create-stack \ --stack-name opensearch-ui-friendly-url \ --template-url https://opensearch-ui-quickstart-sample-cfn-templates.s3.us-west-2.amazonaws.com/opensearch-ui-friendly-url/main.yaml \ --parameters \ ParameterKey=DomainName,ParameterValue=your-domain.com\ ParameterKey=HostedZoneId,ParameterValue=Z0123456789ABCDEFG\ ParameterKey=MappingsBucket,ParameterValue=your-bucket-name\ ParameterKey=MappingsKey,ParameterValue=opensearch-ui-friendly-url-app-mappings-v1.json \ ParameterKey=MappingsVersion,ParameterValue=v1 \ --region us-east-1 -
如果您使用 AWS CLI (選項 2),請在
us-east-1區域中部署堆疊。CloudFront 要求 ACM 憑證在 中us-east-1。您的 OpenSearch UI 應用程式可以位於 OpenSearch UI 的任何支援區域和配額中。 -
等待堆疊完成 (約 15 分鐘)。您可以監控進度:
aws cloudformation wait stack-create-complete \ --stack-name opensearch-ui-friendly-url \ --region us-east-1 -
測試重新導向。開啟您的瀏覽器並導覽至
https://。您應該重新導向至 OpenSearch UI 應用程式。prod.your-domain.com您也可以使用 驗證
curl:curl -I https://prod.your-domain.com# Expected: HTTP/2 302 # location: https://application-prod-abc123.us-west-2.opensearch.amazonaws.com
以下是上述啟動堆疊連結和 CLI 命令所使用的完整 CloudFormation 範本。您也可以直接從 下載https://opensearch-ui-quickstart-sample-cfn-templates.s3.us-west-2.amazonaws.com/opensearch-ui-friendly-url/main.yaml。
AWSTemplateFormatVersion: '2010-09-09' Metadata: TemplateVersion: '1.0.0' LastUpdated: '2026-08-05' Author: 'OpenSearch UI Team' Description: > OpenSearch UI Friendly URL - Creates a CloudFront distribution with a CloudFront Function that redirects friendly subdomain URLs to OpenSearch Application endpoints. Deploy this template in us-east-1 (required for ACM certificates used with CloudFront). Parameters: DomainName: Type: String Description: "Your domain name (e.g., example.com or subdomain.example.com)" AllowedPattern: "^[a-zA-Z0-9][a-zA-Z0-9-]*(\\.[a-zA-Z0-9][a-zA-Z0-9-]*)+$" HostedZoneId: Type: AWS::Route53::HostedZone::Id Description: "Route 53 Hosted Zone ID for your domain" MappingsBucket: Type: String Description: "S3 bucket name containing your app mappings JSON file" MappingsKey: Type: String Description: "S3 key (path) to your app mappings JSON file" Default: "opensearch-ui-friendly-url-app-mappings.json" MappingsVersion: Type: String Description: "Version identifier for your mappings (change this when updating mappings, e.g., v1, v2, v3)" Default: "v1" AllowedPattern: "^[a-zA-Z0-9-]+$" Resources: # 1. Wildcard TLS Certificate (DNS validated via Route 53) Certificate: Type: AWS::CertificateManager::Certificate Properties: DomainName: !Sub "*.${DomainName}" ValidationMethod: DNS DomainValidationOptions: - DomainName: !Sub "*.${DomainName}" HostedZoneId: !Ref HostedZoneId # 2. CloudFront KeyValueStore with S3 import for app mappings AppMappingStore: Type: AWS::CloudFront::KeyValueStore Properties: Name: !Sub "${AWS::StackName}-kvs-${MappingsVersion}" Comment: !Sub "OpenSearch UI app mappings ${MappingsVersion} for ${DomainName}" ImportSource: SourceType: S3 SourceArn: !Sub "arn:aws:s3:::${MappingsBucket}/${MappingsKey}" # 3. CloudFront Function (reads KVS, returns 302 redirect) RedirectFunction: Type: AWS::CloudFront::Function Properties: Name: !Sub "${AWS::StackName}-fn" AutoPublish: true FunctionConfig: Comment: !Sub "Redirects friendly URLs to OpenSearch Application endpoints (${MappingsVersion})" Runtime: cloudfront-js-2.0 KeyValueStoreAssociations: - KeyValueStoreARN: !GetAtt AppMappingStore.Arn FunctionCode: !Sub | import cf from 'cloudfront'; const kvsHandle = cf.kvs("${AppMappingStore.Id}"); async function handler(event) { var request = event.request; var host = request.headers.host.value; // Extract subdomain prefix (e.g., "app1" from "app1.example.com") var subdomain = host.split('.')[0]; try { var targetUrl = await kvsHandle.get(subdomain); return { statusCode: 302, statusDescription: 'Found', headers: { 'location': { value: targetUrl }, 'cache-control': { value: 'no-cache, no-store, must-revalidate' } } }; } catch (e) { // Key not found - return 404 return { statusCode: 404, statusDescription: 'Not Found', headers: { 'content-type': { value: 'text/html' } }, body: { encoding: 'text', data: '<html><body><h1>Application Not Found</h1><p>No OpenSearch application is mapped to the requested subdomain.</p></body></html>' } }; } } # 4. CloudFront Distribution Distribution: Type: AWS::CloudFront::Distribution DependsOn: Certificate Properties: DistributionConfig: Enabled: true Comment: !Sub "OpenSearch UI Friendly URL for ${DomainName}" Aliases: - !Sub "*.${DomainName}" ViewerCertificate: AcmCertificateArn: !Ref Certificate SslSupportMethod: sni-only MinimumProtocolVersion: TLSv1.2_2021 DefaultCacheBehavior: ViewerProtocolPolicy: redirect-to-https AllowedMethods: - GET - HEAD CachedMethods: - GET - HEAD CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" # AWS managed CachingDisabled policy TargetOriginId: dummy-origin FunctionAssociations: - EventType: viewer-request FunctionARN: !GetAtt RedirectFunction.FunctionMetadata.FunctionARN Origins: - Id: dummy-origin DomainName: "example.com" CustomOriginConfig: OriginProtocolPolicy: https-only HttpVersion: http2and3 IPV6Enabled: true PriceClass: PriceClass_All # 5. Wildcard DNS record pointing to CloudFront WildcardDnsRecord: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Ref HostedZoneId Name: !Sub "*.${DomainName}" Type: A AliasTarget: HostedZoneId: Z2FDTNDATAQYW2 # CloudFront's fixed hosted zone ID (constant for all distributions) DNSName: !GetAtt Distribution.DomainName EvaluateTargetHealth: false Outputs: CloudFrontDomain: Description: "CloudFront distribution domain name" Value: !GetAtt Distribution.DomainName CertificateArn: Description: "ACM Certificate ARN" Value: !Ref Certificate KeyValueStoreArn: Description: "CloudFront KeyValueStore ARN" Value: !GetAtt AppMappingStore.Arn ExampleUrl: Description: "Example friendly URL" Value: !Sub "https://prod.${DomainName}" MappingsFileLocation: Description: "S3 location of your app mappings file" Value: !Sub "s3://${MappingsBucket}/${MappingsKey}" CurrentMappingsVersion: Description: "Current mappings version deployed" Value: !Ref MappingsVersion TemplateVersion: Description: "Template version and last updated date" Value: "1.0.0 (2026-08-05)"
新增或移除應用程式
若要新增、更新或移除應用程式映射,請建立新的 S3 映射檔案版本,並使用新版本更新堆疊。版本控制方法會將 S3 檔案保留為事實來源,並可讓您隨時轉傳至新的組態或轉返至先前的版本。
-
編輯映射檔案以新增或移除項目。使用遞增的版本尾碼 (例如 ) 儲存它
opensearch-ui-friendly-url-app-mappings-v2.json。 -
將新版本上傳至 S3:
aws s3 cp opensearch-ui-friendly-url-app-mappings-v2.json \ s3://your-bucket-name/opensearch-ui-friendly-url-app-mappings-v2.json -
使用新的
MappingsKey和 更新堆疊MappingsVersion:使用主控台:開啟CloudFormation 主控台
,選取堆疊,選擇更新,選取使用目前範本,然後使用新值更新 MappingsKey和MappingsVersion參數。使用 AWS CLI:
aws cloudformation update-stack \ --stack-name opensearch-ui-friendly-url \ --use-previous-template \ --parameters \ ParameterKey=DomainName,UsePreviousValue=true \ ParameterKey=HostedZoneId,UsePreviousValue=true \ ParameterKey=MappingsBucket,UsePreviousValue=true \ ParameterKey=MappingsKey,ParameterValue=opensearch-ui-friendly-url-app-mappings-v2.json \ ParameterKey=MappingsVersion,ParameterValue=v2 \ --region us-east-1
重要
每次更新映射時,您必須變更 MappingsVersion 參數。版本會驅動 KeyValueStore 名稱,這會觸發 CloudFormation 以更新的資料取代 KeyValueStore。為了清楚起見,請保持MappingsKey檔案名稱 和 MappingsVersion 同步 (例如,...-v2.json使用 MappingsVersion=v2)。
若要復原至先前的版本,請更新指向先前檔案和版本的堆疊。
使用主控台:開啟CloudFormation 主控台MappingsKey 並MappingsVersion返回先前的值 (例如 v1)。
使用 AWS CLI:
aws cloudformation update-stack \ --stack-name opensearch-ui-friendly-url \ --use-previous-template \ --parameters \ ParameterKey=DomainName,UsePreviousValue=true \ ParameterKey=HostedZoneId,UsePreviousValue=true \ ParameterKey=MappingsBucket,UsePreviousValue=true \ ParameterKey=MappingsKey,ParameterValue=opensearch-ui-friendly-url-app-mappings-v1.json \ ParameterKey=MappingsVersion,ParameterValue=v1 \ --region us-east-1
此版本控制方法可讓您完全控制視需要轉返或轉返應用程式映射,同時將您的 S3 檔案保留為每個組態版本的最終記錄。
不使用 Route 53 進行設定 (手動組態)
如果您的網域是由 Route 53 以外的 DNS 供應商管理,您可以在 AWS 管理主控台中手動設定易記的 URL 重新導向。此方法不會使用 Amazon S3 進行映射,您可以直接在 CloudFront 主控台中管理鍵/值對。
設定不含 Route 53 的易記 URL 重新導向
-
在 ACM 中請求憑證
-
在
us-east-1區域中開啟位於 https://https://console.aws.amazon.com/acm/的 ACM 主控台。 -
選擇請求憑證。
-
針對網域名稱,輸入
*.(萬用字元憑證)。your-domain.com -
針對驗證方法,選擇 DNS 驗證。
-
選擇請求。
-
在憑證詳細資訊頁面上,記下網域驗證下的 CNAME 記錄名稱和值。在您的 DNS 供應商建立此 CNAME 記錄,以驗證網域擁有權。
-
等待憑證狀態變更為已發行 (通常在 DNS 記錄建立後 5 到 30 分鐘)。
-
-
建立 CloudFront KeyValueStore
-
在 https://console.aws.amazon.com/cloudfront/
開啟 CloudFront 主控台。 -
在導覽視窗中,選擇函數。然後選擇 KeyValueStores 標籤。
-
選擇建立 KeyValueStore。
-
輸入名稱 (例如
opensearch-ui-friendly-url-app-mappings-store)。 -
選擇建立。
-
建立後,選擇編輯以新增鍵/值對。對於每個應用程式,新增金鑰 (子網域名稱,例如
prod) 和值 (完整的 OpenSearch UI 應用程式 URL)。
-
-
建立 CloudFront 函數
-
在 https://console.aws.amazon.com/cloudfront/
開啟 CloudFront 主控台。 -
在導覽視窗中,選擇函數。
-
在函數索引標籤上,選擇建立函數。
-
輸入函數的名稱 (例如
opensearch-ui-friendly-url-redirect-function)。 -
針對執行期,選擇 cloudfront-js-2.0。
-
將函數程式碼取代為下列項目:
import cf from 'cloudfront'; const kvsHandle = cf.kvs("YOUR_KVS_ID"); async function handler(event) { var request = event.request; var host = request.headers.host.value; var subdomain = host.split('.')[0]; try { var targetUrl = await kvsHandle.get(subdomain); return { statusCode: 302, statusDescription: 'Found', headers: { 'location': { value: targetUrl }, 'cache-control': { value: 'no-cache, no-store, must-revalidate' } } }; } catch (e) { return { statusCode: 404, statusDescription: 'Not Found', headers: { 'content-type': { value: 'text/html' } }, body: { encoding: 'text', data: '<html><body><h1>Application Not Found</h1><p>No OpenSearch application is mapped to the requested subdomain.</p></body></html>' } }; } }將
YOUR_KVS_ID取代為您建立的 KeyValueStore 的 ID (可在 KeyValueStore 詳細資訊頁面上看到)。 -
在 KeyValueStore 關聯中,關聯您建立的 KeyValueStore。
-
選擇儲存變更,然後選擇發佈函數。
-
-
建立 CloudFront 分佈
-
在 CloudFront 主控台中,選擇建立分佈。
-
針對原始網域,輸入任何有效的網域 (例如
example.com)。永遠不會聯絡原始伺服器,因為函數會在到達回應之前傳回回應。 -
在預設快取行為下,針對檢視器通訊協定政策,選擇將 HTTP 重新導向至 HTTPS。
-
針對快取政策,選擇 CachingDisabled。
-
在函數關聯下,針對檢視器請求,選取您的 CloudFront 函數。
-
在設定下,針對備用網域名稱 CNAMEs),輸入
*.。your-domain.com -
針對自訂 SSL 憑證,選取您在 ACM 中建立的憑證。
-
選擇 Create Distribution (建立分佈)。
-
請記下分佈網域名稱 (例如
d1234abcdef8.cloudfront.net)。
-
-
在您的供應商設定 DNS
在您的 DNS 供應商,建立
*.指向 CloudFront 分佈網域名稱的 CNAME 記錄 (例如your-domain.comd1234abcdef8.cloudfront.net)。注意
有些 DNS 供應商不支援萬用字元 CNAME 記錄。在這種情況下,請為您要使用的每個子網域建立個別 CNAME 記錄 (例如,
prod.your-domain.com、staging.your-domain.com)。
手動新增應用程式映射
若要在初始手動設定之後新增應用程式映射:
-
在 https://console.aws.amazon.com/cloudfront/
開啟 CloudFront 主控台。 -
在導覽視窗中,選擇函數。然後選擇 KeyValueStores 標籤。
-
選擇您的 KeyValueStore 名稱 (例如
opensearch-ui-friendly-url-app-mappings-store)。 -
選擇編輯。
-
選擇新增配對。輸入子網域名稱作為索引鍵,並輸入完整的 OpenSearch UI 應用程式 URL 作為值。
-
選擇儲存變更。
儲存後,即可立即使用新的易記 URL。
清除
若要移除易記的 URL 重新導向基礎設施,請執行下列命令:
aws cloudformation delete-stack \ --stack-name opensearch-ui-friendly-url \ --region us-east-1
此命令會移除 CloudFront 分佈、函數、KeyValueStore、ACM 憑證和 DNS 記錄。它不會影響您的 OpenSearch UI 應用程式。
疑難排解
- ACM 憑證保留在
Pending validation -
確定您網域的 DNS 已正確委派給 Route 53 (或您在 DNS 供應商建立驗證 CNAME)。使用
dig來驗證名稱伺服器。your-domainNS - 瀏覽器顯示憑證錯誤
-
確認 ACM 憑證以萬用字元 () 的形式涵蓋您的網域
*.your-domain.com。憑證必須位於us-east-1區域。 - 找不到 404 應用程式
-
您嘗試存取的子網域在 KeyValueStore 中沒有映射。驗證映射檔案中存在的金鑰,並確認您在上次變更後已更新堆疊 (或手動新增配對)。
- CloudFront 分佈會顯示超過 15 分鐘
Deploying的狀態 -
CloudFront 分佈最多可能需要 15 分鐘才能全域部署。如果部署需要更長的時間,請檢查 CloudFront 主控台以取得錯誤詳細資訊。
- SourceARN 在堆疊建立期間是無法存取的錯誤
-
確保 S3 儲存貯體政策授予讀取映射檔案的
cloudfront.amazonaws.com許可。同時確認部署堆疊的 IAM 角色在儲存貯體上有s3:GetObject、s3:HeadObject和s3:GetBucketLocation許可。