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.
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
| Method | Notes |
|---|---|
.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
new alien.Stack("acme")
.add(files, "frozen")
.add(api, "live")
.add(sessions, "frozen", { remoteAccess: true })| Argument | Notes |
|---|---|
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: true | Publishes 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
.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
.permissions({
profiles: {
execution: {
files: ["storage/data-read", "storage/data-write"],
"*": ["queue/data-write"],
},
},
management: { extend: { credentials: ["vault/data-write"] } },
})| Field | Notes |
|---|---|
profiles | Map 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.
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()| Helper | Value | Extra options |
|---|---|---|
alien.string(opts) | string | minLength, maxLength, pattern, format |
alien.secret(opts) | string | minLength, maxLength, pattern, format, generate: { length }. No default. |
alien.number(opts) | number | min, max |
alien.integer(opts) | number | min, max (integers) |
alien.boolean(opts) | boolean | |
alien.enum(values, opts) | one of values | |
alien.stringList(opts) | string[] | minItems, maxItems |
| Option | Notes |
|---|---|
providedBy | "developer", "deployer", or both. |
required | Whether a value must be provided. |
label, description | Shown in setup UIs. Both required. |
placeholder | Shown in setup UIs. |
default | Not allowed on secrets. |
platforms | Ask for the input only on these platforms. |
env | Environment 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
.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.
| Key | Notes |
|---|---|
<built-in plugin> | Settings for that plugin, plus approval. A setting is a string, a stack input, a resource, or a list of resources. |
approval | Map of operation name (or "*") to "auto", "manual", or { decision, maxRisk }. maxRisk is read-only, mutating, or destructive. Operations no rule matches need approval. |
plugins | Published 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.
.dynamicContainerRepositories(["ghcr.io/acme/runner"])
.dynamicContainerImageResources(["api"])| Method | Rules |
|---|---|
.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.