Skip to content

Commit 185cdc7

Browse files
author
Bob Strahan
committed
fix: update S3 vectors manager to recreate index on updates and improve metadata configuration
1 parent 45dd5e4 commit 185cdc7

File tree

1 file changed

+83
-4
lines changed
  • options/bedrockkb/src/s3_vectors_manager

1 file changed

+83
-4
lines changed

options/bedrockkb/src/s3_vectors_manager/handler.py

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ def handle_s3_vector_resources(event, context, properties):
127127
delete_s3_vector_resources(s3vectors_client, old_bucket_name, old_index_name)
128128
return create_s3_vector_resources(s3vectors_client, bucket_name, index_name, embedding_model, kms_key_arn)
129129
else:
130-
# Just return existing resource info
131-
return get_s3_vector_info(s3vectors_client, bucket_name, index_name)
130+
# Names haven't changed - update existing resources (recreate index)
131+
return update_s3_vector_info(s3vectors_client, bucket_name, index_name)
132132

133133
elif request_type == 'Delete':
134134
logger.info(f"Deleting S3 Vector bucket: {bucket_name}")
@@ -325,6 +325,28 @@ def get_knowledge_base_info(bedrock_agent_client, kb_id):
325325
raise
326326

327327

328+
def delete_vector_index(s3vectors_client, bucket_name, index_name):
329+
"""Delete a vector index from an S3 Vectors bucket."""
330+
try:
331+
logger.info(f"Deleting vector index: {index_name} from bucket: {bucket_name}")
332+
333+
s3vectors_client.delete_index(
334+
vectorBucketName=bucket_name,
335+
indexName=index_name
336+
)
337+
logger.info(f"Successfully deleted vector index: {index_name}")
338+
return True
339+
340+
except ClientError as e:
341+
if e.response['Error']['Code'] in ['IndexNotFound', 'ResourceNotFoundException', 'NoSuchIndex']:
342+
# Index doesn't exist, which is fine for delete operations
343+
logger.info(f"Index {index_name} not found (already deleted or never existed)")
344+
return False
345+
else:
346+
logger.error(f"Error deleting vector index {index_name}: {e}")
347+
raise
348+
349+
328350
def create_vector_index(s3vectors_client, bucket_name, index_name):
329351
"""Create a vector index with standard configuration for Bedrock Knowledge Base integration."""
330352
try:
@@ -335,11 +357,11 @@ def create_vector_index(s3vectors_client, bucket_name, index_name):
335357
indexName=index_name,
336358
dataType="float32",
337359
dimension=1024, # All embedding models in picklist output 1024
338-
distanceMetric="euclidean",
360+
distanceMetric="cosine",
339361
metadataConfiguration={
340362
"nonFilterableMetadataKeys": [
341363
"AMAZON_BEDROCK_METADATA",
342-
"AMAZON_BEDROCK_TEXT"
364+
"AMAZON_BEDROCK_TEXT_CHUNK"
343365
]
344366
}
345367
)
@@ -356,6 +378,22 @@ def create_vector_index(s3vectors_client, bucket_name, index_name):
356378
raise
357379

358380

381+
def recreate_vector_index(s3vectors_client, bucket_name, index_name):
382+
"""Delete and recreate a vector index to ensure fresh configuration."""
383+
try:
384+
logger.info(f"Recreating vector index: {index_name} in bucket: {bucket_name}")
385+
386+
# Delete existing index if it exists
387+
delete_vector_index(s3vectors_client, bucket_name, index_name)
388+
389+
# Create new index
390+
return create_vector_index(s3vectors_client, bucket_name, index_name)
391+
392+
except Exception as e:
393+
logger.error(f"Error recreating vector index {index_name}: {e}")
394+
raise
395+
396+
359397
def create_s3_vector_resources(s3vectors_client, bucket_name, index_name, embedding_model, kms_key_arn=None):
360398
"""Create S3 Vector bucket and index following Console approach."""
361399
try:
@@ -492,6 +530,47 @@ def get_s3_vector_info(s3vectors_client, bucket_name, index_name):
492530
raise
493531

494532

533+
def update_s3_vector_info(s3vectors_client, bucket_name, index_name):
534+
"""Update existing S3 Vector resources by recreating the index."""
535+
try:
536+
# Get bucket info
537+
bucket_response = s3vectors_client.get_vector_bucket(vectorBucketName=bucket_name)
538+
bucket_arn = bucket_response.get('BucketArn')
539+
540+
# Get region and account ID for ARN construction
541+
region = s3vectors_client.meta.region_name
542+
sts_client = boto3.client('sts', region_name=region)
543+
account_id = sts_client.get_caller_identity()['Account']
544+
545+
# Construct bucket ARN if not returned in response
546+
if not bucket_arn:
547+
bucket_arn = f"arn:aws:s3vectors:{region}:{account_id}:bucket/{bucket_name}"
548+
549+
logger.info(f"Found existing vector bucket ARN: {bucket_arn}")
550+
551+
# For updates, always recreate the index to ensure fresh configuration
552+
logger.info(f"Recreating vector index for update: {index_name}")
553+
recreate_vector_index(s3vectors_client, bucket_name, index_name)
554+
555+
# Construct index ARN (required for Knowledge Base configuration)
556+
index_arn = f"arn:aws:s3vectors:{region}:{account_id}:bucket/{bucket_name}/index/{index_name}"
557+
558+
logger.info(f"Vector bucket ARN: {bucket_arn}")
559+
logger.info(f"Vector index ARN: {index_arn}")
560+
561+
return {
562+
'BucketName': bucket_name,
563+
'BucketArn': bucket_arn,
564+
'IndexName': index_name,
565+
'IndexArn': index_arn,
566+
'Status': 'Updated'
567+
}
568+
569+
except ClientError as e:
570+
logger.error(f"Error updating S3 Vector bucket info: {e}")
571+
raise
572+
573+
495574
def get_physical_resource_id(event, properties, response_data):
496575
"""
497576
Generate appropriate PhysicalResourceId for successful operations.

0 commit comments

Comments
 (0)