This guide walks through setting up the AWS infrastructure for Vrin Enterprise. After completion, Vrin’s backend will route all operations for your vrin_ent_ API key to your AWS resources.
Prerequisites
AWS account with admin access
AWS CLI v2 configured
A Vrin enterprise account (contact us )
Architecture overview
Your AWS Account Vrin's AWS Account
+-----------------------------------+ +---------------------------+
| Neptune (knowledge graph) |<----| API Gateway + Lambda |
| OpenSearch (vector store) | | (assumes IAM role) |
| S3 (document storage) | | DynamoDB (org config) |
| IAM Role (VRINDataAccessRole) | | STS (cross-account) |
+-----------------------------------+ +---------------------------+
Step 1: Create the IAM role
Vrin assumes a role in your account to access your resources. The role trusts Vrin’s AWS account (859271276727).
# Create trust policy
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::859271276727:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "YOUR_EXTERNAL_ID"
}
}
}
]
}
EOF
aws iam create-role \
--role-name VRINDataAccessRole \
--assume-role-policy-document file://trust-policy.json
Replace YOUR_EXTERNAL_ID with the external ID from your Vrin enterprise portal.
Step 2: Create Neptune cluster
# Create Neptune subnet group (use your private subnets)
aws neptune create-db-subnet-group \
--db-subnet-group-name vrin-neptune-subnets \
--db-subnet-group-description "Vrin Neptune subnets" \
--subnet-ids subnet-xxx subnet-yyy
# Create Neptune cluster
aws neptune create-db-cluster \
--db-cluster-identifier vrin-knowledge-graph \
--engine neptune \
--enable-iam-database-authentication \
--vpc-security-group-ids sg-xxx \
--db-subnet-group-name vrin-neptune-subnets
# Create Neptune instance
aws neptune create-db-instance \
--db-instance-identifier vrin-neptune-1 \
--db-instance-class db.t3.medium \
--engine neptune \
--db-cluster-identifier vrin-knowledge-graph
# Wait for instance to be available
aws neptune wait db-instance-available \
--db-instance-identifier vrin-neptune-1
Use db.t3.medium for development. For production, use db.r5.large or higher.
Step 3: Create OpenSearch domain
aws opensearch create-domain \
--domain-name vrin-vectors \
--engine-version OpenSearch_2.11 \
--cluster-config InstanceType=t3.medium.search,InstanceCount= 1 \
--ebs-options EBSEnabled= true ,VolumeType=gp3,VolumeSize= 20 \
--node-to-node-encryption-options Enabled= true \
--encrypt-at-rest-options Enabled= true \
--domain-endpoint-options EnforceHTTPS= true \
--access-policies '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::YOUR_ACCOUNT_ID:role/VRINDataAccessRole"},
"Action": "es:*",
"Resource": "arn:aws:es:us-east-1:YOUR_ACCOUNT_ID:domain/vrin-vectors/*"
}]
}'
The IAM role must exist before creating the OpenSearch domain — AWS validates principal ARNs at creation time.
Step 4: Create S3 bucket
aws s3api create-bucket \
--bucket your-org-vrin-documents \
--region us-east-1
# Enable versioning
aws s3api put-bucket-versioning \
--bucket your-org-vrin-documents \
--versioning-configuration Status=Enabled
# Enable encryption
aws s3api put-bucket-encryption \
--bucket your-org-vrin-documents \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms"
}
}]
}'
Step 5: Attach permissions to the IAM role
cat > vrin-role-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "NeptuneAccess",
"Effect": "Allow",
"Action": ["neptune-db:*"],
"Resource": "arn:aws:neptune-db:us-east-1:YOUR_ACCOUNT_ID:*/vrin-knowledge-graph/*"
},
{
"Sid": "OpenSearchAccess",
"Effect": "Allow",
"Action": ["es:ESHttp*"],
"Resource": "arn:aws:es:us-east-1:YOUR_ACCOUNT_ID:domain/vrin-vectors/*"
},
{
"Sid": "S3Access",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::your-org-vrin-documents",
"arn:aws:s3:::your-org-vrin-documents/*"
]
}
]
}
EOF
aws iam put-role-policy \
--role-name VRINDataAccessRole \
--policy-name VRINResourceAccess \
--policy-document file://vrin-role-policy.json
Save your infrastructure configuration through the SDK or web portal:
from vrin import VRINEnterpriseClient
client = VRINEnterpriseClient( api_key = "vrin_ent_your_key" )
client.save_configuration({
"database" : {
"provider" : "neptune" ,
"endpoint" : "vrin-knowledge-graph.cluster-xxx.us-east-1.neptune.amazonaws.com" ,
"port" : 8182
},
"vector_store" : {
"provider" : "opensearch" ,
"endpoint" : "https://search-vrin-vectors-xxx.us-east-1.es.amazonaws.com"
},
"storage" : {
"provider" : "s3" ,
"bucket" : "your-org-vrin-documents" ,
"region" : "us-east-1"
},
"iam" : {
"role_arn" : "arn:aws:iam::YOUR_ACCOUNT_ID:role/VRINDataAccessRole" ,
"external_id" : "YOUR_EXTERNAL_ID"
}
})
Step 7: Validate connectivity
result = client.validate_connectivity()
for service, status in result.items():
print ( f " { service } : { status[ 'status' ] } " )
All services should report connected. If any fail:
Neptune : Check security group allows inbound on port 8182 from Vrin’s VPC peering
OpenSearch : Check domain access policy includes the VRINDataAccessRole ARN
S3 : Check bucket policy and IAM role permissions
Step 8: Test end-to-end
# Insert a document
client.insert(
"Test document for connectivity validation." ,
title = "Connectivity Test"
)
# Query it back
result = client.query( "What was in the test document?" )
print (result[ "summary" ])
Security checklist
Networking
Vrin connects to your infrastructure via VPC peering . During onboarding, Vrin will provide:
Vrin VPC ID and CIDR block
Peering request from Vrin’s AWS account
You need to:
Accept the peering connection
Add route table entries for Vrin’s CIDR
Update security groups to allow inbound from Vrin’s CIDR
Enable DNS resolution on both sides of the peering connection
DNS resolution must be enabled on both sides of the peering connection (AllowDnsResolutionFromRemoteVpc). Without this, Neptune and OpenSearch endpoint resolution fails.