# How to Import Workspace Resources into Your Rudder CLI Project


This guide walks you through importing workspace resources into a Rudder CLI project and running `apply` so the CLI manages them.

## Overview

Rudder CLI manages Data Catalog, Tracking Plans, SQL Models, Event Stream Sources, Destinations, Connections, and Transformations as YAML.

If those resources already exist in your workspace, you can use the `import workspace` command to generate files under `imported/`, adjust them if needed, then run `apply` to attach them to your CLI project — you do not need to recreate everything manually.

### Required permissions {#required-permissions}

Generate a [workspace-level Service Access Token]({{< ref "access-management/service-access-tokens.md#workspace-sat" >}}) with the [permissions]({{< ref "access-management/policies-overview.md#resource-permissions" >}}) required for each resource type you want to import and manage:

{{< tip >}}
Include permissions only for the resource types you use. The same scope applies for `apply` locally or in CI/CD. See [Manage Workspaces]({{< ref "dev-tools/rudder-cli/import-resources/manage-workspaces.md" >}}) for a deployment-oriented workflow.
{{< /tip >}}

| Resource type | Resource | Permissions |
| :----| :----| :-----|
| Data Catalog and Tracking Plans | Data Catalog | **Edit** |
| | Tracking Plans | **Edit** |
| SQL Models | SQL Models | **Create & Delete**, **Edit** |
| Event Stream Sources | Event Stream Sources | **Create & Delete**, **Edit**, **Connect** |
| | Tracking Plans | **Edit**, **Connect** |
| Destinations | Destinations | **Create & Delete**, **Edit**, **Connect** |
| Transformations | Transformations | **Edit**, **Connect**, **Create & Delete** |
| | Transformation Libraries | **Edit** |

{{< info >}}
**Important considerations**

- To import or apply Event Stream connections, include **Connect** (and **Edit**) on both Event Stream Sources and Destinations.
- If a destination links a transformation, also include the Transformations **Edit** and **Connect** permissions.
{{< /info >}}

{{< customreadfile "/includes/rudder-cli/token-auth-footer-admin.md" >}}

## Import workspace resources {#import-workspace-resources}

{{< warning >}}
**Before you import workspace resources**

Before starting the import process, make sure:

- You have a Rudder CLI project directory (can be empty)
- You have no unsynced changes in your project — apply any existing changes first by running the `apply` command.
- You don't have an existing directory named `imported` in your CLI project.

Otherwise, the import process will fail.
{{< /warning >}}

To import all resources from your current workspace into a CLI project, run the `import workspace` command — replace `<project-directory>` with the path to your CLI project directory.

```bash
rudder-cli import workspace -l <project-directory>
```

The command scans your workspace for resources not yet managed by Rudder CLI, writes YAML under `imported/`, and adds import metadata that maps local IDs to workspace IDs.

### What gets imported and where

```text
project/
├── imported/
│   ├── data-catalog/
│   │   ├── events/
│   │   ├── properties/
│   │   ├── categories/
│   │   ├── trackingplans/
│   │   └── custom-types/
│   ├── retl-sources/
│   │   ├── <model-name>.yaml
│   │   └── sql/
│   │       └── <model-name>.sql
│   ├── event-stream/
│   │   ├── connections.yaml
│   │   └── sources/
│   │       └── <source-name>.yaml
│   ├── destinations/
│   │   └── <destination-id>.yaml
│   ├── transformations/
│   │   ├── <transformation-name>.yaml
│   │   └── javascript/ 
│   │       ├── <transformation-name>.js
│   │       └── <library-name>.js
│   └── import-manifest.yaml
```

{{< info >}}
If a resource type has no instances, its folder is empty or omitted.
{{< /info >}}

| Resource | Path (under `imported/`) | <div style="width:300px">Notes</div> |
| :----| :----| :----|
| Events | `data-catalog/events/` | One YAML file per event definition |
| Properties | `data-catalog/properties/` | One YAML file per property definition |
| Event Categories | `data-catalog/categories/` | One YAML file per category |
| Custom Types | `data-catalog/custom-types/` | One YAML file per custom type |
| Tracking Plans | `data-catalog/trackingplans/` | One YAML per plan <br /><br /><ul><li>Supports plans from the [RudderStack Dashboard]({{< ref "data-governance/tracking-plans/create-tracking-plans.md" >}}) and [Data Catalog API]({{< ref "api/data-catalog-api/" >}})</li><li>Does not support [non-migrated]({{< ref "data-governance/tracking-plans/migration-guide.md" >}}) legacy plans from Google Sheets or the deprecated [Tracking Plan API]({{< ref "api/tracking-plan-api.md" >}})</li></ul> |
| Event Stream Sources | `event-stream/sources/` | One YAML per source <br /><br /><ul><li>[SDK Sources]({{< ref "sources/event-streams/sdks/" >}}) only (client or server)</li><li>Cloud and webhook sources are not supported</li></ul> |
| Destinations | `destinations/` | One YAML per destination. Secret config keys are written as `{{ .VAR }}` placeholders — see [Fill placeholders after import]({{< ref "dev-tools/rudder-cli/variable-substitution.md#fill-placeholders-after-import" >}}). Requires experimental `destinationSupport`. |
| Event Stream connections | `event-stream/connections.yaml` | One YAML file listing all Event Stream connections (`kind: event-stream-connections`). Requires experimental `connectionSupport`. |
| Transformations | `transformations/` | One YAML per transformation or library — code inline or under `javascript/` or `python/` when using external files |
| SQL Models | `retl-sources/` | One YAML per model — SQL inline by default, or under `sql/` when using external files |
| Import manifest | `import-manifest.yaml` | Maps local URNs to workspace IDs so `apply` can reconcile imported resources. Generated by import. |

