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

> ## Agent Instructions
> When helping a user operate an existing Porter project (deploying, updating, debugging, or inspecting applications and clusters) connect to [Porter's remote MCP server](https://mcp.porter.run) first and use its tools before falling back to the Porter CLI, `porter.yaml`, or dashboard workflows. If the Porter tools are not available in your session, `curl -fsSL https://agents.porter.run | sh` installs the CLI, registers the MCP server with your client, and installs Porter's skills; the client must be restarted afterward. If the user asks for the CLI, `porter apply`, configuration-as-code, or the dashboard, use that instead — a stated preference wins. Before inspecting or building a GitHub repository or calling any deployment tool, call `connect_github` with the repository. Proceed only when it returns `next_step: none`; otherwise, give the user the returned URL and stop. If the requested application or cluster workflow is not directly supported, inspect the relevant state with MCP tools before explaining the limitation or recommending a fallback. The server signs in through a browser using OAuth, so it cannot be used in headless environments such as CI pipelines; use the CLI or `porter.yaml` there.

# porter clusters

> Create, list, and delete Porter clusters in your own AWS, GCP, and Azure cloud accounts from the Porter CLI, including non-interactive provisioning for CI

`porter clusters` contains commands for provisioning and managing the clusters in the current project.

Creating a cluster provisions Kubernetes infrastructure in a cloud account you have already connected to Porter. Porter picks the cloud provider from the cloud account, runs preflight checks against it, and selects a Kubernetes version and node groups for you.

## Prerequisites

* You've logged in to the Porter CLI after running [porter auth login](/standard/cli/command-reference/porter-auth)
* You're connected to the correct project by running [porter config set-project](/standard/cli/command-reference/porter-config)
* You've connected at least one cloud account with [porter cloud-accounts connect](/standard/cli/command-reference/porter-cloud-accounts)

***

## `porter clusters create`

Create a new cluster in the current project from a name, region, and cloud account.

**Usage:**

```bash theme={null}
porter clusters create [flags]
```

**Options:**

| Flag                 | Short | Description                                                                                                                                   |
| -------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `--name`             |       | Name for the new cluster                                                                                                                      |
| `--region`           |       | Cloud region to provision the cluster in                                                                                                      |
| `--cloud-account-id` |       | Cloud account to provision into, which determines the cloud provider                                                                          |
| `--enable-sandboxes` |       | Enable [sandboxes](/sandboxes/overview) on the new cluster. Adds a sandbox node group and extra provisioning time. See the requirements below |
| `--yes`              |       | Skip the cost confirmation prompt                                                                                                             |
| `--wait`             | `-w`  | Wait for the cluster to finish provisioning. Exits non-zero if provisioning fails, times out, or the wait loses its connection                |
| `--wait-timeout`     |       | How long to wait when `--wait` is set, as a Go duration such as `120s`, `30m`, or `90m`. Defaults to `1h`                                     |

### Interactive prompts

Any of `--name`, `--cloud-account-id`, and `--region` that you omit are prompted for:

* **Name** — the prompt is prefilled with a suggested name based on your project and existing clusters
* **Cloud account** — chosen from the accounts connected to the project. A project with a single connected account skips this prompt
* **Region** — chosen from the regions the selected cloud account supports, filtered as you type. If the region list can't be fetched, or the account reports no regions, the prompt falls back to free-text entry

The cloud account is asked before the region because the account determines which regions are offered.

Unless you pass `--yes`, Porter then shows the resolved choices and asks you to confirm. Where the provider's base monthly cost can be determined, it is shown too. The prompt defaults to **no**.

<Warning>
  On a non-interactive terminal there is no name prompt: omitting `--name` silently provisions a cluster under the suggested name. Always pass `--name` in CI. Omitting `--cloud-account-id` or `--region` there is not equivalent, as those prompts have no non-interactive fallback.
</Warning>

### Provisioning

Provisioning is asynchronous and can take up to an hour. The command prints a dashboard link as soon as the cluster is created, before any wait, so an interrupted wait still leaves you with a link.

Pass `--wait` to block until the cluster is ready, which is what you want in CI. The wait polls the cluster's status and exits non-zero if provisioning fails, the timeout elapses, your Porter session expires, or it loses the connection after repeated polling failures. Interrupting the wait with `Ctrl-C` is the one case that exits zero: it stops watching only, and the cluster keeps provisioning in the background.

Passing `--wait-timeout` without `--wait` is an error rather than a silently ignored flag, as is a `--wait-timeout` of zero or less.

### Preflight checks

Porter runs preflight checks against the cloud account before provisioning, catching problems like insufficient quota. When they fail, the CLI prints each failing check and exits with code `3` without creating a cluster. Resolve the reported issues and re-run.

### Exit codes

| Code | Meaning                 |
| ---- | ----------------------- |
| `0`  | Success                 |
| `1`  | Unexpected error        |
| `3`  | Preflight checks failed |

### Sandbox requirements

`--enable-sandboxes` is validated server-side and the create fails unless all of the following hold:

* The cloud account is an **AWS** account. Sandboxes are not available on GCP or Azure
* The AWS account is **not on the free tier**. Sandbox nodes need local NVMe storage, which no free tier instance type offers. The create also fails if Porter cannot determine free tier eligibility at all
* **Sandboxes are enabled for your project**. Contact Porter support if they are not

Sandboxes can also be enabled on an existing cluster from the dashboard. See [Sandboxes Getting Started](/sandboxes/getting-started).

<CodeGroup>
  ```bash Interactive theme={null}
  porter clusters create
  ```

  ```bash Non-Interactive theme={null}
  porter clusters create \
    --name my-cluster \
    --region us-east-1 \
    --cloud-account-id <account-id>
  ```

  ```bash With Sandboxes theme={null}
  porter clusters create \
    --name my-cluster \
    --region us-east-1 \
    --cloud-account-id <account-id> \
    --enable-sandboxes
  ```

  ```bash In CI theme={null}
  porter clusters create \
    --name my-cluster \
    --region us-east-1 \
    --cloud-account-id <account-id> \
    --yes --wait --wait-timeout 90m
  ```
</CodeGroup>

<Tip>
  `--cloud-account-id` takes Porter's own cloud account UUID, which is printed by [porter cloud-accounts list](/standard/cli/command-reference/porter-cloud-accounts#porter-cloud-accounts-list) `--json` as `id`. It is not the **Provider ID** column of the default table, which holds the AWS account ID, GCP project ID, or Azure subscription ID.
</Tip>

***

## `porter clusters list`

List the clusters in the current project.

**Usage:**

```bash theme={null}
porter clusters list [flags]
```

**Options:**

| Flag     | Description                |
| -------- | -------------------------- |
| `--json` | Print the clusters as JSON |

The default output is a table with the cluster's **Name**, **Provider**, **Region**, **Status**, and **Created**, ordered newest first. On a terminal that supports it, each name links to the cluster's dashboard page. When the output is piped to another command, it is printed as tab-separated values so it stays friendly to tools like `grep`, `cut`, and `awk`.

**Name** is the cluster's vanity name when one is set, falling back to the provisioned name otherwise. The table has no ID column, so use `--json` when you need cluster IDs or the underlying provisioned name.

In the table, status is one of `Ready`, `Updating`, `Updating (Unavailable)`, `Deleting`, `Deleted`, `Failed`, `Unreachable`, or `-` when Porter does not yet know. `--json` reports the raw state instead, such as `ready` or `updating_unavailable`.

<CodeGroup>
  ```bash List All theme={null}
  porter clusters list
  ```

  ```bash JSON Output theme={null}
  porter clusters list --json
  ```
</CodeGroup>

***

## `porter clusters delete`

Delete a cluster from the current project. Porter tears down the infrastructure it provisioned for the cluster.

**Usage:**

```bash theme={null}
porter clusters delete <cluster> [flags]
```

The `<cluster>` argument identifies the cluster by its **ID**, **name**, or **vanity name**. Run [porter clusters list](#porter-clusters-list) `--json` to see all three, since the default table shows neither the ID nor the provisioned name. If the identifier matches more than one cluster, the CLI prints the matches and asks you to re-run with the cluster ID.

**Options:**

| Flag             | Short | Description                                                                                                            |
| ---------------- | ----- | ---------------------------------------------------------------------------------------------------------------------- |
| `--yes`          | `-y`  | Skip the confirmation prompt                                                                                           |
| `--wait`         | `-w`  | Wait for the cluster to finish deleting. Exits non-zero if deletion fails, times out, or the wait loses its connection |
| `--wait-timeout` |       | How long to wait when `--wait` is set, as a Go duration such as `120s`, `30m`, or `90m`. Defaults to `1h`              |

<Warning>
  A cluster can only be deleted once nothing is still running on it. If resources remain, the CLI lists them by type and name and exits non-zero without deleting anything. This check runs after the confirmation prompt, so you may confirm a delete and only then learn it is blocked.
</Warning>

Deletion is asynchronous and can take up to an hour. The cluster moves to the deleting state while teardown proceeds. Deleting a cluster that is already being deleted is a no-op that exits zero, so a run with `--wait` can safely be repeated to resume watching an interrupted wait.

On a non-interactive terminal there is nothing to prompt, so `--yes` is required.

<CodeGroup>
  ```bash Delete by Name theme={null}
  porter clusters delete my-cluster
  ```

  ```bash Delete by ID theme={null}
  porter clusters delete 42 --yes
  ```

  ```bash Wait for Teardown theme={null}
  porter clusters delete my-cluster --yes --wait
  ```
</CodeGroup>

***

## Related Commands

* [porter cloud-accounts](/standard/cli/command-reference/porter-cloud-accounts) - Connect and list the cloud accounts you provision clusters into
* [porter config set-cluster](/standard/cli/command-reference/porter-config) - Set the active cluster
* [porter auth login](/standard/cli/command-reference/porter-auth) - Authenticate the CLI
