本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
为 OpenSearch UI 应用程序设置友好 URL(自助服务)
OpenSearch UI 应用程序具有自动生成的 URL,例如https://application-。这些 URL 很长,很难记住。您可以设置友好 URL(例如name-id.Region.opensearch.amazonaws.com.rproxy.goskope.comhttps://prod.example.com)。此 URL 重定向到您的应用程序,因此您无需通过 AWS 管理控制台导航即可直接访问仪表板。
工作原理
此解决方案用于将请求从您的友好 URL 重定 CloudFront 向到您的 OpenSearch UI 应用程序终端节点。该架构包含以下组件:
-
ACM 证书 — 为您的友好 URL 提供 HTTPS 加密。
-
CloudFront KeyValueStore— 存储子域名和应用程序 URL 之间的映射。
-
CloudFront 函数 -读取 KeyValueStore 并返回指向正确应用程序 URL 的 302 重定向。
-
CloudFront 分发 — 使用 TLS 为您的友好网址提供服务,并通过该函数路由请求。
-
Route 53 DNS 记录 — 将你的友好 URL 指向 CloudFront 发行版。
当您访问友好 URL(例如https://prod.example.com)时,该 CloudFront 函数会查找相应的应用程序 URL 并将您的浏览器重定向到该网址。应用程序直接处理身份验证。
先决条件
-
一个或多个 OpenSearch UI 应用程序及其终端节点 URL。
-
您拥有的域名(例如,
example.com)。 -
您的域名在 Route 53 中的公共托管区域。如果您没有,有关更多信息,请参阅在没有 Route 53 的情况下进行设置(手动配置)。
-
一个 Amazon S3 存储桶,用于存储您的应用程序 URL 映射文件。
使用进行部署 AWS CloudFormation
使用以下过程使用 CloudFormation 模板部署友好的 URL 重定向基础架构。
为您的 OpenSearch UI 应用程序设置友好 URL
-
创建一个 JSON 文件,将您的友好名称映射到应用程序 URL。每个密钥都成为一个子域(例如,密钥
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参数。使用 C AWS LI:
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)。
使用 C AWS LI:
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://console.aws.amazon.com/acm/中打开 ACM 控制台。 -
选择 “申请证书” 。
-
对于域名,输入
*.(通配符证书)。your-domain.com -
对于验证方法,选择 DNS 验证。
-
选择请求。
-
在证书详细信息页面上,记下 “域验证” 下的 CNAME 记录名称和值。在您的 DNS 提供商处创建此 CNAME 记录以验证域所有权。
-
等待证书状态更改为已颁发(通常在创建 DNS 记录后 5 到 30 分钟)。
-
-
创建一个 CloudFront KeyValueStore
-
在处打开 CloudFront 控制台https://console.aws.amazon.com/cloudfront/
。 -
在导航窗格中,选择函数。然后选择KeyValueStores选项卡。
-
选择创建 KeyValueStore。
-
输入名称(例如,
opensearch-ui-friendly-url-app-mappings-store)。 -
选择创建。
-
创建后,选择 “编辑” 以添加键值对。为每个应用程序添加一个密钥(子域名,例如
prod)和一个值(完整的 OpenSearch UI 应用程序 URL)。
-
-
创建 CloudFront 函数
-
在处打开 CloudFront 控制台https://console.aws.amazon.com/cloudfront/
。 -
在导航窗格中,选择函数。
-
在函数选项卡上,选择创建函数。
-
输入函数的名称(例如,
opensearch-ui-friendly-url-redirect-function)。 -
对于运行时,选择 c loudfront-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 控制台中,选择 “创建分发” 。
-
对于 Origin 域,输入任何有效的域(例如,
example.com)。由于该函数在到达源之前会返回响应,因此永远不会联系到源。 -
在 “默认缓存行为” 下,对于查看器协议策略,选择 “将 HTTP 重定向到 HTTPS” 。
-
对于缓存策略,选择CachingDisabled。
-
在 “函数关联” 下,对于查看者请求,选择您的 CloudFront函数。
-
在 “设置” 下,在 “备用域名 (CNAME)” 中输入
*.。your-domain.com -
对于自定义 SSL 证书,选择您在 ACM 中创建的证书。
-
选择创建分配。
-
记下分发域名(例如
d1234abcdef8.cloudfront.net)。
-
-
在您的提供商处配置 DNS
在您的 DNS 提供商处,创建指
*.向您的 CloudFront分发域名的 CNAME 记录(例如,your-domain.comd1234abcdef8.cloudfront.net)。注意
某些 DNS 提供商不支持通配符 CNAME 记录。在这种情况下,为要使用的每个子域名创建单独的 CNAME 记录(例如
prod.your-domain.com,staging.your-domain.com)。
手动添加应用程序映射
要在初始手动设置之后添加新的应用程序映射,请执行以下操作:
-
在处打开 CloudFront 控制台https://console.aws.amazon.com/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 分发显示
Deploying状态的时间超过 15 分钟 -
CloudFront 在全球部署分发最多可能需要 15 分钟。如果部署需要更长的时间,请查看 CloudFront 控制台以了解错误的详细信息。
- 创建堆栈时出现 SourceARN 无法访问错误
-
确保 S3 存储桶策略授予读取映射文件的
cloudfront.amazonaws.com权限。还要验证部署堆栈的 IAM 角色在存储桶上拥有s3:GetObjects3:HeadObject、和s3:GetBucketLocation权限。