Example: Remove an integration and its agent with Claude

Remove a connection and the collection agent behind it, in Monte Carlo and in AWS, without touching anything you keep. Covers an agent managed by Terraform and one deployed with CloudFormation.

In this example two things are removed:

Everything else in the account stays. Claude checks what depends on each target, removes the Monte Carlo side in the right order, and gives you the AWS steps.

WhoWhatHow
ClaudeMap what's on each target and confirm nothing you keep depends on itMCP tools
YouReview and apply the Terraform destroyterraform plan -destroy, terraform apply
ClaudeDeregister the CloudFormation agent and delete its deploymentdelete_aws_collection_agent, delete_deployment
YouEmpty the agent's bucket, delete the stackAWS CLI
ClaudeConfirm what's leftMCP tools

1. Ask Claude

Name what to remove and how each piece was created. Monte Carlo doesn't record which tool created a resource, and anything Terraform manages has to be removed with Terraform: deleting it through Claude leaves it in the Terraform state, and the next apply creates it again. If you're not sure, Claude asks, and gives you a check to run in each Terraform directory. It prints the address of the resource whose id this is, or nothing, and never the state:

ID=<resource-id>
[ -n "${ID}" ] && terraform state list -id="${ID}"

Then ask:

We want to clean up two things in Monte Carlo and AWS:
1. The Snowflake integration <warehouse-name> and its agent <tf-agent-name>. Both were created with our Terraform in <terraform-dir> (state is there).
2. The agent <cfn-agent-name>, which has nothing on it; it was deployed with the CloudFormation stack <stack-name> in AWS account <account-id>, <region>.
Everything else must stay. What's the safe way to remove these?

Claude lists what's on each target: in this example the Terraform agent held one warehouse, its connection and credentials, and the other agent held nothing. It confirms that nothing you keep depends on them, and points out anything shared: here, the Snowflake secret in Secrets Manager isn't in the Terraform state, so a destroy leaves it for the other connection that uses it.

2. The Terraform-managed integration and agent

Empty the agent's bucket first. The agent stores samples and temporary results in a versioned S3 bucket, and S3 won't delete a bucket that still holds old object versions or delete markers, even when list-objects-v2 shows it as empty. Find the bucket in the Terraform state, confirm it's this agent's, and empty it:

cd <terraform-dir>
terraform state show module.mcd_agent.aws_s3_bucket.mcd_agent_store | grep -E '^ *bucket '

B=<agent-bucket-name>
while :; do
  aws s3api list-object-versions --bucket "${B}" --max-items 1000 \
    --query '{Objects: [Versions, DeleteMarkers][][].{Key: Key, VersionId: VersionId}, Quiet: `true`}' \
    --output json > empty-bucket.json
  jq -e '.Objects | length > 0' empty-bucket.json > /dev/null || break
  aws s3api delete-objects --bucket "${B}" --delete file://empty-bucket.json > /dev/null
done

Plan the destroy and let Claude review it.

terraform plan -destroy -out=destroy.tfplan

Send Claude the summary (Plan: 0 to add, 0 to change, 24 to destroy. in this example) and the resource list. Claude reads the saved plan too, and confirms every resource in it belongs to this agent: the Monte Carlo deployment, agent, warehouse, connection and credentials, the secret-read IAM policy, and the mcd-agent module's Lambda, roles, log group and bucket. Nothing outside the configuration is in it.

terraform apply destroy.tfplan
terraform state list   # expect nothing

Apply the new destroy.tfplan, not an older saved plan in the same folder. Terraform removes the Monte Carlo resources in dependency order (connection, warehouse and credentials, registration, deployment) and the AWS resources after them. Deleting the connection also deletes its monitors.

3. The CloudFormation-deployed agent

Claude deregisters it in Monte Carlo after re-checking that nothing is on it: delete_aws_collection_agent, then delete_deployment. Monte Carlo refuses to delete a deployment while an agent is still registered on it, which is why the agent goes first. Deregistering doesn't touch AWS.

Then delete the stack. Empty its bucket first (the StorageArn output of the stack; same loop as above), then:

REGION=<region>
STACK=<stack-name>
aws cloudformation describe-stacks --region "$REGION" --stack-name "$STACK" \
  --query 'Stacks[0].Outputs[?OutputKey==`StorageArn`].OutputValue' --output text
aws cloudformation delete-stack --region "$REGION" --stack-name "$STACK"
aws cloudformation wait stack-delete-complete --region "$REGION" --stack-name "$STACK"

Use the exact stack name: agents' stacks often have similar names. An agent running in a VPC takes 15–40 minutes to delete while AWS releases its Lambda's network interfaces (about 12 minutes in this example); the wait isn't stuck.

4. Claude confirms what's left

Claude lists deployments, agents, warehouses, connections and credentials again. In this example only the agent and cloud deployment that were meant to stay remain, each with its warehouses and connections, and no credentials are left without a connection. Claude can't see your AWS account, so it relies on your report for that side: an empty Terraform state and DELETE_COMPLETE on the stack.

Troubleshooting

SymptomCause and fix
terraform destroy or delete-stack fails with BucketNotEmptyThe bucket still has old object versions or delete markers. Run the emptying loop above, then plan and apply the destroy again (the earlier plan is stale), or retry delete-stack.
delete_deployment is refusedSomething is still registered or connected through it. Delete in the summary's order: connections, warehouses, credentials, the agent, then the deployment.
The connection delete is refusedThe warehouse has warehouse-level monitors or use cases that would go with its last connection. Review them with Claude before deleting.
wait stack-delete-complete runs for many minutesNormal for an agent in a VPC. Check describe-stack-events for a DELETE_FAILED event only if the wait itself fails.

Did this page help you?