terraform refresh tries to find any resources stored in the status file and update with any drift that occurred in the provider outside Terraform since the last time it ran.
For example, let's say the status file contains 3 EC2 instances with i-abc123 , i-abc124 , i-abc125 , and then you delete i-abc124 outside Terraform. After starting terraform refresh a plan will show that it needs to create a second instance, while the destruction plan will show that it only needs to destroy the first and third instances (and will not destroy the missing second instance).
Terraform makes a very specific decision not to interfere with things that are not controlled by Terraform. This means that if a resource does not exist in its status file, it will not touch it at all. This allows you to run Terraform along with other tools, as well as manually make changes to the AWS console. It also means that you can run Terraform in different contexts by simply providing a different state file for use, allowing you to split your infrastructure into several state files and get rid of the catastrophic distortion of the state file.
To get rid of your current hole, I suggest you freely use terraform import to return data to your status file or, if possible, manually destroy everything outside Terraform and start from scratch.
In the future, I would suggest how to unzip state files for use in more detailed contexts, and to store your remote state in an S3 bucket with version control enabled. You can also look at tools like Terragrunt to lock your status file, to avoid damage, or wait for the lock of the ground state file in the upcoming 0.9 release of Terraform.
source share