> ## Documentation Index
> Fetch the complete documentation index at: https://www.ravion.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Import existing resources into a Terraform Stack

> Use Terraform import blocks to bring existing resources from any provider under a Ravion rvn-stack module's management through the normal plan and apply pipeline.

Use this guide to bring existing resources under the management of your own Terraform or OpenTofu code running through an [`rvn-stack` module](/module-definitions/catalog/rvn-stack). 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](https://opentofu.org/docs/language/import/) to your configuration and let Ravion's normal plan → approval → apply pipeline perform the import. No CLI state surgery required.

<Note>
  Importing into a Ravion standard library module (`rvn-s3`, `rvn-rds`, and so on)? See [Import into a standard module](/migrate/import-into-standard-module) instead.
</Note>

## 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](#manual-walkthrough) below — copy this prompt into your coding agent in the repository containing your Terraform code:

<Prompt description="Add import blocks for existing resources and run them through the Ravion pipeline." icon="sparkles" actions={["copy", "cursor"]}>
  Fetch [https://www.ravion.com/docs/migrate/import-into-terraform-stack.md](https://www.ravion.com/docs/migrate/import-into-terraform-stack.md) and follow its manual walkthrough to import my existing resources into the Terraform configuration in this repository, which runs through a Ravion `rvn-stack` module. I will tell you which resources to import. Guardrails:

  * The walkthrough's example is an S3 bucket — adapt the inspection commands and import IDs to my resource types and providers.
  * Show me the plan before anything is applied.
  * Stop before approval. Never approve a pipeline run unless I explicitly tell you to.
  * After the run is approved and applied, remind me to remove the import blocks in a follow-up commit.
</Prompt>

## Manual walkthrough

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

<Steps>
  <Step title="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):

    ```bash theme={null}
    aws s3api get-bucket-versioning --bucket my-existing-bucket
    ```

    ```hcl terraform/main.tf highlight={6,20-28} theme={null}
    terraform {
      required_version = ">= 1.6.0"

      # Required when using Ravion's managed state backend.
      # Ravion injects the connection settings at runtime.
      cloud {}

      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = ">= 5.0"
        }
      }
    }

    provider "aws" {
      region = "us-east-1"
    }

    import {
      to = aws_s3_bucket.assets
      id = "my-existing-bucket"
    }

    import {
      to = aws_s3_bucket_versioning.assets
      id = "my-existing-bucket"
    }

    resource "aws_s3_bucket" "assets" {
      bucket = "my-existing-bucket"
    }

    resource "aws_s3_bucket_versioning" "assets" {
      bucket = aws_s3_bucket.assets.id

      versioning_configuration {
        status = "Enabled"
      }
    }
    ```

    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.

    <Note>
      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`.
    </Note>
  </Step>

  <Step title="Run the change pipeline">
    If the module already exists, push to the primary branch (for connected repos) or trigger a run manually:

    ```bash highlight={4-5} theme={null}
    # Find the stack ID: stackId from the module
    ravion module list --json

    ravion stack trigger-pipeline <stack-id> --pipeline-type change \
      --description "Import existing resources"
    ```

    If you're creating the `rvn-stack` module now, `--initial-stack-run PLAN` starts the first run for you. See the [`rvn-stack` reference](/module-definitions/catalog/rvn-stack) for the module inputs.
  </Step>

  <Step title="Review the IMPORT plan and approve">
    When the run reaches the approval gate, check the plan:

    ```bash theme={null}
    # Poll until the status is PENDING_APPROVAL
    ravion pipeline run get <run-id> --json

    ravion pipeline run get-plan <run-id>
    ```

    ```text Example output highlight={3-4} theme={null}
    ADDRESS                          CHANGE_TYPE
    aws_s3_bucket.assets             IMPORT
    aws_s3_bucket_versioning.assets  IMPORT
    ```

    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:

    ```bash theme={null}
    ravion terraform resource get <tfres-id> --json
    ```

    Approve the run in the dashboard or via the CLI, and the apply adopts the resources into state:

    ```bash highlight={2} theme={null}
    ravion pipeline step-execution list --pipeline-run-id <run-id> --json
    ravion pipeline step-execution approve <sexec-id>
    ```
  </Step>

  <Step title="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.
  </Step>
</Steps>

## 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](/migrate/import-into-standard-module#manual-walkthrough) 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

<CardGroup cols={2}>
  <Card title="Terraform Stack module" href="/module-definitions/catalog/rvn-stack">
    Full `rvn-stack` input reference: git triggers, tfvars, state backend options.
  </Card>

  <Card title="Module stack" href="/modules/stack">
    How stacks, change pipelines, and the managed state backend work.
  </Card>
</CardGroup>
