OpenSearch UI supports connecting to OpenSearch domains and serverless collections that live in different AWS accounts. This is essential for organizations that use multi-account strategies — for example, separate accounts for production, staging, and security.
Cross-Account Access
Overview
Cross-account access lets you associate a domain from Account B with an OpenSearch UI application in Account A. The data stays in Account B, but users in Account A can query and visualize it through the application.
Account A (Application) Account B (Data Source)
┌──────────────────────┐ ┌──────────────────────┐
│ OpenSearch UI App │───────▶│ OpenSearch Domain │
│ (app-abc123) │ │ (remote-logs) │
└──────────────────────┘ └──────────────────────┘Prerequisites
- An OpenSearch UI application in Account A
- An OpenSearch managed domain in Account B
- IAM permissions in both accounts to configure cross-account access
- Both accounts must be in the same AWS partition (e.g., both in
awsor both inaws-cn)
Step-by-step setup
Step 1: Create a cross-cluster connection (Account B)
In the account that owns the domain, create an outbound cross-cluster connection:
# Run in Account B
aws opensearch create-outbound-connection \
--local-domain-info '{
"AWSDomainInformation": {
"DomainName": "remote-logs",
"OwnerId": "999888777666",
"Region": "us-west-2"
}
}' \
--remote-domain-info '{
"AWSDomainInformation": {
"DomainName": "placeholder",
"OwnerId": "123456789012",
"Region": "us-east-1"
}
}' \
--connection-alias "app-account-connection" \
--connection-mode "DIRECT" \
--region us-west-2Note the ConnectionId from the response.
Step 2: Accept the inbound connection (Account A)
In the application account, accept the inbound connection:
# Run in Account A
aws opensearch accept-inbound-connection \
--connection-id conn-abc123def456 \
--region us-east-1Step 3: Update the domain access policy (Account B)
The domain in Account B must allow the OpenSearch UI service from Account A to access it. Update the domain's access policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "application.opensearchservice.amazonaws.com"
},
"Action": "es:ESHttp*",
"Resource": "arn:aws:es:us-west-2:999888777666:domain/remote-logs/*",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "123456789012"
}
}
}
]
}Apply the policy:
# Run in Account B
aws opensearch update-domain-config \
--domain-name remote-logs \
--access-policies file://access-policy.json \
--region us-west-2Step 4: Associate the remote domain (Account A)
Add the remote domain as a data source in your application:
# Run in Account A
aws opensearch update-application \
--id app-abc123def456 \
--region us-east-1 \
--data-sources '[
{
"dataSourceArn": "arn:aws:es:us-west-2:999888777666:domain/remote-logs",
"dataSourceDescription": "Remote account logs (Account B, us-west-2)"
}
]'Step 5: Authorize VPC access (if applicable)
If the remote domain is in a VPC, you also need to authorize VPC endpoint access:
# Run in Account B
aws opensearch authorize-vpc-endpoint-access \
--domain-name remote-logs \
--service application.opensearchservice.amazonaws.com \
--account 123456789012 \
--region us-west-2IAM permissions required
Account A (application account)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"es:UpdateApplication",
"es:GetApplication",
"es:AcceptInboundConnection"
],
"Resource": "*"
}
]
}Account B (data source account)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"es:CreateOutboundConnection",
"es:UpdateDomainConfig",
"es:AuthorizeVpcEndpointAccess"
],
"Resource": "arn:aws:es:us-west-2:999888777666:domain/remote-logs"
}
]
}Cross-account with serverless collections
For serverless collections in another account, the setup is different:
Data access policy (Account B)
Create a data access policy that grants the application's IAM role access:
[
{
"Description": "Allow cross-account OpenSearch UI access",
"Rules": [
{
"ResourceType": "collection",
"Resource": ["collection/my-collection"],
"Permission": [
"aoss:ReadDocument",
"aoss:DescribeIndex"
]
}
],
"Principal": [
"arn:aws:iam::123456789012:role/OpenSearchUIServiceRole"
]
}
]Network policy (Account B)
[
{
"Description": "Allow OpenSearch UI service from Account A",
"Rules": [
{
"ResourceType": "collection",
"Resource": ["collection/my-collection"]
}
],
"SourceServices": [
"application.opensearchservice.amazonaws.com"
],
"AllowFromPublic": false
}
]Cross-region considerations
Cross-account access can also span regions. For example, your application in us-east-1 can connect to a domain in us-west-2 in another account.
For detailed cross-region setup including latency considerations and regional service availability, see the Cross-Region page in the Administration section.
Security best practices
- Use condition keys in domain access policies to restrict access to specific source accounts
- Minimize permissions — grant only
es:ESHttp*actions, not fulles:* - Use AWS Organizations SCPs to control which accounts can create cross-account connections
- Monitor access using CloudTrail logs in both accounts
- Regularly audit cross-account connections and remove unused ones
Verifying the connection
After setup, verify the cross-account data source is working:
- Launch your OpenSearch UI application
- Navigate to a workspace that has the remote data source
- Go to Dashboards Management → Data Sources
- The remote domain should appear with a Green health status
- Create an index pattern against the remote domain's indices
- Use Discover to query data from the remote domain
Troubleshooting
Remote domain not appearing in data source list
- Verify the inbound connection is in Active state
- Check that the
update-applicationcall included the correct ARN - Ensure the domain access policy allows the OpenSearch UI service
"Access denied" when querying remote data
- The domain access policy in Account B may be missing or incorrect
- Verify the
aws:SourceAccountcondition matches Account A's ID - Check that the IAM role used by the application has the necessary permissions
Connection shows as "Pending"
- The inbound connection hasn't been accepted yet — run
accept-inbound-connectionin Account A - If already accepted, the connection may be processing — wait a few minutes
VPC domain in remote account not reachable
- Run
authorize-vpc-endpoint-accessin Account B - Verify the security group allows inbound TCP 443
- Check that the VPC endpoint is in Available state
Latency is high for cross-region queries
- Cross-region queries add network latency proportional to the geographic distance
- Consider caching frequently accessed data or creating read replicas closer to the application
- Use time-bounded queries to reduce data transfer