Created
September 18, 2025 00:30
-
-
Save adenot/9eaad982bf6a8ad5348100000c48a1e3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| """ | |
| Script to delete all default VPCs across all AWS regions. | |
| Only targets VPCs that are marked as default. | |
| """ | |
| import boto3 | |
| from botocore.exceptions import ClientError | |
| def get_all_regions(): | |
| """Get all available AWS regions for EC2.""" | |
| ec2 = boto3.client('ec2', region_name='us-east-1') | |
| response = ec2.describe_regions() | |
| return [region['RegionName'] for region in response['Regions']] | |
| def delete_default_vpc(region): | |
| """Delete the default VPC in a specific region if it exists.""" | |
| ec2 = boto3.client('ec2', region_name=region) | |
| try: | |
| # Get all VPCs in the region | |
| response = ec2.describe_vpcs( | |
| Filters=[ | |
| { | |
| 'Name': 'isDefault', | |
| 'Values': ['true'] | |
| } | |
| ] | |
| ) | |
| # Check if there's a default VPC | |
| if not response['Vpcs']: | |
| print(f"[{region}] No default VPC found") | |
| return False | |
| # Delete each default VPC (should only be one) | |
| for vpc in response['Vpcs']: | |
| vpc_id = vpc['VpcId'] | |
| # Delete dependencies first | |
| delete_vpc_dependencies(ec2, vpc_id, region) | |
| # Delete the VPC | |
| try: | |
| ec2.delete_vpc(VpcId=vpc_id) | |
| print(f"[{region}] Successfully deleted default VPC: {vpc_id}") | |
| return True | |
| except ClientError as e: | |
| print(f"[{region}] Error deleting VPC {vpc_id}: {e}") | |
| return False | |
| except ClientError as e: | |
| print(f"[{region}] Error accessing region: {e}") | |
| return False | |
| def delete_vpc_dependencies(ec2, vpc_id, region): | |
| """Delete VPC dependencies (subnets, IGW, etc.) before deleting VPC.""" | |
| # Delete subnets | |
| try: | |
| subnets = ec2.describe_subnets( | |
| Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}] | |
| ) | |
| for subnet in subnets['Subnets']: | |
| ec2.delete_subnet(SubnetId=subnet['SubnetId']) | |
| print(f"[{region}] Deleted subnet: {subnet['SubnetId']}") | |
| except ClientError as e: | |
| print(f"[{region}] Error deleting subnets: {e}") | |
| # Detach and delete internet gateways | |
| try: | |
| igws = ec2.describe_internet_gateways( | |
| Filters=[{'Name': 'attachment.vpc-id', 'Values': [vpc_id]}] | |
| ) | |
| for igw in igws['InternetGateways']: | |
| ec2.detach_internet_gateway( | |
| InternetGatewayId=igw['InternetGatewayId'], | |
| VpcId=vpc_id | |
| ) | |
| ec2.delete_internet_gateway( | |
| InternetGatewayId=igw['InternetGatewayId'] | |
| ) | |
| print(f"[{region}] Deleted IGW: {igw['InternetGatewayId']}") | |
| except ClientError as e: | |
| print(f"[{region}] Error deleting IGW: {e}") | |
| # Delete route tables (except main) | |
| try: | |
| route_tables = ec2.describe_route_tables( | |
| Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}] | |
| ) | |
| for rt in route_tables['RouteTables']: | |
| # Skip main route table | |
| if not any(assoc.get('Main', False) for assoc in rt.get('Associations', [])): | |
| ec2.delete_route_table(RouteTableId=rt['RouteTableId']) | |
| print(f"[{region}] Deleted route table: {rt['RouteTableId']}") | |
| except ClientError as e: | |
| print(f"[{region}] Error deleting route tables: {e}") | |
| # Delete security groups (except default) | |
| try: | |
| sgs = ec2.describe_security_groups( | |
| Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}] | |
| ) | |
| for sg in sgs['SecurityGroups']: | |
| if sg['GroupName'] != 'default': | |
| ec2.delete_security_group(GroupId=sg['GroupId']) | |
| print(f"[{region}] Deleted security group: {sg['GroupId']}") | |
| except ClientError as e: | |
| print(f"[{region}] Error deleting security groups: {e}") | |
| # Delete network ACLs (except default) | |
| try: | |
| nacls = ec2.describe_network_acls( | |
| Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}] | |
| ) | |
| for nacl in nacls['NetworkAcls']: | |
| if not nacl['IsDefault']: | |
| ec2.delete_network_acl(NetworkAclId=nacl['NetworkAclId']) | |
| print(f"[{region}] Deleted network ACL: {nacl['NetworkAclId']}") | |
| except ClientError as e: | |
| print(f"[{region}] Error deleting network ACLs: {e}") | |
| def main(): | |
| """Main function to delete all default VPCs.""" | |
| print("Starting deletion of default VPCs across all regions...") | |
| print("=" * 60) | |
| # Get all regions | |
| regions = get_all_regions() | |
| print(f"Found {len(regions)} regions to check\n") | |
| deleted_count = 0 | |
| failed_regions = [] | |
| # Process each region | |
| for region in regions: | |
| if delete_default_vpc(region): | |
| deleted_count += 1 | |
| else: | |
| # Track regions where deletion failed (if VPC existed) | |
| ec2 = boto3.client('ec2', region_name=region) | |
| try: | |
| response = ec2.describe_vpcs( | |
| Filters=[{'Name': 'isDefault', 'Values': ['true']}] | |
| ) | |
| if response['Vpcs']: | |
| failed_regions.append(region) | |
| except: | |
| pass | |
| # Summary | |
| print("\n" + "=" * 60) | |
| print(f"Summary: Deleted {deleted_count} default VPC(s)") | |
| if failed_regions: | |
| print(f"Failed to delete default VPCs in: {', '.join(failed_regions)}") | |
| print("Process complete!") | |
| if __name__ == "__main__": | |
| # Safety confirmation | |
| print("WARNING: This will delete ALL default VPCs across ALL regions!") | |
| print("This action cannot be undone.") | |
| confirmation = input("Type 'DELETE' to confirm: ") | |
| if confirmation == "DELETE": | |
| main() | |
| else: | |
| print("Operation cancelled.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment