terraform destroy doesn't delete the ec2 instance created using input parameters for variables

I tried launching an ec2 instance using input parameters for the variables in terraform apply command. This creates the instance successfully. However, when I try to delete the instance using terraform destory, it executes but nothing gets deleted.

So I have a region variable with a default value. When I pass a different region in this variable using input parameters,instance launchesjust fine in the provided region but I am not able to terminate it using terraform destroy.

main.tf

variable "region" {
  default = "us-west-1"
}

variable "ami" {
  type    = "map"
  default = {
    us-east-2 = "ami-02e680c4540db351e"
    us-west-1 = "ami-011b6930a81cd6aaf"
  }
}

provider "aws" {
  region = "${var.region}"
}

resource "aws_instance" "web" {
  ami           = "${lookup(var.ami,var.region)}"
  instance_type = "t2.micro"

  tags {
    Name = "naxi"
  }
}

Terraform apply:

terraform apply -var region=us-east-2

Output of terraform destroy :

aws_instance.web: Refreshing state... (ID: i-05ca0514f61dcaf16)
Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes


Destroy complete! Resources: 0 destroyed.

Though it's able to lookup the instance id in the correct region, my guess is that it is trying to terminate the instance from the default region and not from the one I supplied as parameter.

Is there a way I can supply a parameter -var region=something with terraform destroy?

Destroy works as expected if I use the default values and no input parameters.

EDIT---

As soon as I give the this command: terraform destroy -varfile=variables.tfvars, all the instance related information from terraform.tfstate file gets removed and all the previous content of this file gets saved as backup to terraform.tfstate.backup. But still the instance is not deleted.

enter image description here


Solution 1:

I think this is your main problem:

  1. You ran apply with your "aws" provider defined one way (via a variable), but then you ran destroy with the same "aws" provider defined differently (you let the "region" variable default instead of specifying it).
  2. As a result, terraform destroy looked in the wrong place (wrong AWS region) for your created resources.
  3. Since terraform destroy was looking in the wrong place, it found nothing there.
  4. Therefore terraform destroy saw that it did not need to destroy anything, just update its locally stored state information to reflect the absence of the resources.

Try these steps instead:

terraform apply -var 'region=us-east-2'
terraform destroy -var 'region=us-east-2'

This works for me, Terraform v0.12.2 + provider.aws v2.16.0.

I am guessing slightly here, but it seems like the point is probably that you, the Terraform user, are responsible for making sure you destroy with the exact same provider definitions you apply'd with.

And if you're using any variables to help define your providers, then this is something you will need to be especially mindful of, since you are making it easy to accidentally change provider definitions.

As a side note, I ran into a similar confusion myself. It seems to me that HashiCorp's Getting Started guide, in its current state, could do a better job of warning about this. It walks newbies through a very similar setup to yours, and currently appears to say nothing about how to destroy properly, or any potential pitfalls.

Solution 2:

Perhaps you have multiple providers set. Try aliasing your provider and passing that into the resource.

provider "aws" {
  region = var.region
  alias  = "mine"
}

resource "aws_instance" "web" {
  provider = aws.mine
}