Skip to content
Spinbox is experimental: APIs change and data may be lost. Status lists what is built and what proves it.

The installation module

View Markdown

Source: github.com/spin-stack/spin-terraform-aws?ref=<tag>. Generated from its variables.tf and outputs.tf.

VariableTypeDefault
spin_versionstringrequired
domainstringrequired
namestringthe module’s own
acme_emailstringthe module’s own
admin_emailstringthe module’s own
runner_policyobject({ shutdown_grace = optional(string) preemption_source = optional(string) })the module’s own
proxy_allowed_cidrslist(string)the module’s own
instance_typestringthe module’s own
proxy_instance_typestringthe module’s own
collectorobject({ metric_interval = optional(string) })the module’s own
controlplane_volume_gbnumberthe module’s own
image_idsmap(string)the module’s own
image_measurementsmap(list(object({ pcr4 = string pcr7 = string pcr12 = string statement = optional(string) bundle = optional(string) revoked = optional(string) })))the module’s own
installation_configstringthe module’s own
runner_idle_minutesnumberthe module’s own
quiet_hoursstringthe module’s own
time_zonestringthe module’s own
runner_instance_typeslist(string)the module’s own
runner_spotboolthe module’s own
runner_data_volume_gbnumberthe module’s own
runner_root_volume_gbnumberthe module’s own
request_quotaboolthe module’s own
max_runnersnumberthe module’s own
runner_rolloutstringthe module’s own
decommissionboolthe module’s own
monthly_budget_usdnumberthe module’s own
budget_emailslist(string)the module’s own
tagsmap(string)the module’s own

The release the installation runs, as v<YYYYMMDD>.<N>: every machine boots the Spin OS image of it (spin-stack/ami), published into this account and tagged spin:version.

  • Type: string
  • Required

The base domain: the dashboard is app.<domain>, workspaces are *.ws.<domain>.

  • Type: string
  • Required

The installation’s name, one per region of an account (two regions may share it): every resource’s prefix, the SSM path /spin/<name>/, and with the region every IAM name. 2 to 26 characters; modules/controlplane’s default is spin.

  • Type: string
  • Default: null (the module’s own default)

The address Let’s Encrypt writes to; none is admin@<domain>.

  • Type: string
  • Default: null (the module’s own default)

Who the first administrator signs in as; none is admin@<domain>.

  • Type: string
  • Default: null (the module’s own default)

The host policy a runner starts with when it joins: shutdown_grace and preemption_source; modules/controlplane’s default is a spot runner on AWS with 100s.

  • Type: object({ shutdown_grace = optional(string) preemption_source = optional(string) })
  • Default: null (the module’s own default)

Where users reach the proxy on 443 from; modules/controlplane’s default is anywhere.

  • Type: list(string)
  • Default: null (the module’s own default)

The control plane’s machine; modules/controlplane’s default is t8i.medium.

  • Type: string
  • Default: null (the module’s own default)

The proxy’s machine; modules/controlplane’s default is t8i.micro.

  • Type: string
  • Default: null (the module’s own default)

The collector, as modules/controlplane’s collector object: how often metrics are pushed to it; modules/controlplane’s default is 60s. Where it sends is set in the dashboard.

  • Type: object({ metric_interval = optional(string) })
  • Default: null (the module’s own default)

The control plane’s disk, which /var - the database and the stores - takes all of past the OS; modules/controlplane’s default is 40.

  • Type: number
  • Default: null (the module’s own default)

Spin OS AMIs of your own, one per role - control-plane, runner and proxy - instead of those images.json names for spin_version in this region.

  • Type: map(string)
  • Default: null (the module’s own default)

The builds of each role’s image - control-plane, runner and proxy - oldest first, each the PCRs an instance of it measures (its manifest’s measurements), instead of measurements.json’s: the control plane’s key is answered to the control plane’s builds, a host joins only as the runner’s, and the proxy is given its token only as the proxy’s. The control plane’s and the runner’s also carry statement and bundle, base64, as spin-os images sign writes them. The last of a role’s is the image image_ids names. Required with image_ids, and for a release published before its PCRs were.

  • Type: map(list(object({ pcr4 = string pcr7 = string pcr12 = string statement = optional(string) bundle = optional(string) revoked = optional(string) })))
  • Default: null (the module’s own default)