{{< info >}}
Folder names under `imported/` follow the layout your Rudder CLI version generates. If you upgrade the CLI and the structure changes, compare the new output with this table and move files as needed before you run `apply`.
{{< /info >}}

## Import metadata {#import-metadata}

YAML from an import includes `metadata.import` so Rudder CLI can match local definitions to workspace resources. 

For how `workspace_id` behaves when you target another workspace, see [Manage Workspaces]({{< ref "dev-tools/rudder-cli/import-resources/manage-workspaces.md" >}}).

Example:

```yaml
version: "rudder/v1"
kind: "categories"
metadata:
  import:
    workspaces:
      - workspace_id: "3NrueK2Hu7ooXVQqQJhKqKlnofE"
        resources:
          - local_id: "abc"
            remote_id: "cat_343HNkcWRt8YXHphthHwa8QEdXE"
          - local_id: "webapp"
            remote_id: "cat_2ohsVV9iKuw7GfLFITwsVLn6Nhy"
  name: "categories"
spec:
  categories:
    - id: "abc"
      name: "ABC"
    - id: "webapp"
      name: "Webapp"
```

| Property | Type | <div style="width:350px">Description</div> |
| :----| :-----| :------|
| `workspace_id` | String | Workspace the resources were imported from. |
| `resources` | Array | Maps each `local_id` to a workspace `remote_id`. Do not change `remote_id` after import; see [Key considerations](#key-considerations). |

For the full metadata schema, see the [CLI Project Resources YAML Reference]({{< ref "dev-tools/rudder-cli/yaml-data-catalog-and-tracking-plans" >}}).

## Complete the import {#review-and-organize-imported-resources}

The `import workspace` command only writes files; it does not register them with your CLI project.

### Review and adjust files

Confirm the generated YAML matches what you expect. You may move files out of `imported/` to match your layout and edit fields such as names or descriptions. Before you run `apply`, read [Key considerations](#key-considerations) for rules on `local_id`, `remote_id`, import metadata, and dashboard changes.

### Apply imported resources {#apply-imported-resources}

Run:

```bash
rudder-cli apply -l <project-directory>
```

`apply` finds resources marked for import, links them to the CLI project, prints a summary, and asks you to confirm.

Example:

```bash
$ rudder-cli apply -l ./my-rudder-project

Importable resources:
  - category:abc
  - category:webapp

? Do you want to apply these changes? (y/N)
```

After you confirm, you manage those resources through Rudder CLI.

## Important considerations {#key-considerations}

This section covers important considerations when importing workspace resources and applying them to your CLI project.

#### Use Rudder CLI as the source of truth

For CLI-managed resources, use only Rudder CLI (not the dashboard or APIs) unless you intend to reconcile outside changes. After a successful `apply`, Rudder CLI is the source of truth for those resources.

#### IDs, metadata, and the dashboard

- Do not change `remote_id` values in imported YAML — updates will fail.
- You may change `local_id` only **before** `apply`. Keep the import metadata mapping in sync with any `local_id` you change.
- After `apply`, do not change `local_id`.
- Do not delete a resource in the dashboard after import but before `apply` — otherwise `apply` will fail with `Resource with ID not found`. See [Resource Deleted from Dashboard Before Apply]({{< ref "dev-tools/rudder-cli/import-resources/troubleshooting.md#resource-deleted-from-dashboard-before-apply" >}}).

#### Workflow tips

- Try the flow in a development workspace before production.
- Commit imported YAML to version control so changes stay reviewable and reversible.

## Next steps

- See [Manage Workspaces]({{< ref "dev-tools/rudder-cli/import-resources/manage-workspaces.md" >}}) for workspace promotion and CI/CD
- See [Fill placeholders after import]({{< ref "dev-tools/rudder-cli/variable-substitution.md#fill-placeholders-after-import" >}}) if imported YAML contains `{{ .VAR }}` placeholders
- See [Troubleshooting]({{< ref "dev-tools/rudder-cli/import-resources/troubleshooting.md" >}}) for common import and `apply` errors

