Import Existing Resource into Terraform Configuration
Not every cloud resources are provisioned from a Terraform configuration. In production environment, most of the resources are actually outside of a configuration. For certain scenarios, we would want to move some existing resources into a Terraform configuration. The most common reason is that we want to provision some resources that reference to an existing resource. However, that existing resource is not in the configuration so we will have to either temporary move it in or even permanently.
We will use the example below. There are already the VPC and the subnet-a. We want to add the VM new-vm into the subnet using Terraform. If we create a configuration to provision the VM, we will not be able to provide the subnet and the VPC.
Below is the flow as mentioned in the HashiCorp documentation. Based on the flow, we must do IMPORT before WRITE CONFIG. That is not entirely true though. We will see in the steps below.
The syntax for import is pretty simple as below
#terraform import ADDRESS ID
The ADDRESS would be the name and type of resource we defined in our configuration file. For example, the ADDRESS for the resource below would be google_compute_network.vpcs
As for the ID, it is different for different Provider. For example the EC2 in AWS, the document is as below.
And for GCP, it is as below
Let’s try to import the VPC first.
#terraform import google_compute_network.vpc-1 vpc-1
Error: resource address "google_compute_network.vpc-1" does not exist in the configuration.
So we can see that, the import is looking for the configuration file that has the resource vpc-1. This is why I said earlier that the flow provided by HashiCorp is wrong. We need the configuration file first.
HashiCorp is working on the new version of Terraform that could generate the configuration during import. As of version 1.1.4, this is still not available.
Let’s try to put some placeholder for our VPC in the configuration as below.
The import command returns without error now. However, when we try to plan it.
So we can see that, we must provide the entire original configuration, not just the name. And we must specify everything the same if do not want changes.
So at the end, I must have full configuration file like this to do a proper import and avoid changes. It took me a few rounds of planning and updating the configuration file to get it correct.
After getting the right configuration I did the apply, only new resources were provisioned, the 2 imported resources were left intact. However, when I called destroy using the new config, Terraform was trying to destroy the imported resources too. Because I still had the VM in the subnet, I got this error ‘resourceInUseByAnotherResource’ and everything got messed up.
In conclusion, I think the import function in Terraform is still a half-baked feature until when it could fully generate the configuration. It would still be useful in some scenarios but there are lot of manual steps to be done. Most importantly, whoever doing this has to be careful when calling the command to destroy his configuration.