> For AI agents: the complete Sanity documentation index is available at [https://www.sanity.io/docs/llms.txt](https://www.sanity.io/docs/llms.txt).

# Resource lifecycle

Understand how Blueprints manages resource state during deployments, and how to configure deletion policies, ownership actions, and deployment dependencies.

When you run `blueprints deploy`, Blueprints compares your blueprint against the current state of your stack and determines what needs to change. Each change (creating, updating, or removing a resource) is an **action**. The full set of actions for a deploy is an **operation**.

## How an operation runs

Operations move through four states:

- **Queued**: Accepted, waiting to run.
- **In progress**: Actions are executing. Resources are created, updated, or destroyed in dependency order.
- **Completed**: All actions succeeded. Your stack matches the blueprint.
- **Failed**: One or more actions failed. Blueprints rolls back all completed actions in reverse order and restores your stack to its previous state.

Operations are transactional: either your stack fully reflects the new blueprint, or it is restored to what it was before.

You can follow progress in real time with `blueprints deploy`, which streams logs by default. To review a past operation, run `blueprints logs`.

## Deployment scenarios

- **First deployment**: Creates all resources in the blueprint.
- **Redeploy with changes**: Creates new resources, updates changed ones, and removes resources no longer in the blueprint.
- **Remove a resource**: Destroys that resource, unless a deletion policy prevents it.
- **Run blueprints destroy**: Destroys the stack and most managed resources; resources with a retain policy are detached rather than destroyed.

## Configuring lifecycle behavior

The `lifecycle` property is available on every resource type. It controls what happens to a resource when the stack is deployed, updated, or destroyed.

- `deletionPolicy`: Controls what happens when the resource is removed from the blueprint or the stack is destroyed. Defaults to `allow`; datasets and projects default to `retain`.
- `ownershipAction`: Controls the ownership relationship between a resource and the stack.
- `dependsOn`: Declares that this resource must be deployed after another resource in the same blueprint.

## deletionPolicy

Controls what happens to a resource when you remove it from the blueprint or destroy the stack.

### allow

The resource is destroyed when removed from the blueprint or when you run `blueprints destroy`. This is the global default for most resource types.

Datasets and projects are an exception: they default to `retain`. Set `deletionPolicy: 'allow'` explicitly if you want them destroyed on removal.

**sanity.blueprint.ts**

```typescript
defineRobotToken({
  name: 'ci-robot',
  label: 'CI Robot',
  memberships: [{
    resourceType: 'project',
    resourceId: 'your-project-id',
    roleNames: ['editor'],
  }],
  lifecycle: {
    deletionPolicy: 'allow',
  },
})
```

### retain

The resource is detached when the stack is destroyed and continues to exist independently. Removing it from the blueprint will cause the deployment to fail until you either restore it or set the policy to `allow`.

Robot tokens and other credentials are good candidates for `retain` since losing them can break dependent systems.

**sanity.blueprint.ts**

```typescript
defineRobotToken({
  name: 'deploy-robot',
  label: 'Deploy Robot',
  memberships: [{
    resourceType: 'project',
    resourceId: 'your-project-id',
    roleNames: ['editor'],
  }],
  lifecycle: {
    deletionPolicy: 'retain',
  },
})
```

### protect

The resource is not updated, removed, destroyed, or detached by Blueprints while this policy is set. Any attempt causes the deployment to fail. To release a protected resource, first change `deletionPolicy` to `allow` or `retain`, deploy, then use `detach`.

Use `protect` during initial rollout to prevent accidental changes to critical resources. Remove it when you are ready to manage the resource normally.

**sanity.blueprint.ts**

```typescript
defineRobotToken({
  name: 'deploy-robot',
  label: 'Deploy Robot',
  memberships: [{
    resourceType: 'project',
    resourceId: 'your-project-id',
    roleNames: ['editor'],
  }],
  lifecycle: {
    deletionPolicy: 'protect',
  },
})
```

❌ Don't use `protect` on a resource you expect to update regularly. Every deploy will fail until you remove the policy.

### replace

The resource is destroyed and recreated on every deployment rather than updated in place. Use `replace` when a resource does not support in-place updates or when you want a guaranteed clean state on each deployment.

**sanity.blueprint.ts**

```typescript
defineDocumentWebhook({
  name: 'content-sync',
  url: 'https://api.example.com/webhook',
  on: ['create', 'update'],
  lifecycle: {
    deletionPolicy: 'replace',
  },
})
```

### Provider defaults

Some resource types override the global default. Datasets and projects have a default deletion policy of `retain`, not `allow`. Removing a dataset or project from a blueprint will fail unless you explicitly set `deletionPolicy: 'allow'`.

**sanity.blueprint.ts**

```typescript
defineDataset({
  name: 'staging',
  datasetName: 'staging',
  lifecycle: {
    deletionPolicy: 'allow',
  },
})
```

## ownershipAction

Controls the ownership relationship between a resource and the stack. Use [attach](https://www.sanity.io/docs/blueprints/blueprints-manage-existing-resource) to take over an existing resource, [detach](https://www.sanity.io/docs/blueprints/blueprints-manage-existing-resource) to release one without destroying it, or [reference](https://www.sanity.io/docs/blueprints/blueprints-reference-resource) to read values from a resource in another stack.

## dependsOn

Use `dependsOn` to declare that one or more resources must be fully deployed before another. The values must start with `$.resources.` followed by the name of the resource to deploy first.

**sanity.blueprint.ts**

```typescript
defineDocumentFunction({
  name: 'on-publish',
  src: 'functions/on-publish',
  event: {
    on: ['create'],
    filter: "_type == 'article'",
  },
  lifecycle: {
    dependsOn: ['$.resources.production-dataset'],
  },
})
```

If a resource already references another resource in its parameters using a `$.resources.*` path, Blueprints creates the deployment dependency automatically. You only need `dependsOn` when there is no such parameter reference and you still need to control the order.

#### Related

[Reference a resource across stacks](https://www.sanity.io/docs/blueprints/blueprints-reference-resource)
Learn how to read values from a resource managed by another Blueprints stack without taking ownership of it.

[Manage an existing resource with Blueprints](https://www.sanity.io/docs/blueprints/blueprints-manage-existing-resource)
Learn how to bring an existing Sanity resource under Blueprints stack management, and how to release a resource without destroying it.

[Blueprints introduction](https://www.sanity.io/docs/blueprints/blueprints-introduction)
Learn what Blueprints are, how they work, and how to get started.

