Importing f5 resources with Terraform

Hello everyone, I’m trying to import f5 virtual servers, irules etc with Terraform but the existing resources are numerous and would be a tedious task to do with the terraform import command. Is there any way to do it in bulk per resource? I saw there a for each command. Will it help with my issue?

Hi @Asiya-Yunusa,

Terraform’s own import command is a single-resource operation, but you can use it as a building block for a batch import script. Some batch import wrappers already exist in the community, but I don’t know if any of them have support for F5 resource types in particular and so you may need to write something yourself in this case.

The overall process for that script to follow would be:

  • Use the F5 API directly to find the subset of servers that are relevant to your current configuration. You’ll need to define the rule for choosing the relevant servers yourself, based on your organization’s conventions and your intended architecture.
  • Run some more custom logic to decide which of the objects you found in the F5 API should correspond with each resource instance address in your configuration. The result here would be a mapping from whatever ID format the F5 provider expects to one Terraform resource instance address per source ID.
  • Either generate a script containing a series of terraform import ... commands, or run those commands directly from your first script, to tell Terraform each of those relationships between Terraform resource address and remote system ID.

Notice that a key part of this is defining the relationship between the existing objects and the resource instance addresses in Terraform. The appropriate rules for that tend to vary by user and so that’s why Terraform doesn’t have any automatic functionality for this today.

If you have a set of servers that are all equivalent, perhaps duplicating the same stateless service for redundancy or scale, then that can indeed be a potential use of for_each or count in order to describe their settings systematically in Terraform, rather than writing each of them out separately. However, that is a matter for how you structure your configuration, and doesn’t significantly change the import process I described above.

The only part of the process that varies depending on whether you are using for_each, count, or neither is what resource address syntax you’ll use in the terraform import commands:

  • bigip_ltm_virtual_server.example would identify the single instance of a resource that doesn’t use either for_each or count.
  • bigip_ltm_virtual_server.example["foo"] would identify one of possibly many instances of a resource that uses for_each, where "foo" is one of the keys included in the for_each collection.
  • bigip_ltm_virtual_server.example[0] would identify the first of possibly several instances of a resource that uses count, as long as count is greater than zero.

If you are new to Terraform then it may be best to experiment with some “throwaway” experimental infrastructure first, so that you can get some experience with how the count and for_each features behave, which may help you decide on a suitable way to structure your Terraform configuration to describe your existing servers. Then you can write the configuration for the “real” infrastructure, run terraform plan to see what resource addresses that configuration plans to create, and then make your batch import script generate those same addresses to create all of the expected relationships.

Once you’ve imported everything, you should be able to run terraform plan again and see it not plan to create any new infrastructure objects. It might plan to modify your existing objects, if the configuration you wrote doesn’t exactly match how those existing objects are configured today, but you can review the plan to decide on a case-by-case basis whether you’d prefer to change the Terraform configuration to match the existing objects or to have Terraform update those objects to match the Terraform configuration.