Tình Huống
Khi chạy terraform import để đưa một tài nguyên AWS đang tồn tại vào quản lý bởi Terraform, lệnh thất bại ngay lập tức với thông báo:
Error: Cannot import non-existent remote object
While attempting to import an existing object to aws_instance.example,
the provider detected that no object exists with the given id.
Only pre-existing objects can be imported.
Tài nguyên trông vẫn tồn tại trên AWS console — hoặc ít nhất bạn nghĩ vậy. Lỗi này có nghĩa là provider của Terraform đã tra cứu ID bạn cung cấp nhưng không tìm thấy gì.
Nguyên Nhân
Bản thân lệnh import khá đơn giản: Terraform gọi API của cloud với ID bạn cung cấp. Nếu API không trả về kết quả, bạn sẽ gặp lỗi này. Nguyên nhân hầu như luôn là một trong những trường hợp sau:
- Sai ID tài nguyên — nguyên nhân phổ biến nhất. Mỗi loại tài nguyên có định dạng ID riêng, và nhầm lẫn giữa chúng rất dễ xảy ra.
- Sai region AWS — provider được cấu hình cho
us-east-1nhưng tài nguyên lại nằm ởap-southeast-1. - Sai tài khoản AWS — credentials trong shell trỏ đến một tài khoản khác với nơi tài nguyên được tạo.
- Tài nguyên đã bị xóa — nó tồn tại khi bạn bắt đầu viết import block nhưng đã bị dọn dẹp trước khi bạn chạy lệnh.
- Sai loại tài nguyên — cố import ID của RDS cluster vào
aws_db_instancethay vìaws_rds_cluster.
Khắc Phục Nhanh — Chẩn Đoán Trước Khi Chạy Lại
Bước 1: Xác nhận tài nguyên thực sự tồn tại
Trước khi động vào Terraform, hãy kiểm tra bằng AWS CLI:
# Với EC2 instance
aws ec2 describe-instances --instance-ids i-0abc123def456 --region us-east-1
# Với S3 bucket
aws s3api head-bucket --bucket my-bucket-name
# Với RDS instance
aws rds describe-db-instances --db-instance-identifier mydb --region us-east-1
Nếu CLI cũng không trả về gì — hoặc báo lỗi not found — tài nguyên đã biến mất. Chuyển đến phần bên dưới về cách xử lý tài nguyên đã bị xóa.
Bước 2: Kiểm tra tài khoản và region mà credentials đang dùng
aws sts get-caller-identity
aws configure get region
So sánh account ID và region với nơi tài nguyên thực sự tồn tại. Nếu không khớp, hãy chuyển profile hoặc đặt region một cách tường minh:
export AWS_PROFILE=production
export AWS_DEFAULT_REGION=ap-southeast-1
terraform import aws_instance.example i-0abc123def456
Bước 3: Kiểm tra định dạng ID cho từng loại tài nguyên
Mỗi loại tài nguyên yêu cầu một định dạng ID cụ thể. Một số trường hợp hay gây nhầm lẫn:
# EC2 instance — dùng instance ID trực tiếp
terraform import aws_instance.web i-0abc123def456
# Security group — dùng sg- ID
terraform import aws_security_group.main sg-0abc123def456
# IAM role — dùng tên role, không phải ARN
terraform import aws_iam_role.deployer my-deployer-role
# S3 bucket — dùng tên bucket
terraform import aws_s3_bucket.assets my-assets-bucket
# RDS cluster (không phải aws_db_instance!)
terraform import aws_rds_cluster.main my-cluster-id
# Subnet — dùng subnet ID
terraform import aws_subnet.private subnet-0abc123def456
Tài liệu trên Terraform registry cho mỗi tài nguyên luôn liệt kê định dạng import ID ở cuối trang trong phần Import. Hãy kiểm tra trước khi chạy lệnh.
Bước 4: Chạy lại với đầu ra chi tiết
Nếu bạn vẫn không chắc chắn điều gì đang xảy ra, hãy chạy với logging được bật để xem chính xác API call mà provider đang thực hiện:
TF_LOG=DEBUG terraform import aws_instance.example i-0abc123def456 2>&1 | grep -i "describe\|import\|error"
Đầu ra debug sẽ hiển thị chính xác API call và response, giúp bạn nhận ra ngay sự không khớp.
Xử Lý Tài Nguyên Đã Bị Xóa
Nếu tài nguyên thực sự không còn tồn tại, bạn có hai hướng xử lý:
Phương án A — Xóa import block (Terraform 1.5+ import blocks)
Nếu bạn đang dùng cú pháp import dạng HCL mới hơn, chỉ cần xóa block và cấu hình tài nguyên liên quan:
# Xóa phần này khỏi file .tf của bạn:
import {
to = aws_instance.example
id = "i-0abc123def456"
}
resource "aws_instance" "example" {
# ...
}
Phương án B — Xóa state entry nếu đã được import một phần
Đôi khi state rơi vào trạng thái import dở dang. Hãy dọn dẹp như sau:
# Kiểm tra xem nó có trong state không
terraform state list | grep example
# Xóa nếu nó đã lọt vào
terraform state rm aws_instance.example
Phương án C — Để Terraform tạo mới
Nếu bạn đã xóa import block nhưng giữ lại resource block, terraform plan sẽ hiển thị nó như một tài nguyên mới cần tạo. Đây thường là kết quả đúng khi tài nguyên gốc đã biến mất.
Khắc Phục Vĩnh Viễn — Xác Minh Trước Khi Import
Quy trình gọn nhất trước bất kỳ thao tác import nào:
#!/bin/bash
# verify-before-import.sh
RESOURCE_ID="$1"
REGION="${2:-us-east-1}"
echo "Đang kiểm tra instance $RESOURCE_ID tại $REGION..."
aws ec2 describe-instances \
--instance-ids "$RESOURCE_ID" \
--region "$REGION" \
--query 'Reservations[0].Instances[0].State.Name' \
--output text
if [ $? -ne 0 ]; then
echo "Không tìm thấy tài nguyên — không chạy terraform import"
exit 1
fi
echo "Tài nguyên tồn tại. An toàn để import."
Chạy script này trước mỗi lần import và bạn sẽ không bao giờ gặp lỗi này từ tài nguyên đã bị xóa hoặc không tồn tại nữa.
Xác Minh — Kiểm Tra Sau Khi Sửa
Sau khi sửa đúng ID hoặc region và chạy lại import:
# 1. Import phải hoàn tất mà không có lỗi
terraform import aws_instance.example i-0abc123def456
# Kết quả mong đợi: Import successful!
# 2. Kiểm tra state đã được điền đầy đủ
terraform state show aws_instance.example
# Phải hiển thị đầy đủ các thuộc tính của tài nguyên
# 3. Chạy plan — lý tưởng nhất là không có thay đổi
terraform plan
# Kết quả mong đợi: No changes. Your infrastructure matches the configuration.
Nếu terraform plan vẫn hiển thị thay đổi sau khi import, điều đó có nghĩa là cấu hình tài nguyên trong file .tf của bạn không khớp với tài nguyên thực tế. Đó là vấn đề drift riêng biệt — nhưng bản thân lỗi import đã được giải quyết.

