Docs

Show deployment progress

Deployment progress is the card in your product that tells a customer what their deployment is doing and who must act next. You show it when you launch the portal from your product with a Deploy button, or build it into your product with your own setup screen.

Example UI /Provisioning

Document processing

Settings ยท Deploy in your cloud

Setting up

Setting up in your AWS account

This usually takes 10 to 20 minutes. You can leave this page.

Resources

Compute3Setting up
  • Compute clustercomputeCreating

    Waiting for machines to join the cluster.

  • API serverapiWaiting

    Waiting for Compute cluster.

  • Event processoreventsRunning
Data1Running
  • Uploads bucketuploadsRunning
Secrets and keys2Running
  • Service credentialscredentialsRunning
  • Application secretssecretsRunning
Networking and access3Running
  • Networkdefault-networkRunning
  • Management identitymanagementRunning
  • Service account (application)application-saRunning
Last update
12 seconds ago

Every state comes from one call, GET /v1/deployments/{id}, read by your backend. Errors, blocked updates, and removal have their own pages:

Waiting for setup

The initial setup runs in the customer's account, with their admin's credentials, outside your product. Until it reports back, your page waits.

Example UI /Waiting for setup

Document processing

Settings ยท Deploy in your cloud

Waiting for setup

Finish the setup in AWS

The setup hasnโ€™t started in your AWS account yet. Weโ€™ll update this page when it does.

Account
123456789012 ยท us-east-1
Last checked
8 seconds ago
Reopen setupCheck nowSend to an admin

Show it when a deployment exists, status is pending or initial-setup, and lastHeartbeatAt is null.

  • Console opened, nothing created. Opening the AWS console proves nothing. Keep this state until the deployment reports, even if the customer clicks Continue.
  • Reload. Land on the same deployment. Reopen setup shows the same setup step instead of creating a second deployment.
  • Check now. It only requests a check and returns requestedAt. Show "Check requested" until a newer resourceObservedAt arrives.
  • Wrong person. The person who clicked often isn't the cloud admin. Send to an admin shares the setup link, not a screenshot of your page.
  • Stack rolled back. On CloudFormation, setupMetadata.setupReservation.rolledBackAt means the stack failed before it reported back. See Come back to it.
GET /v1/deployments/{id}
{
  "id": "dep_0c29fq4a2yjb7kx3smwdgxlc",
  "status": "pending",
  "setupMethod": "cloudformation",
  "lastHeartbeatAt": null,
  "resourceObservedAt": null,
  "resources": []
}

Each action is one call with no body:

  • Check now: POST /v1/deployments/{id}/check asks Alien to look for the deployment again, and returns 202 with requestedAt.
  • Reopen setup: POST /v1/deployments/{id}/installation returns the same launch link, Terraform configuration or command, never a new deployment.
lib/setup-handoff.ts
import { alien } from "./alien"

export const checkNow = (id: string) => alien.requestDeploymentCheck({ id })
export const reopenSetup = (id: string) => alien.resumeDeploymentInstallation({ id })

Setting up

While Alien creates the live resources, show them grouped by category, as the deployment portal and the Alien dashboard do. The example at the top of this page shows this state.

Show it when status is provisioning, waiting-for-machines, or waiting-for-secrets.

  • Closed categories. Each category shows one status. Open one on its own only when it holds a failed resource.
  • No percentages. Resources finish in parallel and take different times. Don't show a progress bar or an ETA.
  • Long setups. A first deployment usually takes 10 to 20 minutes. Say so once, and let the customer leave the page.
  • progress is for people. Show it as is; never branch on it. It's null when there's nothing to say.
  • Missing secrets. waiting-for-secrets needs the customer. Name the secret from runtimeMetadata.deployerSecrets, where status is missing or invalid, and link to Inputs and secrets.
GET /v1/deployments/{id}
{
  "status": "provisioning",
  "resourceObservedAt": "2026-01-15T09:04:48Z",
  "resources": [
    {
      "id": "compute",
      "displayName": "Compute cluster",
      "type": "compute-cluster",
      "status": "provisioning",
      "progress": "Waiting for machines to join the cluster.",
      "error": null,
      "retryAttempt": 0
    }
  ]
}

resources lists every resource in the deployment, including the network, identities, and cloud APIs Alien adds for the platform:

FieldUse
displayNameThe resource's name. Falls back to id when the stack doesn't set one.
typeIts category. See Categories.
descriptionA tooltip or a detail view, when you want one.
statusrunning is Running, *-failed is Failed, anything else is in progress.
progressWhat the resource is waiting for right now. Show it as is.
errorThe resource's last error. See Errors and retries.
retryAttemptHow many times in a row the current step has failed.

resourceObservedAt says when Alien last read the resources; show it as "Last update".

