prerelease Prerelease stable Latest
Kumoss
prerelease Prerelease stable Latest

Import infrastructure

Bring existing, unmanaged cloud resources under Terraform management, for a specific set of resources or across a whole scope.

The Kumoss web application offers two import modes: Partial Import, for the unmanaged resources your request names, and Full Import, for every unmanaged resource in the session’s scope. Both find the resources the cloud holds but the Terraform state does not, write a resource block for each, run terraform import on them, and reconcile the imported configuration with the real resources. They differ only in how the resources are selected. This guide covers both.

Prerequisites

  • The devops operation role to select either mode in the web application; below devops both are shown disabled with the hint "Requires the devops operation role." The API itself, POST /api/v1/iac/import, requires only developer, plus ownership when it continues an existing session. See Roles and permissions for the complete role matrix.

  • A repository URL, the target cloud, and a scope id, as covered in Make a request. The scope is what discovery lists: an Azure subscription, a GCP project, or an AWS account. OCI and Kubernetes have no scope listing, so an import round on them finds nothing to import (see Limitations).

  • The IaC sidecar’s credentials must be able to read the cloud inventory for the scope: Azure Resource Graph, GCP Cloud Asset Inventory, or an AWS Resource Explorer aggregator index. See Terraform providers.

Partial import

Use case. Some resources were created by hand, or by another tool, and you want only some of them managed from the repository: "import the key vault and its private endpoint".

Required inputs. Repository URL, cloud, scope id, and a non-empty request naming what to import. The API rejects a partial import with an empty text.

Workflow.

  1. Filtering. The request filter runs in import mode and declines requests that are not about importing. A declined request ends the round uncompleted with the filter’s rationale.

  2. Prompt composition, as in generate.

  3. Discovery. The core lists what the Terraform state tracks (/v1/import/state-resource-ids) and what the cloud scope holds (/v1/import/scope-resource-ids), and keeps the resource IDs the state does not track. Azure IDs are compared case-insensitively; every other provider compares them exactly. The IaC sidecar already leaves out resources another control plane owns, such as AKS-managed resource groups or GKE nodes.

  4. Import exception list. IDs on the cloud’s <cloud>-guidelines-import_exceptions list are withheld from the rest of the round, whatever the request says. See Import exception list.

  5. Selection. The import_filter agent narrows the remaining unmanaged IDs to the ones your request names.

  6. Generate, validate and import loop, up to orchestration.max_import_iteration attempts (5 by default). Each attempt:

    1. generates or corrects the resource blocks for the selected IDs, without modifying configuration that was already there, and commits and pushes them to the session branch;

    2. runs init, validate and plan on the session’s targets;

    3. has an agent read the branch diff and pair each generated block’s Terraform address with the cloud resource ID it must be imported from, in the spelling the provider expects;

    4. runs terraform import for each pair, one address at a time, through the IaC sidecar’s /v1/import.

      If the plan fails, its error is fed back to the generator as the next attempt’s request. If any import is rejected, the generator is given every rejected address with the engine’s error, plus the addresses already imported, which it must leave unchanged. The next attempt corrects the blocks and retries only the resources that are still not imported; resources imported by an earlier attempt stay in the state. A failed plan and a rejected import each count as one attempt.

  7. Convergence. When at least one resource was imported, the round runs the drift loop of Remediate drift over the plan’s targets, up to orchestration.max_drift_reports iterations, so the generated configuration matches what was imported. Its final plan is what the report judges state alignment from.

  8. Report. An import JSON report: the selected, imported and failed counts, an outcome, an execution summary, one entry per resource with its address, ID, status and error, the resources the exception list withheld, the state alignment, and recommendations. The outcome is Succeeded when every selected resource was imported, Partial when some failed, and Failed when none was imported. Withheld resources are not failures and do not lower the outcome.

When there is nothing to import. The round still completes with an import report that says why: the scope could not be listed (with the IaC sidecar’s diagnostics), the scope holds no importable resource, every resource in it is already managed, every unmanaged resource is on the import exception list, or no unmanaged resource matched the request.

When the attempts run out. If the last attempt’s plan passed, the round goes on with what did import: convergence runs for the imported resources, and the report lists the ones that still failed, with the engine’s error for each, and reports Partial or Failed. If the last plan itself failed, the round fails and the session ends failed.

Inspects existing IaC and state. Yes: the state inventory, the cloud scope inventory, and the configuration the plan runs on.

Targets. Generated from the session’s changes, so the plan covers the imported resources.

Artifacts and reports. Plans per attempt, code-change files, drift reports from convergence, an import JSON report, a pushed branch.

State. Changed during the round. terraform import writes to the state as soon as each import succeeds, before any pull request exists; a resource imported in a round stays in the state even if the round later fails.

Plan pinned, apply, pull requests, compliance, locks. No plan is pinned and no apply follows. You can create a pull request from the branch; in the web application the merge button is labelled for merging only, and merging ends the session with "Pull Request merged. The imported resources are now managed from your repository." Import rounds run no compliance audit and never set the lock.

Example. "Import the storage account stappdev001 and the key vault kv-app-dev." Kumoss finds both among the unmanaged resources in the subscription, writes an azurerm_storage_account and an azurerm_key_vault block, and imports them. The storage account imports; the key vault is rejected because the ID was paired in a spelling the provider does not parse. The engine’s error goes back to the generator, which leaves the storage account’s block untouched, the address agent pairs the key vault again with the corrected ID, and the next attempt imports only the key vault. The report shows both resources imported and Succeeded.

Full import

Use case. Adopt everything in a scope that Terraform does not yet manage, for example when bringing an existing subscription into a repository.

Required inputs. Repository URL, cloud, and scope id. The web application asks for no request text and sends the fixed request "Import all the infrastructure".

Workflow. Identical to partial import except that the request filter and the import_filter selection are skipped: every unmanaged resource in the scope that is not on the import exception list is selected.

Inspects existing IaC and state, targets, artifacts, state, apply, compliance, locks. As for partial import.

Example. "Import all the infrastructure" on a GCP project with a bucket, a service account and one IAM binding that Terraform does not track. Kumoss selects all three, generates the blocks, imports them, and reports Succeeded.

Limitations

  • Scope discovery exists only for Azure, GCP and AWS. On OCI and Kubernetes the scope cannot be listed, and the round ends with a report that says so and imports nothing.

  • The import exception list is matched against the exact IDs the scope listing returns (case-insensitively on Azure), so an entry must be spelled the way discovery spells it.

  • Imports are bounded by orchestration.max_import_iteration. Resources still rejected when the attempts run out stay out of the state; their resource blocks stay on the branch, so review them before merging.

  • A resource the address agent cannot pair with a generated block is not imported and is not fed back to the generator.

  • Import rounds run no compliance check, show no impact banner, and pin no plan.

Next steps