When attempting to delete an Amazon VPC through AWS CLI, you might encounter the frustrating DependencyViolation
error. This occurs because AWS enforces dependency checks to prevent accidental deletion of resources that other services rely on.
aws ec2 delete-vpc --vpc-id vpc-xxx
# Returns: An error occurred (DependencyViolation) when calling the DeleteVpc operation: The vpc 'vpc-xxx' has dependencies and cannot be deleted.
Here's my step-by-step method to uncover all dependencies:
1. Check for Active EC2 Instances
aws ec2 describe-instances --filters Name=vpc-id,Values=vpc-xxx \
--query 'Reservations[].Instances[?State.Name==running].[InstanceId]' \
--output text
2. Identify Attached Internet Gateways
aws ec2 describe-internet-gateways \
--filters Name=attachment.vpc-id,Values=vpc-xxx
3. List NAT Gateways
aws ec2 describe-nat-gateways \
--filter Name=vpc-id,Values=vpc-xxx
4. Find VPC Endpoints
aws ec2 describe-vpc-endpoints \
--filters Name=vpc-id,Values=vpc-xxx
5. Check for Load Balancers
aws elbv2 describe-load-balancers | \
jq -r '.LoadBalancers[] | select(.VpcId=="vpc-xxx") | .LoadBalancerArn'
For frequent VPC management, I've created this bash script to identify all potential dependencies:
#!/bin/bash
VPC_ID="vpc-xxx"
echo "Checking dependencies for VPC $VPC_ID"
# EC2 Instances
echo -e "\nEC2 Instances:"
aws ec2 describe-instances --filters Name=vpc-id,Values=$VPC_ID \
--query 'Reservations[*].Instances[*].[InstanceId,State.Name]' \
--output table
# Network Interfaces
echo -e "\nENIs:"
aws ec2 describe-network-interfaces --filters Name=vpc-id,Values=$VPC_ID \
--query 'NetworkInterfaces[*].[NetworkInterfaceId,Status]' \
--output table
From my experience, these are the most frequent dependency issues:
- Dangling Elastic Network Interfaces (ENIs)
- Unreleased Elastic IPs associated with NAT Gateways
- Route tables with active routes
- Security groups still referenced by other resources
# Check for security group references
aws ec2 describe-security-groups \
--filters Name=vpc-id,Values=vpc-xxx \
--query 'SecurityGroups[*].GroupId'
Once dependencies are identified, here's how to systematically remove them:
- Terminate all EC2 instances in the VPC
- Delete load balancers and target groups
- Remove NAT gateways and release Elastic IPs
- Detach and delete internet gateways
# Example: Detach Internet Gateway
IGW_ID=$(aws ec2 describe-internet-gateways \
--filters Name=attachment.vpc-id,Values=vpc-xxx \
--query 'InternetGateways[0].InternetGatewayId' --output text)
aws ec2 detach-internet-gateway --internet-gateway-id $IGW_ID --vpc-id vpc-xxx
aws ec2 delete-internet-gateway --internet-gateway-id $IGW_ID
Every AWS architect has faced this moment - you try to delete a VPC through the CLI and get hit with the dreaded:
A client error (DependencyViolation) occurred when calling the DeleteVpc operation:
The vpc 'vpc-xxx' has dependencies and cannot be deleted.
Before attempting deletion, you need to identify all resources tied to your VPC. These typically include:
- EC2 instances
- ENIs (Elastic Network Interfaces)
- NAT Gateways
- Load Balancers
- VPC Peering Connections
- Internet Gateways
- Route Tables
- Security Groups
- Subnets
- Endpoints
Here's a complete set of AWS CLI commands to uncover all dependencies:
# Check for EC2 instances
aws ec2 describe-instances --filters Name=vpc-id,Values=vpc-xxx
# List network interfaces
aws ec2 describe-network-interfaces --filters Name=vpc-id,Values=vpc-xxx
# Find NAT gateways
aws ec2 describe-nat-gateways --filter Name=vpc-id,Values=vpc-xxx
# Discover load balancers (both ALB and NLB)
aws elbv2 describe-load-balancers | jq '.LoadBalancers[] | select(.VpcId=="vpc-xxx")'
# Check for VPC peering connections
aws ec2 describe-vpc-peering-connections --filters Name=requester-vpc-info.vpc-id,Values=vpc-xxx
# Verify internet gateway attachment
aws ec2 describe-internet-gateways --filters Name=attachment.vpc-id,Values=vpc-xxx
# Inspect route tables
aws ec2 describe-route-tables --filters Name=vpc-id,Values=vpc-xxx
# List security groups (except default)
aws ec2 describe-security-groups --filters Name=vpc-id,Values=vpc-xxx | jq '.SecurityGroups[] | select(.GroupName!="default")'
# Check subnets
aws ec2 describe-subnets --filters Name=vpc-id,Values=vpc-xxx
# Find VPC endpoints
aws ec2 describe-vpc-endpoints --filters Name=vpc-id,Values=vpc-xxx
For frequent VPC cleanup tasks, consider this bash script that compiles all dependencies:
#!/bin/bash
VPC_ID="vpc-xxx"
echo "Checking dependencies for VPC: $VPC_ID"
check_resource() {
local service=$1
local command=$2
local filter=$3
echo -e "\nChecking $service:"
result=$(aws $service $command --filters $filter 2>&1)
if [ $? -eq 0 ] && [ ! -z "$result" ]; then
echo "$result" | jq .
return 1
else
echo "No dependencies found"
return 0
fi
}
# Run all checks
check_resource ec2 describe-instances "Name=vpc-id,Values=$VPC_ID"
check_resource ec2 describe-network-interfaces "Name=vpc-id,Values=$VPC_ID"
check_resource ec2 describe-nat-gateways "Name=vpc-id,Values=$VPC_ID"
# Include other checks as needed...
echo -e "\nDependency check complete for VPC: $VPC_ID"
Some particularly tricky dependencies to watch for:
- DynamoDB Streams: Can maintain VPC endpoint connections
- RDS Instances: Might be in subnets you're trying to delete
- Lambda Functions: Could be configured with VPC settings
For Lambda functions specifically:
aws lambda list-functions | jq '.Functions[] | select(.VpcConfig!=null) | select(.VpcConfig.VpcId=="vpc-xxx")'
After cleaning all visible dependencies, run this verification command:
aws ec2 describe-vpcs --vpc-ids vpc-xxx \
--query 'Vpcs[0].CidrBlockAssociationSet[].AssociationId' \
--output text | xargs -I {} aws ec2 disassociate-vpc-cidr-block --association-id {}
aws ec2 delete-vpc --vpc-id vpc-xxx
This ensures all CIDR blocks are properly disassociated before attempting deletion.