|
1 | 1 | --- |
2 | | -page_title: Import existing resources into Terraform state |
3 | | -description: Learn how to import existing resources into Terraform state so that you can manage them as code |
| 2 | +page_title: Import resources overview |
| 3 | +description: Learn about importing existing infrastructure resources to your Terraform workspace using the bulk import workflow or the single-resource import workflow |
4 | 4 | --- |
5 | 5 |
|
6 | | -# Import an existing resource |
| 6 | +# Import resources overview |
7 | 7 |
|
8 | | -You can import existing infrastructure resources into your Terraform state so that you can begin managing them using Terraform. This page describes how to write Terraform configuration for importing resources, which lets you import multiple resources at the same time and review the import as part of your Terraform workflow. |
| 8 | +If you have existing infrastructure resources, you can import them to your Terraform workspace so that you can begin managing the resources as code. |
9 | 9 |
|
10 | | -> **Hands-on:** Try the [State Import](/terraform/tutorials/state/state-import?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. |
| 10 | +## Workflows |
11 | 11 |
|
12 | | - |
13 | | -## Overview |
14 | | - |
15 | | -When you import existing infrastructure into state, you must also define the Terraform configuration corresponding to that resource to manage the rest of its lifecycle. You can manually write all of the configuration or use the Terraform CLI to generate configuration for resources your are importing. When you import resources, Terraform pulls all of the resource's attributes into the state file, but you do not need to define all of them in the `resource` block. |
16 | | - |
17 | | -We recommend manually writing the `resource` block when you know how to configure all or most of the resource's arguments. Use generated configuration when importing multiple resources or a single complex resource that you do not already have the configuration for. |
18 | | - |
19 | | -This page describes how to manually write all of your import configuration. Refer to [Generate configuration](/terraform/language/import/generating-configuration) for instructions on how to generate the configuration. |
20 | | - |
21 | | -Complete the following steps to import resources: |
22 | | - |
23 | | -1. Define a destination resource configuration for each resource you want to import. |
24 | | -1. Add a corresponding `import` block for each existing resource you want to import. |
25 | | -1. Run `terraform plan` and verify that the import plan meets your needs. |
26 | | -1. Apply the configuration to import the resources and update your Terraform state. |
27 | | - |
28 | | -You can remove `import` blocks from your configuration after importing resources, but we recommend keeping them as an historical artifact. Refer to [Post import tasks](#post-import-tasks) for more information. |
29 | | - |
30 | | -## Define a destination resource |
31 | | - |
32 | | -Terraform reconciles your configuration and state to create an execution plan. As a result, you must define a `resource` block for any resource in state to prevent Terraform from destroying it. The only required arguments to the `resource` block for an imported resource are the inline resource type and resource label, which form the Terraform state address. |
33 | | - |
34 | | -The following example resource is the destination for an AWS instance with a resource address of `aws_instance.example`: |
35 | | - |
36 | | -```hcl |
37 | | -resource "aws_instance" "example" { |
38 | | - name = "renderer" |
39 | | -} |
40 | | -``` |
41 | | - |
42 | | -You should include provider-specific resource arguments that have non-default values to prevent Terraform from destroying the imported resource on the next apply operation. Terraform uses default values for arguments you do not include in the `resource` block. If Terraform assigns default values, but the existing resource has non-default attributes, the resource in state will not match the actual infrastructure, and Terraform will plan to update the resource on the next apply operation. Refer to the provider documentation for information about which arguments the resource you are importing supports. |
43 | | - |
44 | | - |
45 | | -### Configure Terraform arguments |
46 | | - |
47 | | -You can include [meta-arguments](/terraform/language/meta-arguments) to modify how Terraform manages your resources once imported into state. Meta-arguments are Terraform-specific arguments that establish explicit dependencies between resources and prevent destructive operations. Refer the [`resource` block reference](/terraform/language/block/resource) for details about Terraform meta-arguments you can define. |
48 | | - |
49 | | -## Define an `import` block |
50 | | - |
51 | | -Add an `import` block and specify the ID of an existing resource and [destination resource address](#define-a-destination-resource) to import to. Cloud providers use different methods of identifying resources. As a result, the ID depends on your cloud vendor and the kind of resource you are importing. Refer to the provider documentation for the resource you want to import for details. |
52 | | - |
53 | | -Use the following syntax to configure the `import` block: |
| 12 | +Importing unmanaged resources to your workspace requires an `import` block that specifies the unique infrastructure resource ID to import. The block also declares an address for the imported resource in state. Additionally, you must create a destination `resource` block that matches the address declared in the `import` block. The `resource` block represents the resource in the configuration. |
54 | 13 |
|
55 | | -```hcl |
56 | | -import { |
57 | | - to = TYPE.LABEL |
58 | | - id = "<RESOURCE-ID>" |
59 | | -} |
60 | | -
|
61 | | -resource "<TYPE>" "<LABEL>" { |
62 | | - # ... |
63 | | -} |
64 | | -``` |
65 | | - |
66 | | -The `to` argument is the destination resource address, which is formed from the resource type and label. |
67 | | - |
68 | | -The `id` argument is an identifier specific to your cloud provider. |
69 | | - |
70 | | -Refer to the [`import` block reference](/terraform/language/block/import) for details. |
71 | | - |
72 | | - |
73 | | -### Import multiple instances |
74 | | - |
75 | | -You can configure the destination `resource` block to manage multiple instances of resource using the `count` and `for_each` [meta-arguments](/terraform/language/meta-arguments). You can add a parameter to the value of the `to` argument to specify which instance of the destination resource to import to. |
76 | | - |
77 | | -For example, the `count` block in the destination `resource` block configuration instructs Terraform to import a set number of resource instances. As a result, you can include an index to the `to` argument value to specify which instance to import the resource to. |
78 | | - |
79 | | -In the following example, Terraform imports the resource into the instance at the `0` index: |
80 | | - |
81 | | -```hcl |
82 | | -import { |
83 | | - to = aws_instance.example[0] |
84 | | - id = "i-abcd1234" |
85 | | -} |
86 | | -
|
87 | | -resource "aws_instance" "example { |
88 | | - count = 2 |
89 | | - #. . . |
90 | | -} |
91 | | -``` |
92 | | - |
93 | | -When the destination `resource` block contains a `for_each` argument, Terraform loops through a set of key-value pairs and imports an instance for each pair. In the following example, Terraform imports the resource into the instance with a `env` key: |
94 | | - |
95 | | -```hcl |
96 | | -import { |
97 | | - to = aws_instance.example["env"] |
98 | | - id = "i-abcd1234" |
99 | | -} |
100 | | -
|
101 | | -resource "aws_instance" "example" { |
102 | | - ami = "ami-12345678" |
103 | | - instance_type = "t2.micro" |
104 | | - for_each = { |
105 | | - env = "staging" |
106 | | - geo = "us" |
107 | | - } |
108 | | - # . . . |
109 | | -} |
110 | | -``` |
111 | | - |
112 | | -### Import using a custom resource provider |
113 | | - |
114 | | -By default, Terraform automatically selects the default provider configuration based on the resource type, but you can configure multiple instances of the same provider with aliases and use a non-default provider configuration to import specific resources. In the following example, Terraform imports to a destination `resource` block that contains multiple instances according to the `europe` provider configuration: |
115 | | - |
116 | | -```hcl |
117 | | -provider "aws" { |
118 | | - alias = "europe" |
119 | | - region = "eu-west-1" |
120 | | -} |
121 | | -
|
122 | | -import { |
123 | | - provider = aws.europe |
124 | | - to = aws_instance.example["env"] |
125 | | - id = "i-abcd1234" |
126 | | -} |
127 | | -
|
128 | | -resource "aws_instance" "example" { |
129 | | - provider = aws.europe |
130 | | - for_each = { |
131 | | - env = "staging" |
132 | | - geo = "us" |
133 | | - } |
134 | | -} |
135 | | -``` |
136 | | - |
137 | | -### Import to a module |
138 | | - |
139 | | -When the destination `resource` block is in another module, add the `module.<MODULE-NAME>` prefix to the resource address. In the following example, Terraform imports a resource into a `resource` block in the `instances` module: |
140 | | - |
141 | | - |
142 | | -<CodeBlockConfig filename="main.tf"> |
143 | | - |
144 | | -```hcl |
145 | | -import { |
146 | | - to = module.instances.aws_instance.example |
147 | | - id = "i-abcd1234" |
148 | | -} |
149 | | -``` |
150 | | - |
151 | | -</CodeBlockConfig> |
152 | | - |
153 | | -The following resource appears in the module address specified with the `to` argument in the `import` block: |
154 | | - |
155 | | -<CodeBlockConfig filename="instances/main.tf"> |
156 | | - |
157 | | -```hcl |
158 | | -resource "aws_instance" "example" { |
159 | | - # . . . |
160 | | -} |
161 | | -``` |
162 | | - |
163 | | -</CodeBlockConfig> |
164 | | - |
165 | | -## Plan and apply an import |
| 14 | +You can import single resources or small batches of resources or create queries to discover large sets of unmanaged resources to import them in bulk. |
166 | 15 |
|
167 | | -After configuring the destination `resource` block and the `import` block, run `terraform plan` and review the proposed plan. If Terraform proposes any unexpected changes to the resource, update its configuration until it matches your intended settings. When satisfied with the plan, run `terraform apply` to import the resources and update your state. |
| 16 | +### Import resources in bulk |
168 | 17 |
|
169 | | -When you apply a configuration with `import` blocks, Terraform records that it imported the resources and that it did not create them. |
| 18 | +When you need to identify and import large sets of infrastructure resources, you can define queries as HCL, add the results to your Terraform configuration, and use the `terraform apply` command to import the discovered resources into your workspace. Refer to [Import resources in bulk](/terraform/language/import/bulk) for more information. |
170 | 19 |
|
171 | | -Because the `import` block is idempotent, applying an import action and running another plan does not generate another import action as long as that resource remains in your state. Furthermore, attempting to import a resource into the same address more than once has no impact. |
| 20 | +### Import individual resources |
172 | 21 |
|
173 | | -## Post import tasks |
| 22 | +The workflow for importing single resources or small batches of resources works best when you can easily access unique infrastructure resource IDs and other attributes from your cloud provider. In this workflow, manually write `import` and `resource` blocks and run the `terraform apply` command to import the resources. |
174 | 23 |
|
175 | | -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](/terraform/language/modules/develop/refactoring). |
| 24 | +Alternatively, you can write only the `import` block and run the `terraform apply` command with the `generate-config` flag to generate the `resource` blocks. Refer to [Import a single resource](/terraform/language/import/single) for more information. |
0 commit comments