Docs

Stack

This page lists every option of the Stack builder, the default export of alien.ts: your resources with their lifecycles, plus the options that apply to the whole deployment.

alien.ts
import * as alien from "@alienplatform/core"

const config = alien.inputs({
  region_label: alien.string({
    providedBy: "deployer",
    required: false,
    label: "Region label",
    description: "Shown in logs and dashboards.",
    default: "primary",
    env: "REGION_LABEL",
  }),
})

const files = new alien.Storage("files").build()

const api = new alien.Worker("api")
  .code({ type: "source", src: "./api", toolchain: { type: "typescript" } })
  .link(files)
  .permissions("execution")
  .build()

export default new alien.Stack("acme")
  .platforms(["aws", "gcp", "azure"])
  .inputs(config)
  .add(files, "frozen")
  .add(api, "live")
  .permissions({
    profiles: { execution: { files: ["storage/data-read", "storage/data-write"] } },
  })
  .build()

new alien.Stack(id) takes an id of letters, digits, -, and _, up to 128 characters. .build() validates the whole stack and throws on an invalid config.

Methods

MethodNotes
.add(resource, lifecycle, opts?)Adds a built resource. lifecycle is "frozen" or "live". See Resources.
.platforms(list)Platforms the stack supports. Omit to allow all.
.permissions(config)Permission profiles and management access. See Permissions.
.inputs(set)Values the developer or deployer provides before initial setup, the customer admin's one-time step. See Inputs.
.operations(config)Remote Operator operations (named actions your team runs in a deployment) and approval rules. See Operations.
.dynamicContainerRepositories(repos)Image repositories allowed for containers your app creates at runtime.
.dynamicContainerImageResources(ids)Containers in this release whose image repositories are allowed for dynamic containers.
.build()Validates and returns the stack config.

Resources

alien.ts
new alien.Stack("acme")
  .add(files, "frozen")
  .add(api, "live")
  .add(sessions, "frozen", { remoteAccess: true })
ArgumentNotes
lifecycle: "frozen"Created once at initial setup by the customer's admin. The management identity can't change it.
lifecycle: "live"Created and updated by Alien on every release, during ongoing management.
remoteAccess: truePublishes the resource's binding so your backend can use it through remote bindings. Default false.

Some resource types allow only one lifecycle. See the resources list and Frozen and live resources.

Platforms

alien.ts
.platforms(["aws", "gcp", "azure", "kubernetes", "machines", "local"])

Values are aws, gcp, azure, kubernetes, machines, and local. A deployment to a platform outside the list is refused. See Platforms for what each resource supports.

Permissions

alien.ts
.permissions({
  profiles: {
    execution: {
      files: ["storage/data-read", "storage/data-write"],
      "*": ["queue/data-write"],
    },
  },
  management: { extend: { credentials: ["vault/data-write"] } },
})
FieldNotes
profilesMap of profile name to { <resource id or "*">: permission sets }. Workloads choose a profile with .permissions("<name>"). Each profile becomes one cloud identity.
management"auto" (default), { extend: profile } to add sets, or { override: profile } to replace them.

A permission set is a built-in name such as "storage/data-read" or an inline object. See Permissions.

Inputs

Inputs are values provided before initial setup or a deployment, such as an API key or a feature flag. The developer is you; the deployer is the customer's admin who runs initial setup.

alien.ts
const config = alien.inputs({
  openai_api_key: alien.secret({
    providedBy: "deployer",
    required: true,
    label: "OpenAI API key",
    description: "Used by the summarizer.",
    env: { name: "OPENAI_API_KEY", targetResources: ["api"] },
  }),
  session_secret: alien.secret({
    providedBy: "developer",
    required: true,
    label: "Session signing secret",
    description: "Generated once per deployment.",
    generate: { length: 64 },
    env: "SESSION_SECRET",
  }),
  enable_search: alien.boolean({
    providedBy: "deployer",
    required: false,
    label: "Enable search",
    description: "Creates the search index.",
    default: false,
  }),
  tier: alien.enum(["small", "large"], {
    providedBy: ["developer", "deployer"],
    required: false,
    label: "Size",
    description: "Instance size.",
    default: "small",
  }),
})

const search = new alien.Storage("search-index").enabled(config.enable_search).build()
HelperValueExtra options
alien.string(opts)stringminLength, maxLength, pattern, format
alien.secret(opts)stringminLength, maxLength, pattern, format, generate: { length }. No default.
alien.number(opts)numbermin, max
alien.integer(opts)numbermin, max (integers)
alien.boolean(opts)boolean
alien.enum(values, opts)one of values
alien.stringList(opts)string[]minItems, maxItems
OptionNotes
providedBy"developer", "deployer", or both.
requiredWhether a value must be provided.
label, descriptionShown in setup UIs. Both required.
placeholderShown in setup UIs.
defaultNot allowed on secrets.
platformsAsk for the input only on these platforms.
envEnvironment variables to set from the value: a name, or { name, targetResources?, type?: "plain" | "secret" }. Names use uppercase letters, digits, and _. targetResources limits it to the listed workloads.

Input ids start with a letter or _, use letters, digits, and _, and can't be all caps.

An input value can:

  • set environment variables through env
  • turn a resource on or off with .enabled(input) (boolean inputs)
  • fill an operation setting

Validation options apply only to developer-provided values.

Deployer secrets

Deployer secrets never pass through Alien. The deployer stores them in their own secret store: SSM Parameter Store, Secret Manager, Key Vault, a Kubernetes Secret, or alien dev vault set locally. Alien reports whether they're present, and the workload waits until they are.

Generated secrets

generate: { length } (16 to 256) creates an alphanumeric secret once per deployment and reuses it on later updates. It must be providedBy: "developer" and can't use pattern or format.

Operations

alien.ts
.operations({
  cloudwatch: { approval: { "*": "auto" } },
  kubernetes: {
    approval: {
      "restart-pod": "auto",
      "*": { decision: "manual", maxRisk: "mutating" },
    },
  },
  plugins: ["acme-diagnostics@1.2.0"],
})

Declares the Remote Operator operations a deployment runs. Changing them takes a new release.

KeyNotes
<built-in plugin>Settings for that plugin, plus approval. A setting is a string, a stack input, a resource, or a list of resources.
approvalMap of operation name (or "*") to "auto", "manual", or { decision, maxRisk }. maxRisk is read-only, mutating, or destructive. Operations no rule matches need approval.
pluginsPublished custom plugins: "name@version", or { name, version, ...settings, approval }.

.operations({}) throws. Declare at least one plugin.

Dynamic containers

Containers your app creates at runtime can only use approved images.

alien.ts
.dynamicContainerRepositories(["ghcr.io/acme/runner"])
.dynamicContainerImageResources(["api"])
MethodRules
.dynamicContainerRepositories(repos)1 to 16 distinct, fully qualified OCI repositories, such as ghcr.io/acme/runner.
.dynamicContainerImageResources(ids)Distinct ids of Containers declared in this stack. Their image repositories are approved.

They run on the ComputeCluster pool with dynamicContainers: true. See ComputeCluster.

Next

On this page