Sriram
Sriram

Reputation: 150

Terraform : How to fetch or destroy resources created by other means?

Sometimes I end up creating resources using AWS console due to some errors in Terraform or for lack of time. Can I list all my resources and destroy them? Basically a discovery of existing cloud resources and management of such ?

Ex: list my EC2 instances using Terraform and destroy when needed . How to achieve this?

Upvotes: 0

Views: 960

Answers (1)

Martin Atkins
Martin Atkins

Reputation: 74219

Terraform is designed to ignore any existing objects that it didn't create because otherwise it would be risky to adopt Terraform an existing system with many existing objects and it would be impossible to decompose the infrastructure into different configurations for each subsystem without each one trying to destroy the objects being managed by the others.

Terraform doesn't have any facility for automatically detecting objects created outside of Terraform, but you can explicitly bind specific objects from your remote system to resource instances in your Terraform configuration using the terraform import command.

That command has some safeguards to try to prevent accidentally immediately deleting an object you've just imported if e.g. you make a typo of the resource instance address, and so unfortunately the design of this command is contrary to your goal: it won't let you just import something and run terraform apply to destroy it.

Instead, you'd need to:

  • Write a stub empty resource block for a resource of the appropriate type in your configuration.
  • Run terraform import to bind your existing real object to that empty resource block.
  • After the import succeeds, immediately remove the resource block to tell Terraform that you intend to delete the object.
  • Run terraform apply, and then Terraform should notice that it's tracking an object that is no longer mentioned in the configuration and propose to delete it.

Terraform is not the best tool for this job because it has essentially been designed to do the exact opposite of what you want to do, because typically users want to avoid destroying untracked objects to avoid disrupting neighboring systems.

However, you may be able to get the effect you want with some custom programming on your part, by writing a program that does something like the following:

  • Run terraform show -json in all of your configuration working directories to obtain a machine-readable description of the Terraform state in each one.
  • Decode the JSON state descriptions to find all of the resource instances of type aws_instance and collect a set of all of their id attribute values. This is the set of instances to keep.
  • Call the EC2 API DescribeInstances action to retrieve a list of all of the instances that actually exist. Collect a set of all of their IDs. This is the set of instances that exist.
  • Set-subtract the set of instances to keep from the set of instances that exist. The result is the set of instances to destroy.
  • If the set of instances to destroy isn't empty, call the EC2 API's TerminateInstances action to terminate every instance ID in that set.

This description is specific to Amazon EC2 instances. The same pattern could apply to objects of any other type, but there is no general solution that will work across all object types at once because the AWS API design doesn't work that way: each object type has its own separate operations for querying which objects exist and for destroying a particular object or set of objects.

Upvotes: 4

Related Questions