Terraform 1.5 - Import and Automatic Code Generation
Tags: terraform, iac
Published: 2023-06-14 22:19:05

HashiCorp Terraform has become the defacto standard in the industry, when it comes to infrastructure as code tools. Its adoption has increased exponentially in the past few years specially among multi-cloud organizations. It uses a declarative language and stores the current state of all deployed and managed infrastructure into a file, which can be stored locally or remotely. This file, also called the [state file](https://developer.hashicorp.com/terraform/tutorials/state/state-cli), describes the current infrastructure configurations and is used to plan and deploy changes via files and modules that define the new infrastructure state.

Occasionally, there is a need to manage resources via Terraform that were created externally. That leads to one of the common questions asked by teams when they are considering to standardize their environment using Infrastructure as code with Terraform. How can they migrate their pre-existing infrastructure into Terraform compliant HCL code without spending too much time writing thousands of lines of code or going through the sometimes steep learning curve that may be required in some cases.

In this article, I'll talk about how HashiCorp addressed this challenge in previous Terraform versions, and the improvements they have recently announced with the launch of [Terraform v1.5.0](https://www.hashicorp.com/blog/terraform-1-5-brings-config-driven-import-and-checks) to facilitate the migration and adoption of Terraform to manage organization's cloud resources, by saving teams valuable time during the process.

**The Good Old Days**

To help teams move their infrastructure to Terraform, HashiCorp, introduced the [terraform import](https://developer.hashicorp.com/terraform/cli/import) command. The import Terraform CLI command is used to read real-world infrastructure and update the state, so that future updates to the same set of infrastructure are applied via IaC.

The previous import functionality was very helpful; however, there were some challenges which were not addressed. For example, it did not create the corresponding HCL configuration automatically, which required the resource code to be manually written or the output of command `terraform show` copied and pasted into the configuration file.

It also involved a multi-step process of running plans to identify the required attribute values until you could achieve a clean run of Terraform. The import command also could only import one resource at a time. If the organization had only a few resources they wanted to import, that was not much of a problem, but when the migration involved hundreds or even thousands of resources, that task was absolutely daunting and could lead to a lot of mistakes.

**Terraform v1.5.x - Config-Driven Import and Improvements**

HashiCorp recently launched [Terraform v1.5.0](https://www.hashicorp.com/blog/terraform-1-5-brings-config-driven-import-and-checks), which introduces a new config-driven import feature, that improves the import workflow with the use of a new import block that is declared inside your configuration containing the resources to import.

***Improvements***

*Bulk Import*
The new import block allows you to perform bulk import 
Each block will take the ID of the resource of the provider as well as the Terraform resource address, which will be imported. As you can see in the example below, you can do this for multiple resources at once

- **Step 1**: Define your provider configuration block as usual:
![provider_definition](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tu048ub956js4dt92u66.png)

- **Step 2**: Define your import configuration block with each resource you would like to import. As previously mentioned, notice that the import block takes to arguments: `id` and `to`. In this example, I am importing 4 AWS resources

![import_block](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uxp5d34datqch1xds5b1.png)

- **Step 3**: Once you define your provider configuration and import block(s), you can then initialize Terraform as usual via the command `terraform init`

- **Step 4**: Finally, you can then generate your configuration, by using the newly introduced command `terraform plan -generate-config-out=generated.tf`, where `generated.tf` is the name of the output file which will contain the generated HCL configuration.

The end result, is that Terraform will import, and generate both the state file (Similar to previous versions), but most important, it will generate the HCL code, as per the following output example:
![generated_config](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3e3xebal87aunxwflhp.png)

Notice that for each configuration block, the following comment is automatically added "__generated__ by Terraform"

*Terraform Cloud Support*

The new Config-Driven Import is also available in Terraform Cloud, with the objective of providing a more secure workflow when working in import operations. The advantage of this integration, is that developers no longer need direct access to the state file, or cloud credentials stored locally.

Below is a comparison table between the import capabilities available before v1.5.x and the new ones recently introduced.

![comparisson_table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cbvfvbpl02xpwctc5dof.png)

**Limitations**

Although the Config-Driven Import functionality is a big step from where it all began, there are some obvious and other not so obvious limitations:

- Terraform import does not detect or generate relationships between infrastructure. In other words, it won't make references to other ID or name attributes, using data sources or other resources itself.

- The current import method, imports every single attribute, including unused, empty ones. Meaning, that it does not detect which default attributes you can skip setting.

- Not all providers and resources support Terraform import.

This is not an exhaustive list of the limitations but only the ones which I personally consider important to mention before you get started.

**Alternative Options to Config-Driven Import**

I would be remiss, if I didn't mention in this article, that over the years, other open source projects and vendors have created dedicated tools to assist with the migration process either for multiple cloud providers, or vendor specific provider migration tools.

I won't be going in details about each one of the available tools out there, but here is a small list of the ones I could find
![migration_tool_list](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45dj5awb1c3odzs1qacu.png)

**References:**

- [Import Terraform Configuration](https://developer.hashicorp.com/terraform/tutorials/state/state-import)

- [Terraform 1.5 brings config-driven import and checks](https://www.hashicorp.com/blog/terraform-1-5-brings-config-driven-import-and-checks)

- [Config-driven import simplifies migration to Terraform](https://www.hashicorp.com/blog/new-terraform-cloud-capabilities-to-import-view-and-manage-infrastructure)