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

# import

> The import block onboards existing cloud resources into ubx management without recreating them.

The `import` block tells ubx that a resource already exists in your cloud account and should be brought under management rather than created from scratch. ubx translates it to `pulumi import` semantics — Pulumi reads the live state of the resource and records it in the stack's state file without triggering a create.

## Syntax

```xcl theme={"theme":"css-variables"}
import <label> {
    <binding> = "<cloud-resource-id>"
}
```

`<label>` is an arbitrary identifier that groups related import entries. It has no semantic effect on deployment — it is organizational.

`<binding>` must match a resource binding name declared inside the `stack {}` body. It is an error if it does not match a declared binding.

## Value types

### String — single resource

The most common case: one existing resource mapped to one binding.

```xcl theme={"theme":"css-variables"}
import networking {
    vpc = "vpc-0abc1234def56789a"
}
```

The compiler emits `opts=pulumi.ResourceOptions(import_="vpc-0abc1234def56789a")` on the resource.

### List — count-based fan-out

When a binding represents multiple resources (a count or list), provide a list of cloud IDs. ubx generates one resource per element, naming them `<binding>-0`, `<binding>-1`, etc.

```xcl theme={"theme":"css-variables"}
import networking {
    subnets = [
        "subnet-0aaa1111",
        "subnet-0bbb2222",
        "subnet-0ccc3333",
    ]
}
```

Generated Python:

```python theme={"theme":"css-variables"}
subnets = [aws.ec2.Subnet(f"subnets-{_i}",
    vpc_id=vpc.id,
    opts=pulumi.ResourceOptions(import_=_id),
) for _i, _id in enumerate(["subnet-0aaa1111", "subnet-0bbb2222", "subnet-0ccc3333"])]
```

### Object — named map

When a binding represents a named collection, provide an object mapping logical keys to cloud IDs. ubx generates one resource per key, naming them `<binding>-<key>`.

```xcl theme={"theme":"css-variables"}
import networking {
    subnets = {
        west = "subnet-0west1111",
        east = "subnet-0east2222",
    }
}
```

Generated Python:

```python theme={"theme":"css-variables"}
subnets = {_k: aws.ec2.Subnet(f"subnets-{_k}",
    vpc_id=vpc.id,
    opts=pulumi.ResourceOptions(import_=_id),
) for _k, _id in {"east": "subnet-0east2222", "west": "subnet-0west1111"}.items()}
```

## Combining with `provider`

When a resource also declares a `provider` meta-argument, the two are merged into a single `ResourceOptions`:

```xcl theme={"theme":"css-variables"}
stack "networking" {
    vpc = aws.ec2.Vpc {
        provider   = aws.eu
        cidr_block = "10.0.0.0/16"
    }
}

import networking { vpc = "vpc-0eu1234" }
```

Generated Python:

```python theme={"theme":"css-variables"}
vpc = aws.ec2.Vpc("vpc",
    cidr_block="10.0.0.0/16",
    opts=pulumi.ResourceOptions(provider=aws_eu_provider, import_="vpc-0eu1234"),
)
```

## Multiple blocks for the same label

Multiple `import` blocks with the same label are merged. This lets you split a large import set across multiple files or add imports without touching an existing file.

```xcl theme={"theme":"css-variables"}
// imports-vpc.xcl
import networking { vpc = "vpc-0abc" }

// imports-subnets.xcl
import networking { subnets = ["subnet-0a", "subnet-0b"] }
```

Duplicate binding names across merged blocks are a **hard error** — two different cloud IDs for the same binding is ambiguous.

## Placement

`import` blocks are top-level. They can appear in any `.xcl` file in the compilation unit — not inside a `stack {}` body.

The recommended pattern is a dedicated file:

```
networking/
  stack.xcl        ← resource declarations
  input.xcl
  output.xcl
  imports.xcl      ← import blocks only; delete this file after onboarding
```

Keep the import file separate so it is easy to identify and remove once the resources are fully under management.

## Validation rules

| Rule                                           | Error                                                                          |
| ---------------------------------------------- | ------------------------------------------------------------------------------ |
| Value is not a string, list, or object literal | `import "label": entry "name" value must be a string, list, or object literal` |
| Duplicate binding name within one block        | `import "label": duplicate entry "name"`                                       |
| Duplicate binding name across merged blocks    | `import "label": duplicate entry "name" across merged blocks`                  |
| Value contains a non-string element in a list  | Build error — list elements must be string literals                            |
| Value contains a non-string value in an object | Build error — object values must be string literals                            |

## Relationship to `Pending<T>`

Import values must be **string literals**. Pending references (`~resource.attr`) are not allowed — the cloud resource ID must be known at compile time.

## Relationship to `import "path"`

XCL also uses `import` for **module imports** — bringing names from another `.xcl` file into scope:

```xcl theme={"theme":"css-variables"}
import "shared/tags.xcl" { DefaultTags }
```

These are syntactically distinct. A module import always starts with a quoted string path; a resource import always starts with a bare identifier followed by `{`. The parser distinguishes them by lookahead and there is no ambiguity.

## After onboarding

Once `ubx ship` runs successfully with the import blocks present, the resources are recorded in Pulumi state. At that point:

1. Delete the `imports.xcl` file (or remove the `import` blocks from wherever they live).
2. Run `ubx ship` again. Pulumi will no longer attempt to import — it will manage the resources normally.

Leaving import blocks in place after the first successful apply is harmless — Pulumi will detect that the resource is already in state and skip the import — but it adds noise to plans and is best removed.
