Transform manually-created AWS resources into version-controlled Terraform code without recreating them.
Your team has been creating AWS resources through the console for months or years. You now need to:
This guide shows how to use ops0's Discovery feature to scan, import, and manage existing resources.
ops0 discovers resources across these categories:
| Category | Resources |
|---|---|
| Compute | EC2 instances, Auto Scaling groups, Lambda functions |
| Networking | VPCs, subnets, security groups, NAT gateways, load balancers |
| Storage | S3 buckets, EBS volumes, EFS file systems |
| Database | RDS instances, DynamoDB tables, ElastiCache clusters |
| Security | IAM roles, policies, KMS keys |
| Containers | ECS clusters, EKS clusters, ECR repositories |
After the scan completes, you'll see a list of all discovered resources.
| Status | Meaning |
|---|---|
| Unmanaged | Resource exists in AWS but not in any Terraform state |
| Managed | Resource is already tracked by an ops0 project |
| Drifted | Resource differs from Terraform state (manual change detected) |
Use filters to focus on what matters:
Not all resources need to be imported immediately. Start with a logical group:
Select resources by clicking the checkbox next to each one, or use Select All for the filtered view.
With resources selected, click Create Terraform.
ops0 will:
For an EC2 instance:
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.medium"
subnet_id = aws_subnet.private_1a.id
vpc_security_group_ids = [
aws_security_group.web.id
]
root_block_device {
volume_size = 50
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "web-server"
Environment = "production"
}
}
ops0 highlights potential issues:
• Hardcoded AMI IDs (consider using data sources)
• Missing lifecycle rules (prevent accidental destruction)
• Secrets in environment variables (move to Secrets Manager)
This is the critical step - importing resources into Terraform state without recreating them.
terraform import for each resourceImporting aws_vpc.main...
terraform import aws_vpc.main vpc-0123456789abcdef
Import successful!
Importing aws_subnet.private_1a...
terraform import aws_subnet.private_1a subnet-0123456789abcdef
Import successful!
Importing aws_instance.web_server...
terraform import aws_instance.web_server i-0123456789abcdef
Import successful!
Import complete: 3 resources imported
After import, run a Terraform plan to confirm the code matches reality:
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.
If there are differences, ops0's AI can help you fix the Terraform code to match the live resource exactly.
Now that resources are managed, detect future manual changes:
When drift is detected, you can:
The resource is already in another Terraform state. Check:
Common causes:
| Issue | Solution |
|---|---|
| Default values | AWS adds defaults that weren't in original config. Add them explicitly to Terraform. |
| Computed attributes | Some attributes are computed. Add lifecycle { ignore_changes = [...] }. |
| Order differences | Lists may be in different order. Sort them in Terraform. |
For 100+ resources:
prevent_destroy = true to avoid accidents.