Introduction
After importing an existing resource into Terraform state, you must create a corresponding resource block in your configuration. Terraform provides functionality to help generate this configuration. The method for doing so differs based on your version of Terraform.
Expected Outcome
You will have a valid Terraform configuration file for a resource that was previously imported into the Terraform state.
Procedure
This guide uses a manually created AWS EC2 instance as an example resource to import and generate configuration for.
Option 1: For Terraform versions before 1.5
This method uses the terraform state show command to print the resource's attributes, which you can then use to build your configuration.
-
Create a minimal resource block in your configuration file to serve as a target for the import.
resource "aws_instance" "web" {} -
Import the existing EC2 instance into the Terraform state, referencing the resource block you just created. For more details, refer to the Terraform
importcommand documentation.$ terraform import aws_instance.web i-0cfc7230a4cf634b5
The output confirms a successful import.
aws_instance.web: Importing from ID "i-0cfc7230a4cf634b5"... aws_instance.web: Import prepared! Prepared aws_instance for import aws_instance.web: Refreshing state... [id=i-0cfc7230a4cf634b5] Import successful!
-
Use the
terraform state showcommand to display the full configuration of the imported resource as it exists in the state.$ terraform state show aws_instance.web
- Copy the output from the previous command and replace the minimal resource block from step 1. The output will contain many read-only attributes that are not configurable.
-
Run
terraform plan. The plan will fail with errors for attributes that are computed or cannot be set in the configuration.Error: Invalid or unknown key Error: Conflicting configuration arguments Error: Value for unconfigurable attribute
- Remove the attributes that caused errors from your resource block. Continue running
terraform planand removing attributes until the plan succeeds. -
After removing all non-configurable attributes, run
terraform planagain to verify that no changes are needed.$ terraform plan
aws_instance.web: Refreshing state... [id=i-0cfc7230a4cf634b5] No changes. Your infrastructure matches the configuration.
-
Optionally, you can further simplify the configuration by removing attributes that are set to their default values. Refer to the provider documentation for the resource to identify default values. A minimal configuration might look like this.
resource "aws_instance" "web" { ami = "ami-062550af7b9fa7d05" instance_type = "t2.micro" tags = { Name = "HelloWorld" } }
Option 2: For Terraform versions 1.5 and later
Terraform 1.5 introduced import blocks and a -generate-config-out flag for the plan command, which automates configuration generation.
-
Add an
importblock to a configuration file (e.g.,imports.tf). Specify the resource ID and the target resource address.import { # ID of the cloud resource # Check provider documentation for importable resources and format id = "i-0cfc7230a4cf634b5" # Resource address to = aws_instance.web } -
Run
terraform planwith the-generate-config-outflag to create a new file containing the generated configuration.$ terraform plan -generate-config-out=web_instance.tf
The generated code may contain conflicting or non-configurable attributes, resulting in warnings or errors.
Planning failed. Terraform encountered an error while generating this plan. ╷ │ Warning: Config generation is experimental │ │ Generating configuration during import is currently experimental, │ and the generated configuration format may change in future versions. ╵ ╷ │ Error: Conflicting configuration arguments │ │ with aws_instance.web, │ on web_instance.tf line 14: │ (source code not available) │ │ "ipv6_address_count": conflicts with ipv6_addresses ╵
-
Edit the generated file (
web_instance.tf) and remove or comment out the attributes causing errors.# ipv6_address_count = 0 # ipv6_addresses = []
-
Run
terraform planagain to confirm the import will proceed without errors.$ terraform plan
Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.
-
Run
terraform applyto perform the import and update the state file.$ terraform apply
Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed.
- Once the import is complete, you can remove the
importblock from your configuration.