Set the names in alien.ts, so the resources read like your product:

alien.ts
const api = new alien.Container("api")
  .displayName("API server")
  .description("Serves the document processing API.")
  // ...
  .build()

Resources Alien adds have built-in names, such as Network and Management identity. See Supporting resources.

Categories

Pick each resource's category from its type, and show the categories in this order. Leave out empty ones.

Categorytype
Computeworker, container, daemon, sandbox, compute-cluster, build
Datastorage, kv, queue, postgres
Secrets and keysvault, key
AI and emailai, email
Networking and accessEvery other type: networks, service accounts, the management identity, registries, cloud API activations

Each category row shows its name, a count, and one status, worst first:

  • N failed if any resource failed.
  • Setting up if any is pending, provisioning or updating.
  • Deleting if any is deleting.
  • Running otherwise.

Inside a category, list failed resources first, then in-progress ones, then the rest in the order resources returns them. Each resource gets one line, with progress or the error message on a second line.

Ready

running with currentReleaseId equal to desiredReleaseId means Alien finished. It doesn't mean your product can reach the service yet.

Example UI /Ready

Document processing

Settings ยท Deploy in your cloud

Ready to connect

Deployed. Run a connection test.

The service is running in your AWS account. Test it from your app before you switch traffic over.

Resources

Compute3Running
  • Compute clustercomputeRunning
  • API serverapiRunning
  • Event processoreventsRunning
Data1Running
  • Uploads bucketuploadsRunning
Secrets and keys2Running
  • Service credentialscredentialsRunning
  • Application secretssecretsRunning
Networking and access3Running
  • Networkdefault-networkRunning
  • Management identitymanagementRunning
  • Service account (application)application-saRunning
Endpoint
https://docs.customer-1.internal
Version
12
Connection test
Not run
Run connection test

Show it when status is running, currentReleaseId equals desiredReleaseId, and your own connection test hasn't passed yet.

  • Not yet active. Your product turns the feature on after its own test passes. See Verify and activate.
  • Closed categories. Every category shows Running and starts closed.
  • Running an older release. When currentReleaseId differs from desiredReleaseId, an update is pending. See Updates and connection.
GET /v1/deployments/{id}
{
  "status": "running",
  "currentReleaseId": "rel_WbhQgksrawSKIpEN0NAssHX9",
  "desiredReleaseId": "rel_WbhQgksrawSKIpEN0NAssHX9",
  "lastHeartbeatAt": "2026-01-15T09:21:03Z",
  "updateState": { "active": null, "next": null, "latest": null }
}

Read the deployment

Poll from your backend, never from the browser: the Alien API key stays on your server. Store what you read in your own database and serve your page from it. The clients are set up in Set up a client.

lib/deployment-progress.ts
import { alien } from "./alien"

export async function readDeployment(deploymentId: string) {
  const d = await alien.deployments.get({ id: deploymentId })
  return {
    status: d.status,
    resources: d.resources, // id, displayName, status, progress, error, retryAttempt
    update: d.updateState.active, // a blocked or running update, or null
    error: d.error,
    lastHeartbeatAt: d.lastHeartbeatAt,
  }
}
  • Polling. Every 10 to 30 seconds while the customer watches, and every few minutes from a background job otherwise.
  • API errors. Back off: double the delay up to two minutes, keep showing the last state you read, and reset after a good read.
  • Stop when the state settles: ready, failed, waiting on the customer, or removed.
  • Webhooks. To hear about changes without polling, add a webhook endpoint. Alien sends events such as deployment.running or deployment.failed, and your server reads the deployment then.

To find the deployment first, see When they come back.

Status map

Your page needs a few states, not Alien's full lifecycle. Map each status to one:

statusProduct stateHeadline
none, pending, initial-setupWaiting for setup"Finish the setup in AWS."
provisioning, waiting-for-machines, waiting-for-secretsSetting up"Setting up in your AWS account."
runningReady to connectThe endpoint, and your own connection test
update-pending, updatingUpdating"Updating to version 13."
preflights-failed, initial-setup-failed, provisioning-failed, refresh-failed, update-failed, errorFailedThe first failed resource's error, and Retry
teardown-required, teardown-failed, retention-requiredNeeds the customer"Delete the setup stack to finish removal."
delete-pending, deleting, delete-failedRemoving"Removing the service."
retainedRemoved, data kept"Removed. Your data stays in your AWS account."
deletedRemovedClose your record

Test it

  • Unit-test your mapping with the responses on this page and its sibling pages. Assert the headline, categories, and actions for each.
  • Deploy for real into a test account. Watch every state, then reload during initial setup and confirm the page shows the same deployment.
  • Missing secret. Leave a deployer secret unset, and check your page names it.

Next

On this page