A bucket and a queue
The queue is the interesting one: it imports by URL, not by name and not by ARN
resource "aws_s3_bucket" "logs" {
bucket = "my-logs"
}
resource "aws_sqs_queue" "jobs" {
name = "jobs"
} Generate import blocks from resource blocks. The id cannot be derived from your configuration, because it identifies the object in your cloud account, so this names the format instead of guessing the value.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Generate. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
The queue is the interesting one: it imports by URL, not by name and not by ARN
resource "aws_s3_bucket" "logs" {
bucket = "my-logs"
}
resource "aws_sqs_queue" "jobs" {
name = "jobs"
}One import block is not enough, and the error will not mention the missing key
resource "aws_subnet" "private" {
for_each = var.subnets
vpc_id = var.vpc_id
}These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
The id is whatever the provider uses to identify the object. A security group takes sg-..., not the group name, and the failure comes back from the cloud API as not-found.
Instead:Check the Import section at the bottom of the provider's documentation page for that resource type.
An import block targets a single instance, so an unindexed address refers to a resource that does not exist and the error does not mention the missing key.
Instead:Write one block per key, with to = aws_subnet.private["that-key"].
It writes to state immediately with no plan to review, so a wrong id or a wrong address is discovered after the fact.
Instead:Use import blocks on 1.5 or later. plan shows exactly what would be imported before anything changes.
The difference is the whole reason to use them. terraform import mutates state immediately with nothing to review; an import block shows up in plan and changes nothing until apply.
An S3 bucket imports by bucket name, an EC2 instance by i-0123..., a security group by sg-... rather than by group name, an IAM role by role name while an IAM policy takes an ARN, and an SQS queue by queue URL rather than by name or ARN. Getting it wrong produces a not-found from the cloud API rather than a Terraform error, so it reads like a permissions problem.
An import block targets one object. to = aws_subnet.private with a for_each on the resource refers to something that does not exist, and the error names the address rather than the missing key. Write one block per key or index.
Point it at a file and Terraform emits resource blocks matching what it found, which saves transcribing forty arguments by hand. The output needs reconciling: it is exhaustive rather than idiomatic, and it includes computed values you do not want to declare.
A second apply sees the resource already in state and does nothing. Some teams remove them so the configuration describes only desired state; others keep them as a record. Both are fine, and drifting between the two is what causes arguments.
A resource inside a module imports to module.network.aws_subnet.private, not to aws_subnet.private. Import blocks live in the root module and the address is absolute.
Before that, the only option is terraform import, one resource at a time, with no plan and no dry run. If you are importing more than a handful of resources, the upgrade pays for itself immediately.