Skip to content

Commit ebfc168

Browse files
author
Bob Strahan
committed
Fix S3 Vector integration to align with Bedrock Knowledge Base requirements
1 parent 7b9c973 commit ebfc168

File tree

1 file changed

+37
-49
lines changed
  • options/bedrockkb/src/s3_vectors_manager

1 file changed

+37
-49
lines changed

options/bedrockkb/src/s3_vectors_manager/handler.py

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,9 @@ def get_knowledge_base_info(bedrock_agent_client, kb_id):
274274

275275

276276
def create_s3_vector_resources(s3vectors_client, bucket_name, index_name, embedding_model, kms_key_arn=None):
277-
"""Create S3 Vector bucket and index with optional KMS encryption."""
277+
"""Create S3 Vector bucket with optional KMS encryption. Bedrock will manage the index automatically."""
278278
try:
279-
# Step 1: Create vector bucket with optional encryption
279+
# Create vector bucket with optional encryption
280280
logger.info(f"Creating vector bucket: {bucket_name}")
281281

282282
create_bucket_params = {
@@ -286,62 +286,49 @@ def create_s3_vector_resources(s3vectors_client, bucket_name, index_name, embedd
286286
# Add KMS encryption if provided
287287
if kms_key_arn:
288288
create_bucket_params['encryptionConfiguration'] = {
289-
'SSEAlgorithm': 'aws:kms',
290-
'KMSMasterKeyID': kms_key_arn
289+
'sseType': 'aws:kms',
290+
'kmsKeyArn': kms_key_arn
291291
}
292292
logger.info(f"Using KMS encryption for bucket with key: {kms_key_arn}")
293293

294294
bucket_response = s3vectors_client.create_vector_bucket(**create_bucket_params)
295-
bucket_arn = bucket_response['BucketArn']
296-
logger.info(f"Created vector bucket with ARN: {bucket_arn}")
297-
298-
# Step 2: Create vector index in the bucket
299-
logger.info(f"Creating vector index: {index_name} in bucket: {bucket_name}")
300-
index_response = s3vectors_client.create_vector_index(
301-
vectorBucketName=bucket_name,
302-
indexName=index_name,
303-
embeddingConfiguration={
304-
'embeddingModelArn': f"arn:aws:bedrock:*::foundation-model/{embedding_model}"
305-
}
306-
)
307-
index_arn = index_response['IndexArn']
308-
logger.info(f"Created vector index with ARN: {index_arn}")
295+
logger.info(f"Created vector bucket: {bucket_name}")
296+
297+
# Get bucket ARN from response or construct it
298+
bucket_arn = bucket_response.get('BucketArn')
299+
if not bucket_arn:
300+
# Construct bucket ARN if not returned
301+
bucket_arn = f"arn:aws:s3vectors:{s3vectors_client.meta.region_name}:{s3vectors_client.meta.service_model.metadata['signingName']}:bucket/{bucket_name}"
302+
303+
logger.info(f"Vector bucket ARN: {bucket_arn}")
304+
305+
# Note: For Bedrock Knowledge Base integration, Bedrock will automatically
306+
# create and manage the vector index when the Knowledge Base is created.
307+
# We don't create the index manually here.
309308

310309
return {
311310
'BucketName': bucket_name,
312311
'BucketArn': bucket_arn,
313-
'IndexName': index_name,
314-
'IndexArn': index_arn,
312+
'IndexName': index_name, # This will be used by Bedrock
315313
'Status': 'Created'
316314
}
317315

318316
except ClientError as e:
319317
error_code = e.response['Error']['Code']
320-
if error_code in ['BucketAlreadyExists', 'IndexAlreadyExists']:
321-
logger.warning(f"Resource already exists: {e}")
318+
if error_code in ['BucketAlreadyExists', 'ConflictException']:
319+
logger.warning(f"Vector bucket already exists: {e}")
322320
# Try to get existing resource info
323321
return get_s3_vector_info(s3vectors_client, bucket_name, index_name)
324322
else:
325323
raise
326324

327325

328326
def delete_s3_vector_resources(s3vectors_client, bucket_name, index_name):
329-
"""Delete S3 Vector index and bucket."""
327+
"""Delete S3 Vector bucket. Note: Bedrock manages the index lifecycle."""
330328
try:
331-
# Step 1: Delete vector index first
332-
if index_name and bucket_name:
333-
try:
334-
logger.info(f"Deleting vector index: {index_name} from bucket: {bucket_name}")
335-
s3vectors_client.delete_vector_index(
336-
vectorBucketName=bucket_name,
337-
indexName=index_name
338-
)
339-
logger.info(f"Deleted vector index: {index_name}")
340-
except ClientError as e:
341-
if e.response['Error']['Code'] != 'NoSuchVectorIndex':
342-
logger.warning(f"Error deleting vector index: {e}")
343-
344-
# Step 2: Delete vector bucket
329+
# For S3 Vectors with Bedrock integration, Bedrock manages the index lifecycle
330+
# We only need to delete the vector bucket, which should be done after
331+
# the Knowledge Base is deleted to avoid dependency issues
345332
if bucket_name:
346333
try:
347334
logger.info(f"Deleting vector bucket: {bucket_name}")
@@ -350,37 +337,38 @@ def delete_s3_vector_resources(s3vectors_client, bucket_name, index_name):
350337
)
351338
logger.info(f"Deleted vector bucket: {bucket_name}")
352339
except ClientError as e:
353-
if e.response['Error']['Code'] != 'NoSuchBucket':
340+
if e.response['Error']['Code'] not in ['NoSuchBucket', 'BucketNotEmpty']:
354341
logger.warning(f"Error deleting vector bucket: {e}")
342+
else:
343+
logger.info(f"Vector bucket {bucket_name} not found or not empty (expected): {e}")
355344

356345
except Exception as e:
357346
logger.warning(f"Error during deletion (continuing): {e}")
358347

359348

360349
def get_s3_vector_info(s3vectors_client, bucket_name, index_name):
361-
"""Get information about existing S3 Vector resources."""
350+
"""Get information about existing S3 Vector bucket. Bedrock manages the index."""
362351
try:
363352
# Get bucket info
364353
bucket_response = s3vectors_client.get_vector_bucket(vectorBucketName=bucket_name)
365-
bucket_arn = bucket_response['BucketArn']
354+
bucket_arn = bucket_response.get('BucketArn')
366355

367-
# Get index info
368-
index_response = s3vectors_client.describe_vector_index(
369-
vectorBucketName=bucket_name,
370-
indexName=index_name
371-
)
372-
index_arn = index_response['IndexArn']
356+
# Construct bucket ARN if not returned in response
357+
if not bucket_arn:
358+
# Get account ID from STS for ARN construction
359+
sts_client = boto3.client('sts', region_name=s3vectors_client.meta.region_name)
360+
account_id = sts_client.get_caller_identity()['Account']
361+
bucket_arn = f"arn:aws:s3vectors:{s3vectors_client.meta.region_name}:{account_id}:bucket/{bucket_name}"
373362

374363
return {
375364
'BucketName': bucket_name,
376365
'BucketArn': bucket_arn,
377-
'IndexName': index_name,
378-
'IndexArn': index_arn,
366+
'IndexName': index_name, # Index name for Bedrock to use
379367
'Status': 'Existing'
380368
}
381369

382370
except ClientError as e:
383-
logger.error(f"Error getting S3 Vector info: {e}")
371+
logger.error(f"Error getting S3 Vector bucket info: {e}")
384372
raise
385373

386374

0 commit comments

Comments
 (0)