Skip to content

How to bring an unmanaged resource under Terraform

Turn a resource that exists in your cloud but is tracked by no Terraform configuration into a pull request that adopts it. Cloudkeel-DD generates the import {} block and opens the PR; you review and merge it.

This is how you burn down unmanaged resources rather than just counting them.

  • An account with the ADMIN or OWNER role.
  • An unmanaged-resource finding for a resource whose type is supported (see Limits below).
  • Terraform 1.5 or newer in the target repository - import {} blocks do not exist before 1.5.
  • A GitHub or GitLab token configured on your deployment, if you want Cloudkeel-DD to open the PR for you. Without one you can still generate the patch and apply it by hand.

The UI calls this action remediation - “codify” is the internal name for what happens when the resource being remediated is unmanaged: instead of a diff to revert, Cloudkeel-DD generates a Terraform import {} block to adopt it.

  1. Open the resource behind the unmanaged finding (from the drift event, follow View full diff & remediation →, or open the resource directly).

  2. On that finding, click Create remediation PR. You will be prompted for the provider (github or gitlab) and the target repository. Cloudkeel-DD builds the patch from the live payload it captured during the scan, not from a fresh read - so the block reflects the resource as it was when detected.

  3. The generated block looks like this and contains nothing else:

    import {
    to = aws_security_group.example
    id = "sg-0123456789abcdef0"
    }
  4. What happens next depends on severity. A critical finding stops at “Awaiting approval” - use the Approve button to release it. Anything lower opens the pull request straight away. (No GitHub/GitLab token configured on the deployment? The create step fails; apply the block by hand instead.)

  5. In the PR, run the step the body tells you to run:

    Terminal window
    terraform plan -generate-config-out=generated.tf

    This is what produces the actual resource configuration. Cloudkeel-DD deliberately does not synthesise a resource body - see below.

  6. Review the generated config, commit it alongside the import block, and merge.

  7. Re-scan. The resource should now be tracked, and the unmanaged finding resolves.

Generating a full resource body means guessing at every field, and a confident-looking wrong body is worse than no body: it produces a plan that quietly changes real infrastructure on the next apply.

terraform plan -generate-config-out= is Terraform’s own supported path for this, it uses the real provider schema, and it runs on your machine against your state. So Cloudkeel-DD generates the part it can be certain about - the import block and its id - and hands the rest to the tool that does it properly.

  • Unsupported types fail explicitly. If Cloudkeel-DD cannot construct a correct import id for a resource type, codify refuses rather than emitting a block that would import the wrong thing. You will see a “not supported” error naming the type.
  • A finding with no captured live payload cannot be codified. You will get a 422. Re-scan to capture one.
  • azurerm_role_assignment has a cross-tenant caveat. If the assigned principal belongs to a different Azure AD tenant, the generated import id can be wrong. Cloudkeel-DD has no signal for the principal’s tenant, so the PR body carries the caveat and a human must check. Read it before merging.

After merging and re-scanning, the resource should appear as managed rather than unmanaged. Track the trend across your estate with the codify-progress report:

Terminal window
curl -s -H "Authorization: Bearer $TOKEN" \
https://<your-d-detective-host>/api/reports/codify-progress
SymptomCauseFix
422 “no captured live payload”The finding predates payload capture, or the scan did not store oneRe-scan, then retry
“not supported” for the typeNo import-id strategy exists for that typeImport it by hand; the block is three lines
PR not createdNo GitHub/GitLab token configuredApply the patch manually, or ask an admin to configure one
terraform plan rejects importTerraform older than 1.5Upgrade, or write an equivalent terraform import command
Plan wants to change the resourceThe generated config does not match reality yetReconcile the generated config before merging - do not apply