Indeed, this resource type is wrapping an underlying EC2 API operation that is what is really doing all the work here, and that underlying API itself does not support assigning tags to the secondary objects it creates. Therefore the Terraform AWS provider cannot expose that functionality itself.
It’s unfortunately a pretty common situation with EC2 that one API call can generate many objects at the same time but will often only tag the topmost object. I’m not sure if this is still true but I recall having the same problem with launching EC2 instances where the API implicitly creates a network interface or an EBS volume. I would suggest sending this feedback to AWS and then Terraform can expose any new API features they might add to support this requirement.
In the meantime, in a previous role where we were using EC2 in this way we added a scheduled task (an AWS Lambda function in our case, but any scheduled compute would work) that searched for untagged volumes and snapshots, checked which EC2 instance or AMI they were attached to, and copied a subset of the tags over to the volumes and snapshots. This did rely on the fact that we never shared snapshots or volumes between subsystems and so could assume that the tags would never need to change again after being initially populated by the Lambda function.