How to `terraform destroy` an `aws_instance` without also destroying its `aws_ebs_volume` (separate resource)
This may be what you are doing already (in which case this sounds like a bug), yet it seems just based on the limited information in the question that you may be forgetting a step: Run plan -destroy -target=... -target=... first.  The terraform destroy command will try to operate on changes listed in the .plan file.

The following example assumes a Terraform module named foo, with 3 EBS volumes and attachments named as: dev-sdb, dev-sdf, dev-sdg.  All resources are assumed to have count = local.enabled ? 1 : 0.  So this is the more advanced case you may encounter where each resource would have to be targeted with the array syntax [0].


First create a targeted plan file with terraform plan -destroy -target=.... 
Do this before trying to run terraform destroy

terraform plan -destroy \
               -target=module.foo.aws_volume_attachment.dev-sdb-attachments[0] \
               -target=module.foo.aws_volume_attachment.dev-sdf-attachments[0] \
               -target=module.foo.aws_volume_attachment.dev-sdg-attachments[0] \
               -target=module.foo.aws_instance.foo[0]  \
               -target=module.foo.aws_iam_instance_profile.foo[0] \
               -out=intermediate.plan

Run terraform destroy, optionally also using -target=... for safety precautions if you wish:

terraform destroy -target=module.foo.aws_volume_attachment.dev-sdb-attachments[0] \
                  -target=module.foo.aws_volume_attachment.dev-sdf-attachments[0] \
                  -target=module.foo.aws_volume_attachment.dev-sdg-attachments[0] \
                  -target=module.foo.aws_instance.foo[0]  \
                  -target=module.foo.aws_iam_instance_profile.foo[0] \
                  intermediate.plan



If you need this to be unattended for automation, add -auto-approve flag to the terraform destroy command.  Otherwise, it assumes an interactive terminal session and will prompt before destroying any resources.