> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siderolabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GitHub Actions

> Creating an ephemeral Talos Kubernetes cluster on a GitHub Actions runner.

This guide creates a short-lived Talos Kubernetes cluster on a GitHub Actions runner, for example to run end-to-end tests against real Talos nodes in CI.

It uses [talosctl-cluster-action](https://github.com/home-operations/talosctl-cluster-action), a GitHub Action that wraps `talosctl cluster create`.
The action creates the cluster from a declarative configuration file, exports `KUBECONFIG` and `TALOSCONFIG` to later steps in the job, and destroys the cluster when the job ends.

> [!NOTE]
>
> talosctl-cluster-action is a community project maintained by home-operations, not by Sidero Labs.
> Report problems with the action in its [repository](https://github.com/home-operations/talosctl-cluster-action/issues).

## Requirements

The runner and the cluster must meet the following requirements:

* An x86\_64 Linux runner. GitHub-hosted `ubuntu-24.04` runners meet the requirements of both providers described below.
* `talosctl` v1.14 or later on the runner's `PATH`.
* Talos v1.14 or later on the cluster nodes.

The action rejects earlier versions of both `talosctl` and Talos.

## Create a cluster

To create a cluster, choose a provider, then add a cluster configuration file and a workflow to the repository.

The action supports two providers, which map to `talosctl cluster create docker` and the QEMU provisioner.
The provider is set with `spec.provider` in the cluster configuration file, and the providers differ as follows:

| | `docker` | `qemu` (default) |
| - | - | - |
| Nodes run as | Containers on the runner's kernel | Virtual machines, each with its own kernel |
| Control plane nodes | Exactly one | Any number |
| Disks and `talosctl upgrade` | Not supported | Supported |
| Runner needs | A Docker daemon and the `br_netfilter` kernel module | `/dev/kvm`, passwordless `sudo`, and QEMU packages |
| Boot time | Seconds | Minutes |

Use `docker` when a test only needs a Kubernetes API.
Use `qemu` when a test needs real kernels, disks, or Talos upgrades.

**Docker**

The Docker provider runs each node as a container on the runner, and the cluster boots in seconds.

1. Save the cluster configuration to `.talos-cluster.yaml` in the repository:

   apiVersion: v1alpha1
   kind: TalosCluster
   metadata:
   &#x20; name: e2e
   spec:
   &#x20; provider: docker
   &#x20; workers:
   &#x20;   count: 1
   &#x20; docker:
   &#x20;   image: ghcr.io/siderolabs/talos:v1.14.4

   The Docker provider always creates exactly one control plane node, so the configuration sets only the number of workers.

2. Add a workflow, for example `.github/workflows/e2e.yaml`:

   name: e2e

   on:
   &#x20; pull\_request:

   jobs:
   &#x20; e2e:
   &#x20;   runs-on: ubuntu-24.04
   &#x20;   steps:
   &#x20;     \- uses: actions/checkout\@v7

   &#x20;     \- name: Install talosctl
   &#x20;       run: |
   &#x20;         curl -sSfL -o "\$RUNNER\_TEMP/talosctl" https\://github.com/siderolabs/talos/releases/download/v1.14.4/talosctl-linux-amd64
   &#x20;         sudo install -m 0755 "\$RUNNER\_TEMP/talosctl" /usr/local/bin/talosctl

   &#x20;     \# The nodes are containers on the runner's kernel, and the pod network
   &#x20;     \# requires the br\_netfilter module, which runners do not load by default.
   &#x20;     \- name: Load br\_netfilter
   &#x20;       run: sudo modprobe br\_netfilter

   &#x20;     \- name: Create Talos cluster
   &#x20;       uses: home-operations/talosctl-cluster-action\@v0.2.2
   &#x20;       with:
   &#x20;         config: .talos-cluster.yaml

   &#x20;     \- name: Check the cluster
   &#x20;       run: kubectl get nodes

   Without the `br_netfilter` module, the pod network never becomes ready and cluster creation times out.

3. Commit both files and open a pull request.

**QEMU**

The QEMU provider runs each node as a virtual machine with its own kernel, and supports disks and Talos upgrades.

1. Save the cluster configuration to `.talos-cluster.yaml` in the repository:

   apiVersion: v1alpha1
   kind: TalosCluster
   metadata:
   &#x20; name: e2e
   spec:
   &#x20; controlplanes:
   &#x20;   count: 1
   &#x20; workers:
   &#x20;   count: 1
   &#x20; qemu:
   &#x20;   talos-version: v1.14.4

2. Add a workflow, for example `.github/workflows/e2e.yaml`:

   name: e2e

   on:
   &#x20; pull\_request:

   jobs:
   &#x20; e2e:
   &#x20;   runs-on: ubuntu-24.04
   &#x20;   steps:
   &#x20;     \- uses: actions/checkout\@v7

   &#x20;     \- name: Install talosctl
   &#x20;       run: |
   &#x20;         curl -sSfL -o "\$RUNNER\_TEMP/talosctl" https\://github.com/siderolabs/talos/releases/download/v1.14.4/talosctl-linux-amd64
   &#x20;         sudo install -m 0755 "\$RUNNER\_TEMP/talosctl" /usr/local/bin/talosctl

   &#x20;     \- name: Install QEMU
   &#x20;       run: |
   &#x20;         sudo apt-get update
   &#x20;         sudo apt-get install -y --no-install-recommends qemu-system-x86 qemu-utils ovmf

   &#x20;     \# Swap for the runner, not the cluster. When memory runs short, for example
   &#x20;     \# during an upgrade, the runner swaps out a node's QEMU process instead of
   &#x20;     \# killing it.
   &#x20;     \- name: Enable swap
   &#x20;       run: |
   &#x20;         sudo fallocate -l 8G /mnt/e2e-swapfile
   &#x20;         sudo chmod 600 /mnt/e2e-swapfile
   &#x20;         sudo mkswap /mnt/e2e-swapfile
   &#x20;         sudo swapon /mnt/e2e-swapfile

   &#x20;     \- name: Create Talos cluster
   &#x20;       uses: home-operations/talosctl-cluster-action\@v0.2.2
   &#x20;       with:
   &#x20;         config: .talos-cluster.yaml

   &#x20;     \- name: Check the cluster
   &#x20;       run: kubectl get nodes

   The QEMU provisioner must run as root, so the action runs `talosctl cluster create` with `sudo`.
   Each QEMU node uses 2 GiB of memory by default. Runners for public repositories have 16 GB, which fits about three nodes. Runners for private repositories have 8 GB, which fits two.

3. Commit both files and open a pull request.

Both workflows create the cluster on every pull request and destroy it when the job ends, including when a step fails.

## Use the cluster in later steps

After the action runs, `kubectl` and `talosctl` in later steps use the new cluster, because the action exports `KUBECONFIG` and `TALOSCONFIG`.

The action also sets outputs, such as the address of the first control plane node.
To use an output, give the action step an `id`:

```yaml theme={null}
      - name: Create Talos cluster
        id: cluster
        uses: home-operations/talosctl-cluster-action@v0.2.2
        with:
          config: .talos-cluster.yaml

      - name: Check Talos
        run: talosctl -n "$ENDPOINT" version
        env:
          ENDPOINT: ${{ steps.cluster.outputs.endpoint }}
```

The [action's README](https://github.com/home-operations/talosctl-cluster-action#outputs) lists every output, including the control plane and worker addresses.

## Default settings for short-lived clusters

By default, the action applies an `ephemeral` profile that tunes the cluster for a single CI run.
For example, it disables etcd `fsync`, image garbage collection, pod eviction, and the public discovery service.
These settings are not suitable for a long-lived cluster.

To create the cluster without these settings, set `spec.profile: none` in the cluster configuration file.

## More options

The [talosctl-cluster-action README](https://github.com/home-operations/talosctl-cluster-action#readme) describes the rest of the configuration, including:

* Every field of the cluster configuration file and the `talosctl` flag it maps to.
* Image Factory schematics, extra disks, and configuration patches.
* Caching boot assets between runs with the `cache` input.
* Running several cluster shapes in a job matrix.
* Booting nodes in maintenance mode without applying a machine configuration.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.