---
page_title: 'Plugin Development - Framework: Resource Import'
description: >-
  How to support resource import using the provider development framework.
---

# Resource Import

Practitioners can use the  [`terraform import` command](/terraform/cli/commands/import) to let Terraform begin managing existing infrastructure resources. Resources can implement the `ImportState` method, which must either specify enough Terraform state for the `Read` method to refresh [`resource.Resource`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#Resource) or return an error.

## Define Resource ImportState Method

The [`resource.ResourceWithImportState` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ResourceWithImportState) on the [`resource.Resource` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#Resource) implementation will enable practitioner support for importing an existing resource.

Implement the `ImportState` method by:

1. Accessing the import identifier from the [`resource.ImportStateRequest.ID` field](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ImportStateRequest)
1. [Writing state data](/terraform/plugin/framework/writing-state) into the [`resource.ImportStateResponse.State` field](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ImportStateResponse.State).

In this example, the resource state has the `id` attribute set to the value passed into the [`terraform import` command](/terraform/cli/commands/import) using the [`resource.ImportStatePassthroughID` function](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ImportStatePassthroughID):

```go
func (r *ThingResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
    resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
}
```

### Multiple Attributes

When the `Read` method requires multiple attributes to refresh, you must write custom logic in the `ImportState` method.

Implement the `ImportState` method by:

1. Accessing the import identifier from the [`resource.ImportStateRequest.ID` field](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ImportStateRequest)
1. Performing the custom logic.
1. [Writing state data](/terraform/plugin/framework/writing-state) into the [`resource.ImportStateResponse.State` field](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#ImportStateResponse.State).

The `terraform import` command will need to accept the multiple attribute values as a single import identifier string. A typical convention is to use a separator character, such as a comma (`,`), between the values. The `ImportState` method will then need to parse the import identifier string into the multiple separate values and save them appropriately into the Terraform state.

In this example, the resource requires two attributes to refresh state and accepts them as an import identifier of `attr_one,attr_two`:

```go
func (r *ThingResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        Attributes: map[string]schema.Attribute{
            "attr_one": schema.StringAttribute{
                Required: true,
            },
            "attr_two": schema.StringAttribute{
                Required: true,
            },
            /* ... */
        },
    }
}

func (r *ThingResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
    var attrOne, attrTwo string

    resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("attr_one"), &attrOne)...)
    resp.Diagnostics.Append(req.State.GetAttribute(ctx, path.Root("attr_two"), &attrTwo)...)

    if resp.Diagnostics.HasError() {
        return
    }

    // API call using attrOne and attrTwo
}

func (r *ThingResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
    idParts := strings.Split(req.ID, ",")

    if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
        resp.Diagnostics.AddError(
            "Unexpected Import Identifier",
            fmt.Sprintf("Expected import identifier with format: attr_one,attr_two. Got: %q", req.ID),
        )
        return
    }

    resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("attr_one"), idParts[0])...)
    resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("attr_two"), idParts[1])...)
}
```

## Not Implemented

If the resource does not support `terraform import`, skip the `ImportState` method implementation.

When a practitioner runs `terraform import`, Terraform CLI will return:

```console
$ terraform import example_resource.example some-identifier
example_resource.example: Importing from ID "some-identifier"...
╷
│ Error: Resource Import Not Implemented
│ 
│ This resource does not support import. Please contact the provider developer for additional information.
╵
```
