> ## 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.

# moved — Rename a Resource Without Destroying It

> Update a resource's label in state without triggering a destroy and recreate.

Naming things is hard, and names change. A bucket called `media_files` becomes `media_store` when the team reorganises. A security group called `app` needs to become `api` when a second app tier is added. In plain Pulumi, renaming a resource means deleting the old one and creating a new one — which for a production S3 bucket with data, or an RDS instance with a live database, or any stateful resource, is simply not acceptable. The `moved` block tells Pulumi that the old state key (the old label) maps to the new unit block (the new label), so the rename is recorded as a state operation rather than a destroy-and-recreate. No downtime. No data loss. Just a new name in state.

## What you'll learn

* How `moved` renames a resource in Pulumi state without destroying it
* The `from` / `to` syntax and what each references
* When to remove the `moved` block after applying

***

## Why this matters

<Info>
  Without `moved`, renaming a `unit` block label causes Pulumi to destroy the old resource and create a new one. For stateful resources — databases, storage buckets, load balancers — this is destructive. `moved` makes refactoring safe.
</Info>

***

## The source code

<CodeGroup>
  ```hcl main.iac theme={"theme":"css-variables"}
  # New name — this unit block replaces the old "media_files" block.
  # The old "media_files" unit block has been removed from .iac.
  unit "aws_s3_bucket_v2" "media_store" {
    bucket = "myapp-media"
  }
  ```

  ```hcl moves.iac theme={"theme":"css-variables"}
  # moved { from = old_ref; to = new_ref } records a state rename.
  # from: references the old label (the block no longer needs to exist in .iac)
  # to:   references the new unit block (must exist in current .iac)
  #
  # ubx compiles this to: aliases: ["urn:...media_files..."] in Pulumi resource options.
  # After the first ubx apply that includes this moved block, remove it — it only
  # needs to run once to update state.
  moved {
    from = unit.aws_s3_bucket_v2.media_files
    to   = unit.aws_s3_bucket_v2.media_store
  }
  ```

  ```hcl outputs.iac theme={"theme":"css-variables"}
  output "bucket_name" {
    value = unit.aws_s3_bucket_v2.media_store.bucket
  }
  ```

  ```hcl ubx.iac theme={"theme":"css-variables"}
  ubx {
    name    = "moved-block-resource-rename"
    runtime = "typescript"
    stacks  = ["dev", "staging", "prod"]
  }

  backend "s3" {
    bucket = "my-ubx-state"
    region = "us-east-1"
    key    = "${stack}/moved-resource-rename.tfstate"
  }
  ```
</CodeGroup>

***

## How it works

<Steps>
  <Step title="ubx compiles moved to a Pulumi alias">
    The `moved` block compiles to a `aliases` option on the `to` resource's Pulumi constructor. The alias is the full Pulumi URN of the old resource (derived from the `from` reference). Pulumi uses aliases to match existing state entries to new resource declarations.
  </Step>

  <Step title="Pulumi recognises the alias and skips destroy">
    At apply time, Pulumi looks up the old URN in state, finds a matching alias on the new resource, and records the rename as a state update rather than a destroy-and-create. The cloud resource is unchanged — only the state entry is updated.
  </Step>

  <Step title="Remove the moved block after the first apply">
    Once the rename is in state, the `moved` block serves no purpose. Leaving it in place doesn't cause errors, but it adds a stale alias to every subsequent apply. Remove it after confirming the apply succeeded.
  </Step>
</Steps>

***

## What ubx generates

<CodeGroup>
  ```typescript index.ts theme={"theme":"css-variables"}
  // Generated by ubx — do not edit
  import * as pulumi from "@pulumi/pulumi";
  import * as aws from "@pulumi/aws";

  // alias generated from the moved block — tells Pulumi the old state key
  const mediaStore = new aws.s3.BucketV2("media_store", {
      bucket: "myapp-media",
  }, {
      aliases: [{ name: "media_files" }],  // generated from moved block
  });

  export const bucketName = mediaStore.bucket;
  ```

  ```python __main__.py theme={"theme":"css-variables"}
  # Generated by ubx — do not edit
  import pulumi
  import pulumi_aws as aws

  media_store = aws.s3.BucketV2("media_store",
      bucket="myapp-media",
      opts=pulumi.ResourceOptions(aliases=[pulumi.Alias(name="media_files")]),
  )

  pulumi.export("bucket_name", media_store.bucket)
  ```

  ```go main.go theme={"theme":"css-variables"}
  // Generated by ubx — do not edit
  package main

  import (
      "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/s3"
      "github.com/pulumi/pulumi/sdk/v3/go/pulumi"
  )

  func main() {
      pulumi.Run(func(ctx *pulumi.Context) error {
          mediaStore, err := s3.NewBucketV2(ctx, "media_store", &s3.BucketV2Args{
              Bucket: pulumi.String("myapp-media"),
          }, pulumi.Aliases([]pulumi.Alias{{Name: pulumi.StringInput(pulumi.String("media_files"))}}) )
          if err != nil { return err }
          ctx.Export("bucketName", mediaStore.Bucket)
          return nil
      })
  }
  ```
</CodeGroup>

***

## Common mistakes

<Warning>
  `from` can reference a block that no longer exists in the `.iac` files — this is intentional and expected. The old `unit "aws_s3_bucket_v2" "media_files"` block is removed when the rename happens; the `moved` block's `from` is a bare reference that tells ubx where to find the old URN in state, not a reference to a live block.
</Warning>

<Tip>
  `moved` works for any resource type, not just S3 buckets — RDS instances, security groups, EC2 instances, IAM roles. Any time you rename a `unit` block label and the resource shouldn't be destroyed, add a `moved` block before applying.
</Tip>

***

## Run it

```bash theme={"theme":"css-variables"}
ubx validate   # confirms from/to references are valid
ubx plan       # shows the rename as a state update, not destroy + create
ubx apply      # renames in state — cloud resource is unchanged
# After successful apply: remove the moved block
```

***

## What you learned

<Check>`moved` renames a resource in Pulumi state without destroying or recreating the cloud resource</Check>
<Check>`from` references the old label (the block no longer needs to exist); `to` references the new unit block</Check>
<Check>Remove the `moved` block after the first successful apply</Check>

***

## Next steps

<CardGroup cols={2}>
  <Card title="data source lookup" href="/v1/tutorials/33-data-source-lookup">
    Query existing cloud resources without managing them
  </Card>

  <Card title="moved block reference" href="/v1/language/moved">
    Full moved block syntax
  </Card>
</CardGroup>

***

<Info>
  Full runnable example: [github.com/ubiquex/ubx-examples/32-moved-block-resource-rename](https://github.com/ubiquex/ubx-examples/tree/main/32-moved-block-resource-rename)
</Info>
