Import existing resources in bulk
You can configure queries that instruct Terraform to search your existing infrastructure for unmanaged resources. Terraform can also generate configuration for importing the resources it finds so that you can import them to your Terraform workspace in bulk. For information about importing single resources or small batches of resources, refer to Import an existing resource for instructions.
Introduction
For organizations with large sets of infrastructure resources, manually identifying and importing them is tedious and labor intensive, even when using third-party tools or custom scripts. To alleviate this burden, you can write HCL-based queries and run them with the Terraform CLI to retrieve unmanaged resources so that you can import them in bulk.
Complete the following steps to find and import resources in bulk:
- Search for resources: Create
listblocks to search for existing resources. - Review policy results: For remote queries in HCP Terraform, optionally evaluate Terraform policies against discovered resources before selecting resources to import.
- Generate configuration: Use the Terraform command to generate
resourceandimportblocks for importing the resources. The configuration also includes the resource identity. - Import resources: Copy the generated configuration into your main.tf file and run a
terraform applycommand to import the resources. - After importing resources, you can remove the generated
importblock or keep it as an historical record.
Requirements
Terraform v1.12 or newer is required to search for resources according to their resource identities. HCP Terraform uses resource identities to determine when resources are managed by another workspace. Refer to Import existing resources to state for more information.
Policy evaluation with terraform query requires Terraform v1.17.0 or later.
When you run queries remotely in HCP Terraform, HCP Terraform can evaluate policies against the resources it queries. Configure a Terraform policy set to apply to your workspace, or specify policy directories with the -policies flag. To run queries remotely, configure a cloud block, a workspace with remote or agent execution, and credentials as described in Evaluate policies. Refer to HCP Terraform Search requirements for organization and workspace prerequisites.
Supported providers
Verify that the resource type you want to search for is supported. Refer to your provider documentation for the most up-to-date information.
Define a query
To search for resources, you must create a standard .tf configuration and a .tfquery.hcl configuration.
Standard configurations
If your .tf configuration does not already have a required_providers block, add it so that Terraform can install all provider plugins required to create and manage resources specified in the configuration. Refer to the required_providers reference for details on how to configure this block.
If you have an HCP Terraform account, you can compare the resources Terraform discovers to resources you are already managing with Terraform in the HCP Terraform UI. To use this functionality, you must configure the cloud block in your .tf configuration to connect to HCP Terraform. Refer to the cloud block reference for details on how to configure this block.
Query configurations
Create a file with a .tfquery.hcl extension and add list blocks to define queries that read existing infrastructure and return lists of unmanaged resources.
Each list block requires an inline argument that specifies the type of resource you are querying. The type is specific to your provider. The block also requires an inline argument that declares a local name for the list of results returned by the query. Refer to the list block reference for configuration details.
The following example defines a list block named prod that queries aws_instances:
list "aws_instance" "prod" {
# . . .
}
Add the following arguments to your list block:
provider: This argument is required. It specifies which provider configuration Terraform should use to perform the query. Thelistblock retrieves the provider configuration from theterraformblock in yourmain.tfconfiguration, but you can declare aproviderblock in your query file with an alternate configuration and reference it in theproviderargument in yourlistblock.config: Add theconfigblock to yourlistblock and define provider-specific arguments to build your query. Refer to your provider documentation for supported arguments and values.include_resource: By default, Terraform retrieves only resource identities, but you can set theinclude_resourceargument totrueso that Terraform can also retrieve all available resource attributes. To reference resource attributes retrieved by the list block, you must enable theinclude_resourceargument. Setting this argument totruemay affect performance.limit: By default, Terraform retrieves up to 100 resources per list block, but you can use thelimitargument to specify a higher or lower number of results.
The list block also supports several Terraform meta-arguments, which are arguments built into Terraform configuration language that configure how Terraform creates and manages infrastructure objects. For example, you can use the count meta-argument to create multiple instances of the resource list returned by the query. Refer to Meta-arguments for more information.
In the following example, Terraform applies provider arguments to query for aws_instance resources in the us-east-2 region. The query also filters results prefixed with prod- and stage- and that are in a running state. The limit argument, which is not a provider-specific argument, instructs Terraform to return the first 50 results:
list "aws_instance" "prod" {
provider = aws
limit = 50
config {
region = "us-east-2"
filter {
name = "tag:Name"
values = ["prod-*", "staging-*"]
}
filter {
name = "instance-state-name"
values = ["running"]
}
}
}
Parameterize your query configuration
You can parameterize your .tfquery.hcl file so that you can reuse it with a different set of inputs. Refer to Set configuration parameters for instructions on how to parameterize configurations.
Add the following blocks to your query file to parameterize the configuration:
variable: Add thevariableblock to your query file to define variables that people who run the query configuration can provide at runtime. Refer to thevariableblock reference for configuration details.locals: Add thelocalsblock to your query file to define temporary variables scoped to the query configuration. Refer to thelocalsblock reference for configuration details.
Specify a custom provider configuration
The query file checks the main.tf configuration for provider configurations, but you can also declare one or more provider blocks in the query configuration file to define alternate provider configurations. To use one of the alternate provider configurations, add the provider argument to your list block and reference the name of the provider configuration. Refer to the provider block reference for information about how to configure provider blocks.
Query the infrastructure
After configuring the query configuration, you can search for resources using the Terraform CLI or using HCP Terraform if applicable.
HCP Terraform
To run queries from the HCP Terraform UI, you must configure a connnection to HCP Terraform and copy configuration files from your working directory to your workspace in HCP. Refer to Connect to HCP Terraform for instructions.
If HCP Terraform is connected to your version control system (VCS), you can also check your configurations into your VCS before running the query in HCP Terraform. Refer to Connect to VCS Providers for more information.
You can start remote queries using the Terraform CLI connected to a workspace with remote or agent execution, or run queries in the HCP Terraform UI. Refer to Import existing resources to state in the HCP Terraform documentation for instructions on how to run queries and import resources from the UI.
Terraform CLI
Run the terraform query command to retrieve the resource types specified in your list blocks. The command prints the results to your console. By default, each result includes the following information:
- Reference to the
listblock that queried for resources formatted aslist.<type>.<label>. - Identity of a discovered resource.
The provider may also include other information, such as a description of the resource. Refer to your provider documentation for details.
The number of results depends on the provider, as well as any query constraints you configured in the query configuration file.
To generate machine-readable results, you can include the -json flag:
$ terraform query -json
Evaluate policies before import
HCP Terraform evaluates Terraform policies against configuration it generates from discovered resource data. After you configure remote policy evaluation, set include_resource = true in your list blocks to supply policy input. Then run the query with a directory in your configuration that contains policy files:
$ terraform query -policies=./policies
This command evaluates policies without writing a .tf file. HCP Terraform automatically evaluates applicable Terraform policy sets configured for your workspace, including inherited project and organization-wide assignments, so you can omit -policies to use workspace policies without explicit directories.
To evaluate policies and write importable configuration, use an output file that does not exist:
$ terraform query -policies=./policies -generate-config-out=generated.tf
The -generate-config-out option requests full resource data even when you omit include_resource and writes importable configuration to your workstation. The -policies flag alone does not request resource data. Additional resource reads can increase query duration.
Review the CLI policy results and diagnostics before selecting resources to import. Query-time results are informational and do not block import or replace plan-time enforcement. Missing attributes and incomplete relationship data can prevent a policy from determining an outcome, so these results do not provide a complete policy compliance assessment.
To use the HCP Terraform UI, refer to Search and import resources in HCP Terraform for configuration-generation and policy-evaluation controls.
Generate configuration for importing results
To generate configuration, run the terraform query command and add the -generate-config-out flag. The flag expects a path to a file that does not exist, such as generated.tf. The file contains the resource and import blocks, including resource identities, necessary for importing results. If you already generated this file while evaluating policies, review it before continuing to import.
The following example generates configuration to the working directory:
$ terraform query -generate-config-out=generated.tf
Even when connected to HCP Terraform or Terraform Enterprise, Terraform creates the generated.tf file and stores it on the local workstation when running the terraform query command with the -generate-config-out flag.
After generating the results file, you must remove the file before rerunning the command to generate a new results file. Rerunning the command when a generated.tf already exists at the specified path results in an error.
Import resources
Copy the import and resource blocks from the generated.tf file to your main.tf configuration and run the terraform apply command to import the resources.
When you import resources into the same HCP Terraform workspace, HCP Terraform evaluates the workspace's policies again against the import plan. This evaluation does not change the earlier query's policy results.
Next steps
You can discard the generated.tf file after importing your resources. You can either remove import blocks after you've imported them or leave them in your configuration as a record of the resource's origin for future module maintainers. For more information on maintaining configurations over time, refer to Refactoring.