Terraform 1.5+ introduced import blocks as a declarative way to bring existing infrastructure under Terraform management. This replaces the older terraform import CLI approach.
Import blocks are defined in infrastructure/terraform/imports.tf:
import {
id = "<RESOURCE_ID>"
to = <RESOURCE_TYPE>.<RESOURCE_NAME>
}| Resource | ID Format | Example |
|---|---|---|
| VPC | vpc-xxxxxxxx | vpc-12345678 |
| Subnet | subnet-xxxxxxxx | subnet-12345678 |
| EKS Cluster | cluster-name | gistpin-eks-cluster |
| RDS Instance | db-instance-id | gistpin-db-prod |
| S3 Bucket | bucket-name | gistpin-terraform-state |
| DynamoDB Table | table-name | gistpin-terraform-locks |
| IAM Role | role-name | eks-node-role |
| Security Group | sg-xxxxxxxx | sg-12345678 |
| ALB | arn:aws:elasticloadbalancing:... | Full ARN |
| Route53 Record | zone-id_record-name_type | Z1234567890ABCDEFGHIJ_gistpin.io_A |
Ensure a matching resource block exists in .tf files:
resource "aws_s3_bucket" "terraform_state" {
bucket = "gistpin-terraform-state"
}Add an import block in imports.tf:
import {
id = "gistpin-terraform-state"
to = aws_s3_bucket.terraform_state
}terraform plan -var="environment=staging" -generate-config-out=generated.tfReview the plan to ensure Terraform maps the resource correctly without unexpected changes.
terraform apply -var="environment=staging"terraform state list | grep aws_s3_bucket.terraform_state
terraform state show aws_s3_bucket.terraform_state- Resource exists in AWS console or via CLI
- Terraform configuration matches existing resource attributes
- No other Terraform workspace manages the same resource
- Resource can be imported without downtime
- Team notified of import operation
terraform planshows no destructive changes- Resource attributes match expected values
- State file updated correctly
- Run
bash infrastructure/scripts/validate-state.sh
| Issue | Resolution |
|---|---|
| Resource already in state | Run terraform state rm <address> before importing |
| Configuration mismatch | Update .tf to match existing resource attributes |
| Cannot import resource | Check IAM permissions for read access |
| Plan shows resource recreation | Add lifecycle { prevent_destroy = true } |
After successful import, remove the import block to prevent re-importing on future applies:
# Remove the import block for the resource
# Keep the resource definition in .tf filesfor bucket in $(aws s3api list-buckets --query 'Buckets[].Name' --output text); do
echo "import { id = \"${bucket}\"; to = aws_s3_bucket.${bucket//-/_} }"
done