OpenSearch Local Access
Access the OpenSearch cluster from your local machine using SSM port forwarding through a bastion host.
Why This Exists
OpenSearch runs in a private VPC subnet with no public access. To connect locally for development:
- Launch on-demand bastion via Slack bot
- Port forward through bastion using SSM Session Manager
- Access OpenSearch at
https://localhost:9200
Cost: ~$0.001 per 3-hour session (bastion auto-terminates)
Prerequisites
- AWS CLI installed and configured
- Session Manager plugin installed (AWS docs)
- AWS profile configured:
docustack-dev-admin - Access to DocuStack Slack workspace
Quick Start
1. Create Bastion Host
In Slack, run:
/infra bastion create
Wait ~2 minutes for confirmation. The bastion will auto-terminate after 3 hours.
2. Start Port Forwarding
Save this script as opensearch-tunnel.sh:
#!/bin/bash
# opensearch-tunnel.sh - Port forward to OpenSearch via bastion
export AWS_PROFILE=docustack-dev-admin
export AWS_REGION=us-east-1
echo "🔍 Finding bastion instance..."
# Get bastion instance ID
BASTION_INSTANCE_ID=$(aws ec2 describe-instances \
--filters "Name=tag:Name,Values=*bastion*" "Name=instance-state-name,Values=running" \
--query 'Reservations[0].Instances[0].InstanceId' \
--output text \
--region $AWS_REGION)
if [ -z "$BASTION_INSTANCE_ID" ] || [ "$BASTION_INSTANCE_ID" = "None" ]; then
echo "❌ Bastion not found or not running"
echo " Run: /infra bastion create"
exit 1
fi
echo "✅ Bastion Instance: $BASTION_INSTANCE_ID"
echo "🔐 Starting port forwarding..."
echo ""
echo "📍 OpenSearch Cluster: https://localhost:9200"
echo "📊 OpenSearch Dashboards: https://localhost:9200/_dashboards"
echo ""
echo "🔑 Get credentials:"
echo " aws ssm get-parameter --name /docustack/dev/opensearch/master-password --with-decryption --region us-east-1 --query 'Parameter.Value' --output text"
echo ""
echo "⏰ Bastion auto-terminates in 3 hours"
echo "Press Ctrl+C to stop port forwarding"
echo ""
aws ssm start-session \
--target $BASTION_INSTANCE_ID \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"host":["vpc-docustack-dev-search-l72zsvwumer5mdquvl3uqwckam.us-east-1.es.amazonaws.com"],"portNumber":["443"],"localPortNumber":["9200"]}' \
--region $AWS_REGION
Make it executable and run:
chmod +x opensearch-tunnel.sh
./opensearch-tunnel.sh
3. Get Credentials
In another terminal:
export AWS_PROFILE=docustack-dev-admin
export AWS_REGION=us-east-1
PASSWORD=$(aws ssm get-parameter \
--name /docustack/dev/opensearch/master-password \
--with-decryption \
--query 'Parameter.Value' \
--output text \
--region $AWS_REGION)
echo "Username: admin"
echo "Password: $PASSWORD"
4. Test Connection
# Check cluster health
curl -k -u admin:$PASSWORD https://localhost:9200/_cluster/health | jq
# Expected output:
# {
# "cluster_name": "vpc-docustack-dev-search",
# "status": "green",
# "number_of_nodes": 1,
# ...
# }
5. Access OpenSearch Dashboards
Open in browser:
https://localhost:9200/_dashboards
Accept the security warning (SSL certificate is for VPC endpoint, not localhost)
Login with:
- Username:
admin - Password: (from step 3)
Common Tasks
Search Documents
# List all indices
curl -k -u admin:$PASSWORD https://localhost:9200/_cat/indices?v
# Search an index
curl -k -u admin:$PASSWORD https://localhost:9200/my-index/_search | jq
Create Index
curl -k -u admin:$PASSWORD -X PUT https://localhost:9200/my-index \
-H 'Content-Type: application/json' \
-d '{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}'
Index a Document
curl -k -u admin:$PASSWORD -X POST https://localhost:9200/my-index/_doc \
-H 'Content-Type: application/json' \
-d '{
"title": "Test Document",
"content": "This is a test"
}'
Troubleshooting
Error: "Bastion not found or not running"
Cause: Bastion hasn't been created or has already terminated.
Solution:
# Create bastion via Slack
/infra bastion create
# Wait ~2 minutes, then retry
Error: "Parameter not found"
Cause: Missing --region us-east-1 flag.
Solution: Always specify region:
aws ssm get-parameter \
--name /docustack/dev/opensearch/master-password \
--with-decryption \
--region us-east-1 \
--query 'Parameter.Value' \
--output text
Error: "Connection refused" or "Port forwarding failed"
Cause: Bastion instance not ready or wrong endpoint.
Solution:
- Verify bastion is running:
aws ec2 describe-instances \
--filters "Name=tag:Name,Values=*bastion*" "Name=instance-state-name,Values=running" \
--region us-east-1 - Wait 30 seconds after bastion creation for SSM agent to start
- Verify OpenSearch endpoint in script matches current deployment
Browser Security Warning
Cause: SSL certificate is for vpc-docustack-dev-search-*.es.amazonaws.com, not localhost.
Solution: This is expected. Click "Advanced" → "Proceed to localhost" (safe for local development).
Error: "Unauthorized" or 403
Cause: Incorrect credentials or expired password.
Solution:
- Verify password from SSM:
aws ssm get-parameter \
--name /docustack/dev/opensearch/master-password \
--with-decryption \
--region us-east-1 - Check username is
admin(notAdministratoror other)
Bastion Auto-Terminated
Cause: Bastion instances auto-terminate after 3 hours.
Solution:
- Extend lifetime: In Slack, run
/infra bastion extend(adds 2 hours) - Create new bastion: Run
/infra bastion createagain
Security Notes
- No SSH keys: Uses SSM Session Manager with IAM authentication
- No public access: OpenSearch is in private subnet only
- Encrypted: All traffic encrypted (TLS 1.2+)
- Audit trail: All SSM sessions logged to CloudWatch
- Auto-termination: Bastion terminates after 3 hours to prevent forgotten instances
Environment Variables
For convenience, add to your shell profile:
# ~/.zshrc or ~/.bashrc
export AWS_PROFILE=docustack-dev-admin
export AWS_REGION=us-east-1
Related Documentation
- Bastion Orchestrator - How bastion creation works
- OpenSearch Serverless Module - Infrastructure details
- AWS Session Manager - Official AWS docs
Cost
| Resource | Cost |
|---|---|
| OpenSearch domain (t3.small.search) | $31/month |
| Bastion instance (t4g.nano, 3 hours) | ~$0.001/session |
| SSM Session Manager | Free |
Total: ~$31/month + negligible bastion costs