Skip to main content
Use this guide to bring existing resources under the management of your own Terraform or OpenTofu code running through an rvn-stack module. This works for anything your Terraform providers can import — AWS, Cloudflare, Datadog, or any other provider in your configuration. The examples use AWS. Because you own the Terraform source, this is much simpler than importing into a standard module: add import blocks to your configuration and let Ravion’s normal plan → approval → apply pipeline perform the import. No CLI state surgery required.
Importing into a Ravion standard library module (rvn-s3, rvn-rds, and so on)? See Import into a standard module instead.

How it works

Import blocks are plannable. When your config declares an import block next to a matching resource block, the change pipeline’s plan shows the resource with an IMPORT action instead of CREATE. Approving the run makes the apply adopt the existing resource into state — nothing is created or destroyed.

Use an agent

The steps are the manual walkthrough below — copy this prompt into your coding agent in the repository containing your Terraform code:

Add import blocks for existing resources and run them through the Ravion pipeline.

Open in Cursor

Manual walkthrough

The example imports an existing AWS S3 bucket. The same flow works for any resource any of your providers can import.
1

Write the config with import blocks

Declare each existing resource and an import block pointing at it. The resource arguments must match the real settings — inspect every setting your arguments cover first (for an S3 bucket: versioning, encryption, public access block, tags, policy; adapt per resource type and provider):
terraform/main.tf
Import IDs vary by resource type — each provider’s docs list the format in the resource’s Import section. For large configs, terraform plan -generate-config-out=generated.tf run locally can generate the resource blocks for you.
Ravion requires a remote state backend. With use_ravion_state_backend enabled (the default), declare an empty cloud {} block as above. If you manage your own backend (S3 + DynamoDB, Terraform Cloud), keep your existing backend config and disable use_ravion_state_backend.
2

Run the change pipeline

If the module already exists, push to the primary branch (for connected repos) or trigger a run manually:
If you’re creating the rvn-stack module now, --initial-stack-run PLAN starts the first run for you. See the rvn-stack reference for the module inputs.
3

Review the IMPORT plan and approve

When the run reaches the approval gate, check the plan:
Example output
Each imported resource shows IMPORT — not CREATE. If a resource shows CREATE, the import ID or address is wrong. If it shows an UPDATE alongside the import, your resource arguments don’t match the real settings; inspect the diff:
Approve the run in the dashboard or via the CLI, and the apply adopts the resources into state:
4

Clean up the import blocks

Once the apply succeeds, the import blocks are inert — the resources are in state. Remove them in a follow-up commit to keep the config tidy. That push plans as no changes.

Alternative: CLI import

If you prefer terraform import over import blocks — or you’re on Terraform older than 1.5 — the CLI flow from the standard module guide works here too, and it’s simpler because the Terraform source is already yours: run ravion terraform shell --workspace <workspace> -- tofu init and ... -- tofu import <address> <id> from your config directory. Get the workspace name from ravion stack get <stack-id> --json.

Next steps

Terraform Stack module

Full rvn-stack input reference: git triggers, tfvars, state backend options.

Module stack

How stacks, change pipelines, and the managed state backend work.