# Execution planes and worker groups

> The stack SquidCI runs builds in, inside your AWS account — connecting it, worker groups on EC2 or Lambda, sizing, spot, warm pools and schedules, and keeping it current.

An **execution plane** is the CloudFormation stack, in your AWS account and
region, that SquidCI's work runs in. The app calls it your AWS account: you
connect one from the **aws** page, as in
[Getting started](/docs/getting-started/).

## What it does

- **Runs jobs on worker groups**: pools of EC2 instances, or Lambda functions,
  which it creates and changes for you as child stacks.
- **Asks for work; is never sent it.** Workers claim jobs from SquidCI over
  HTTPS and report back. Nothing in your account accepts a connection from
  outside it.
- **Proves who it is** with a key that never leaves your account, and answers
  a challenge from SquidCI once a day. A plane that stops answering shows
  **! stale**.
- **Keeps its own code current.** SquidCI publishes signed releases of the
  plane's functions; the plane installs each one, and rolls back one that
  fails. The account's drawer shows the version, and can **pin** it.

What it creates, and the one permission it opens, are in
[Security](/docs/security/).

## Worker groups

A plane runs nothing until it has a worker group. Add one under the account,
with **+ add a worker group**.

### EC2: jobs in containers

The default, and what anything needing a shell, Docker or a checkout runs on.

- **instance type**: amd64 (`t3`, `c7i`, `m7i`, `r7i`) or arm64 Graviton
  (`t4g`, `c7g`, `m7g`, `r7g`). A job runs only on its own architecture —
  `runner.arch` in the pipeline file, amd64 when it says nothing.
- **size**: the fewest and most instances. The maximum is a spending limit,
  not a target: SquidCI never starts more however much work is queued. A
  minimum of 0 costs nothing while there is no work.
- **idle window**: how long an idle instance is kept before it is stopped.
- **market**: **on-demand**, or **spot** — much cheaper, but AWS can reclaim
  an instance at two minutes' notice, and its jobs go back in the queue.
  Deploys, and components with `runner.spot: false`, never run on spot.
- **warm pool** (on-demand): instances kept stopped when the group scales in,
  so the next job wakes one rather than waiting for a boot. Asleep, an
  instance costs only its disk.
- **schedule**: periods — days, times and a time zone — with their own minimum
  and maximum inside the group's, say `Mon–Fri 09:00–18:00` at 2 to 8. The
  first period that holds sets the bounds; outside them, the group's own do.

Several jobs share an instance: each reserves `runner.vcpus` of it, 1 when the
pipeline file says nothing. Jobs run in containers under
[Sysbox](https://github.com/nestybox/sysbox), so a job can run Docker without
being privileged.

### Lambda: a function per job

For pipeline components with `runner.lambda`: each step is TypeScript or
JavaScript run in a Node.js function, with no shell, checkout or Docker, for
at most 14½ minutes. Quick to start, and nothing to keep running. Set the
**memory** (which sets CPU too) and how many jobs run **at once**.

Each Lambda job uses two of the functions your account may run at once in
the region — 10 in a new account, shared with everything else there. The
account's drawer shows the figure and links to AWS's page to raise it.

## Target AWS accounts

A job's own credentials reach only what the plane gives every job: its run's
artifacts. To deploy anywhere, a job assumes a role in a **target AWS
account**, which you add under the plane. See
[AWS access for jobs](/docs/pipelines/aws/).

## Keeping the stack current

The drawer's **template** line says when SquidCI ships a newer version of the
stack, and what changed; **update the stack** opens CloudFormation to apply
it. The plane's code updates by itself and needs no stack update.

**disconnect** forgets the account and its worker groups, and stops sending it
work. It removes nothing from AWS: delete the SquidCI stack there too.
