77import time
88import logging
99import os
10- from botocore . exceptions import ClientError
10+ from typing import Any , Dict
1111from bedrock_agentcore_starter_toolkit .operations .gateway .client import GatewayClient
1212
1313logger = logging .getLogger ()
1414logger .setLevel (os .environ .get ("LOG_LEVEL" , "INFO" ))
1515
16-
1716def handler (event , context ):
1817 """CloudFormation custom resource handler for AgentCore Gateway"""
1918 logger .info (f"Received event: { json .dumps (event )} " )
@@ -40,9 +39,18 @@ def handler(event, context):
4039
4140 except Exception as e :
4241 logger .error (f"Error: { str (e )} " , exc_info = True )
43- cfnresponse .send (event , context , cfnresponse .FAILED , {},
44- physicalResourceId = gateway_name ,
45- reason = str (e ))
42+ # Check if this is a bedrock-agentcore access issue
43+ if 'bedrock-agentcore' in str (e ).lower () and ('access' in str (e ).lower () or 'unauthorized' in str (e ).lower ()):
44+ logger .warning ("bedrock-agentcore service appears unavailable - continuing without MCP gateway" )
45+ cfnresponse .send (event , context , cfnresponse .SUCCESS , {
46+ 'GatewayUrl' : 'N/A - Service not available' ,
47+ 'GatewayId' : 'N/A' ,
48+ 'GatewayArn' : 'N/A'
49+ }, physicalResourceId = gateway_name )
50+ else :
51+ cfnresponse .send (event , context , cfnresponse .FAILED , {},
52+ physicalResourceId = gateway_name ,
53+ reason = str (e ))
4654
4755
4856def create_or_update_gateway (props , gateway_name ):
@@ -125,45 +133,65 @@ def create_or_update_gateway(props, gateway_name):
125133
126134
127135def delete_gateway (props , gateway_name ):
128- """Delete AgentCore Gateway"""
136+ """Delete AgentCore Gateway using toolkit """
129137 try :
130138 region = props ['Region' ]
131- logger .info (f"Deleting gateway: { gateway_name } " )
132-
133- # Use direct boto3 bedrock-agent client
134- bedrock_client = boto3 .client ('bedrock-agent' , region_name = region )
135-
136- # Try to find and delete the gateway by name
137- try :
138- # List agent gateways to find the one with our name
139- response = bedrock_client .list_agent_gateways ()
140- target_gateway_id = None
141-
142- for gateway in response .get ('agentGateways' , []):
143- if gateway .get ('agentGatewayName' ) == gateway_name :
144- target_gateway_id = gateway .get ('agentGatewayId' )
145- break
146-
147- if target_gateway_id :
148- logger .info (f"Found gateway to delete: { target_gateway_id } " )
149-
150- # Delete the gateway
151- bedrock_client .delete_agent_gateway (agentGatewayId = target_gateway_id )
152- logger .info (f"Successfully deleted gateway: { gateway_name } " )
153- else :
154- logger .info (f"Gateway { gateway_name } not found - may already be deleted" )
155-
156- except Exception as delete_error :
157- logger .warning (f"Error during gateway deletion: { delete_error } " )
158- # Continue to try log group cleanup
139+ client = boto3 .client (
140+ "bedrock-agentcore-control" ,
141+ region_name = region
142+ )
143+ name : str = gateway_name
144+ gateway_id = None
145+ kwargs : Dict [str , Any ] = {"maxResults" : 10 }
146+ resp = client .list_gateways (** kwargs )
147+ items = [g for g in resp .get ("items" , []) if g .get ("name" ) == name ]
148+
149+ if len (items ) > 0 :
150+ gateway_id = items [0 ].get ("gatewayId" )
151+
152+ if gateway_id :
153+ logger .info (f"Attempting to delete gateway by ID: { gateway_id } " )
154+ # Step 1: List and delete all targets
155+ logger .info ("Finding targets for gateway: %s" , gateway_id )
156+ try :
157+ response = client .list_gateway_targets (gatewayIdentifier = gateway_id )
158+ # API returns targets in 'items' field
159+ targets = response .get ("items" , [])
160+ logger .info ("Found %s targets to delete" , len (targets ))
161+ for target in targets :
162+ target_id = target ["targetId" ]
163+ logger .info ("Deleting target: %s" , target_id )
164+ try :
165+ client .delete_gateway_target (gatewayIdentifier = gateway_id , targetId = target_id )
166+ logger .info ("Target deletion initiated: %s" , target_id )
167+ # Wait for deletion to complete
168+ time .sleep (5 )
169+ except Exception as e :
170+ logger .warning ("Error deleting target %s: %s" , target_id , str (e ))
171+
172+ # Verify all targets are deleted
173+ logger .info ("Verifying targets deletion..." )
174+ time .sleep (5 ) # Additional wait
175+ verify_response = client .list_gateway_targets (gatewayIdentifier = gateway_id )
176+ remaining_targets = verify_response .get ("items" , [])
177+ if remaining_targets :
178+ logger .warning ("%s targets still remain" , len (remaining_targets ))
179+ else :
180+ logger .info ("All targets deleted" )
181+ except Exception as e :
182+ logger .warning ("Error managing targets: %s" , str (e ))
183+
184+ client .delete_gateway (gatewayIdentifier = gateway_id )
185+ logger .info ("Gateway deleted successfully using ID" )
186+
187+ else :
188+ logger .info ("Gateway not found" )
159189
160190 # Clean up log group
161191 stack_name = props .get ('StackName' , 'UNKNOWN' )
162192 delete_log_group (gateway_name , region , stack_name )
163-
164193 except Exception as e :
165- logger .warning (f"Error deleting gateway: { e } " )
166- # Don't fail the stack deletion for cleanup issues
194+ logger .error (f"Gateway deletion failed: { e } " )
167195
168196
169197def create_log_group (gateway_name , region , stack_name ):
0 commit comments