The installation’s config file (spin’s configs/spin-example.yaml), as YAML: the control plane seeds its database from it at start, and shows a later change to it in the dashboard to apply or dismiss.

  • Type: string
  • Default: null (the module’s own default)

How long the fleet is idle before its runners’ group is emptied; modules/controlplane’s default is 60.

  • Type: number
  • Default: null (the module’s own default)

HH:MM-HH:MM in time_zone when an idle fleet is emptied at once; none is none.

  • Type: string
  • Default: null (the module’s own default)

The IANA zone quiet_hours are in; modules/controlplane’s default is UTC.

  • Type: string
  • Default: null (the module’s own default)

What the runners’ group may start, most preferred first, one CPU generation; see modules/runners.

  • Type: list(string)
  • Default: null (the module’s own default)

Every runner a spot instance; modules/runners’ default is true.

  • Type: bool
  • Default: null (the module’s own default)

An EBS volume for each runner’s data, for instance types with no local NVMe (none of sa-east-1’s with nested virtualization have one). modules/runners’ default, 0, uses the instance store.

  • Type: number
  • Default: null (the module’s own default)

Each runner’s root disk: the OS and the machine’s files. modules/runners’ default is 30.

  • Type: number
  • Default: null (the module’s own default)

Ask AWS for the vCPU quota max_runners runners need when the account’s is lower; modules/runners’ default is true.

  • Type: bool
  • Default: null (the module’s own default)

The most runners the group may have; the control plane decides how many it has. modules/runners’ default is 1.

  • Type: number
  • Default: null (the module’s own default)

How a new release reaches the runners: idle, when the fleet next empties, moving no workspace (modules/runners’ default); or rolling, replacing them at once, their workspaces suspended and resumed on the new hosts.

  • Type: string
  • Default: null (the module’s own default)

Set to true and apply before tofu destroy: the buckets lose their VPC-only policies and a destroy empties them, data included (README.md, “Removing an installation”). modules/controlplane’s default is false.

  • Type: bool
  • Default: null (the module’s own default)

What the installation may cost in a month, in US dollars: an AWS Budget the control plane reads and whose alerts go to budget_emails. Null is no budget.

  • Type: number
  • Default: null (the module’s own default)

Who is emailed when the month’s cost passes 80 % or 100 % of monthly_budget_usd, or is forecast to pass it.

  • Type: list(string)
  • Default: null (the module’s own default)

Tags on everything both modules create.

  • Type: map(string)
  • Default: null (the module’s own default)
OutputWhat it is
next_stepsWhat to do now that the apply is done, in order: DNS, the first sign-in, what the runners do, and how to reach a machine. Read it with tofu output -raw next_steps.
dashboardThe installation’s dashboard.
first_sign_inThe setup page, the first administrator, and the command that reads their one-time password: an SSM SecureString this apply wrote without it ever being in the state.
name_serversThe domain’s zone’s nameservers: what its registrar, or its parent’s zone, points at.
proxy_ipThe proxy’s elastic IP, where app.<domain>, tunnel.app.<domain> and *.ws.<domain> point: the one address of the installation the internet reaches.
controlplane_groupThe control plane’s group of one; its machine is reached with aws ssm start-session --target &lt;instance>.
update_statusAfter an apply that changed a machine: how its replacement went. Successful, InProgress, or RollbackSuccessful with the reason - after which the old machine serves again, at once or, for a control plane that had handed its database over, once its watch has restored it from the archive.
update_abortAfter an apply whose new machine will not come up: the command that stops waiting for it - rolls the refresh back and abandons the launch the hook still holds - so the next apply can change the group (task update:abort).
boot_logBy role, the command that reads what its machines’ boots said - the ones that are gone included - and follows the next one’s.
runners_groupThe runners’ group, which the control plane sizes: empty until a workspace waits for one.
controlplaneEverything modules/controlplane outputs.
runnersEverything modules/runners outputs.

Generated by task reference from spin-terraform-aws/variables.tf at 1557e9668.

Documents Spinbox v20261019.02. This page as Markdown, for a model or a terminal.