In a real-world situation of test-driven development, it will be a combination of developing terraform scripts and experimenting with the cloud portal. However, during this time, you may need to leverage resources produced manually on the cloud provider’s website. The two methods are to use a data block or an import statement. In this blog post, we will go into detail regarding both.
The main difference between the two is that the data block will only refer to manually created resources, whereas the import statement will import the resource into terraform state. which is equivalent to creating a resource via terraform.
Data block
Let’s say you are about to create a subnet, but the catch is that the virtual network in which the subnet should be is created using cloud portal not with terraform. In this situation, terraform state doesn’t have any permissions to access the virtual network in which the subnet should be created. In such scenario, we use data block. Below is the syntax.
data "provider_resource-type" "data-block-name"{
#filters to find the exact resource
}
The block starts with a keyword, which is “data,” and then it needs the provider and resource type. Let’s say, for our example, that the provider is Azure and the resource type is virtual network. The last word is the block name, which is useful when you want to refer to more than one resource of a similar type. Inside the curly brackets, we usually give filters. For our example, it would be the virtual network name and resource group name. So the code for our example looks exactly like below.
data "azurerm_virtual_network" "myvnet"{
virtual_network_name = "sturdietechie-vnet"
resource_group_name = "sturdietechie-rg"
}
#This will find the vnet in an rg with specified info
Now with this data block, we can use the “sturdietechie-vnet” and do whatever we want. For our example, we are going to create a new subnet which indeed refers to the above mentioned virtual network. that code is given below.
resource "azurerm_subnet" "snet"{
virtual_network_name = data.azurerm_virtual_network.myvnet
address_prefixes = ["10.0.0.0/24"]
}
The most important part of the above code block is to refer the virtual network that is manually created. which will be done with below syntax
data.<provider_resource-type>.<data block name>
Here the important part to note is that terraform has no powers to modify or change the virtual network. But if your use-case requires the terraform to have powers then the only option is to have it imported to state. Let’s talk about that now.
Import to terraform state.
Import, unlike data block, is a command to perform on terraform state rather than a block written in terraform source code. So, you should run in the terraform CLI.
#The command is
terraform import <provider_resource-type.block_name> <resource id>
Before running the terraform import command, you have to write the resource block just like how you write when you are provisioning a new virtual network. You can learn to write a resource block here.
Once you run it, you will be importing the resource to terraform state. since you are writing resource block for the same. terraform will have full pledged control over the resource.
Hope you understand the difference between referring to a manually created resource vs importing a manually created resource. Thanks for taking time to read my blog. Incase, you need help regarding cloud and terraform, you can hire me on fiverr.