Terraform Import Guide: Import Existing Resources
Most teams don't start with a clean Infrastructure as Code environment.
It's common to inherit AWS resources that were created manually through the console, provisioned by scripts, or managed by other tools. EC2 instances, S3 buckets, IAM roles, and databases often exist long before Terraform is introduced.
This Terraform Import Guide explains how to bring existing infrastructure under Terraform management without recreating resources. You'll learn how terraform import works, how it interacts with Terraform state, and how to avoid common mistakes that can lead to configuration drift.
If you're new to Terraform, start with our guide on Getting Started with Terraform and AWS.
Why Terraform Import Matters
Terraform is designed to manage infrastructure through code. Under normal circumstances, resources are created and tracked by Terraform from the beginning.
In real-world environments, that isn't always possible.
You may need to:
- Adopt existing infrastructure into Terraform.
- Migrate from manual cloud management.
- Transition from another Infrastructure as Code tool.
- Standardize resource management across teams.
- Reduce operational risk by bringing unmanaged resources under version control.
Terraform Import solves this problem by associating existing infrastructure with Terraform state so Terraform can manage it moving forward.
How Terraform Import Works Behind the Scenes
Terraform tracks managed resources in a state file.
If Terraform does not know a resource exists, it cannot manage, update, or destroy that resource. That's why understanding the Terraform state file is essential before using imports.
When you run terraform import, Terraform:
- Locates the existing resource using its unique identifier.
- Associates that resource with a Terraform resource address.
- Stores the mapping inside Terraform state.
- Allows future Terraform operations to manage that resource.
It's important to understand one detail:
Terraform Import updates state. It does not automatically create a complete Terraform configuration.
For official behavior and provider-specific import requirements, see the Terraform Import Documentation.
Terraform Import Command Syntax
The basic syntax is:
terraform import <resource_type>.<resource_name> <resource_id>
Example:
terraform import aws_instance.webserver i-1234567890abcdef
In this example:
aws_instanceis the Terraform resource type.webserveris the local resource name.i-1234567890abcdefis the AWS EC2 instance ID.
Provider-specific resource identifiers can vary. Always verify the correct import format in the relevant provider documentation on the Terraform Registry.
Terraform Import Tutorial: Step-by-Step Example
Imagine your team already has an EC2 instance running in AWS that was created manually.
Instead of recreating it, you can import it into Terraform and begin managing it through code.
Step 1: Identify the Existing Resource
Locate the resource you want to import.
For AWS resources, the identifier can usually be found in the AWS Management Console.
Examples include:
- EC2 Instance ID
- S3 Bucket Name
- IAM Role Name
- VPC ID
- Security Group ID
For EC2:
i-1234567890abcdef
Step 2: Create a Resource Block
Before importing, Terraform requires a matching resource block.
Create a minimal configuration:
resource "aws_instance" "webserver" {}
Terraform uses this resource address during the import process.
Step 3: Run the Terraform Import Command
Execute:
terraform import aws_instance.webserver i-1234567890abcdef
If successful, Terraform will add the resource mapping to the state file.
Step 4: Inspect the Imported Resource
After importing, inspect what Terraform recorded.
A practical command many engineers use immediately after import is:
terraform state show aws_instance.webserver
You can learn more about state management in our guide to Terraform state commands.
This command displays the attributes Terraform captured during the import process.
Step 5: Complete the Resource Configuration
Terraform does not automatically generate a complete configuration for imported resources.
You must define the resource attributes so the configuration matches reality.
Example:
resource "aws_instance" "webserver" {
ami = "ami-0abcd1234ef567890"
instance_type = "t3.micro"
key_name = "web-key"
vpc_security_group_ids = [
"sg-0abc12345def6789"
]
}
Use:
- AWS Console
- Provider documentation
- Terraform state output
to identify the correct configuration values.
Step 6: Run Terraform Plan
Validate the imported resource:
terraform plan
Ideally, Terraform should report:
No changes. Your infrastructure matches the configuration.
If Terraform proposes modifications, review the configuration carefully.
A large plan after import often indicates that the configuration does not yet match the imported infrastructure.
Step 7: Manage the Resource Normally
Once the configuration and state are synchronized, the resource behaves like any Terraform-managed resource.
You can:
- Update it with
terraform apply - Review changes with
terraform plan - Remove it with
terraform destroy - Reference it in modules
- Use it in dependencies and outputs
For a broader overview, see our guide on Terraform commands explained.
Common Terraform Import Pitfalls to Avoid
Terraform Import Does Not Generate Code
One of the most common misunderstandings is expecting Terraform Import to create a complete resource definition automatically.
Importing only updates state.
You are responsible for maintaining a matching Terraform configuration.
Without matching configuration, Terraform will detect differences and may attempt unwanted changes during future deployments.
Configuration Drift After Import
Configuration drift occurs when the actual resource differs from the Terraform configuration.
Common causes include:
- Missing attributes
- Incorrect resource arguments
- Provider defaults not represented in code
- Manual infrastructure changes
Always review the output of:
terraform plan
before applying changes.
Incorrect Resource Identifiers
Every provider uses specific import identifiers.
For example:
- AWS EC2 uses instance IDs.
- AWS IAM roles use role names.
- AWS S3 buckets use bucket names.
Using the wrong identifier format will cause import failures.
Verify import requirements in the provider documentation.
Importing Production Resources Without Backups
Before importing critical infrastructure:
- Back up your state.
- Review permissions.
- Validate provider versions.
- Test in a non-production environment when possible.
Version Compatibility Considerations
Terraform Import behavior depends on:
- Terraform version
- Provider version
- Resource type
Always verify compatibility before importing resources into production environments.
Use version constraints to prevent unexpected provider upgrades.
You can learn more in our guide on Version Constraints in Terraform.
Best Practices for Terraform Import
Back Up Terraform State
Always create a backup before importing resources.
If you're using remote state, ensure proper locking is configured.
Read our guide on remote state and state locking in Terraform.
Use Meaningful Resource Names
Avoid generic names such as:
resource "aws_instance" "server1"
Prefer descriptive names:
resource "aws_instance" "production_web_server"
This improves readability and long-term maintenance.
Validate Configuration Before Applying Changes
Run:
terraform validate
terraform plan
before making modifications to imported resources.
Document Imported Resources
Document:
- Why the resource was imported
- When it was imported
- Who performed the import
- Any special considerations
This helps future maintainers understand the infrastructure history.
Real-World Example: Importing an Existing S3 Bucket
Suppose a bucket already exists:
company-logs-prod
Create a resource block:
resource "aws_s3_bucket" "logs" {}
Import the bucket:
terraform import aws_s3_bucket.logs company-logs-prod
Then complete the configuration and verify the result using:
terraform plan
If you work with S3 resources frequently, see our guide on AWS S3 with Terraform.
When Should You Use Terraform Import?
Terraform Import is useful when:
- Adopting existing infrastructure.
- Migrating manually created cloud resources.
- Consolidating infrastructure management.
- Standardizing Infrastructure as Code practices.
- Bringing legacy resources under version control.
It is generally not necessary when Terraform originally created the resource.
Frequently Asked Questions
What does Terraform Import do?
Terraform Import associates an existing resource with Terraform state so Terraform can manage that resource moving forward.
Does Terraform Import create resources?
No.
Terraform Import does not create infrastructure. It only records existing infrastructure in Terraform state.
Can I import resources without a resource block?
No.
Terraform requires a resource address in your configuration before importing a resource.
Does Terraform automatically generate configuration?
No.
Terraform records resource information in state, but you must define and maintain the resource configuration yourself.
Can imported resources be destroyed by Terraform?
Yes.
After import and configuration synchronization, imported resources are managed like any other Terraform resource and can be modified or destroyed through Terraform operations.
How do I verify an imported resource?
Use:
terraform state show <resource_address>
and:
terraform plan
to confirm that Terraform state and configuration are aligned.
Final Thoughts
Terraform Import is one of the most important migration tools available in Terraform.
It allows teams to adopt Infrastructure as Code incrementally instead of rebuilding existing environments from scratch. When combined with good state management practices, proper configuration reviews, and version-controlled infrastructure, Terraform Import becomes a safe and reliable way to bring legacy resources under Terraform management.
8 free, 100% client-side tools for developers — no signup, no data uploads.
Explore all tools