OpenStack setup¶
Prepare the provider before following the Quickstart. For each configuration key, see the OpenStack reference.
Tenant and project¶
Run taloscluster as a user in the project where the cluster will live. The application credential is scoped to a project, and that project's name becomes the ncsa/project node label; converge never reads another project's tenant. Give the project enough quota for everything the cluster owns (see Service quotas below).
Application credentials¶
Create an application credential with python-openstackclient (the openstack CLI, available via uv sync --extra openstack):
openstack --os-project-name myproject application credential create taloscluster
Copy the output id into openstack.credential_id and the secret into openstack.credential_secret in secrets.yaml, replacing the scaffolded CHANGE-ME values:
# secrets.yaml
openstack:
credential_id: "CHANGE-ME"
credential_secret: "CHANGE-ME"
taloscluster authenticates to the Keystone identity endpoint with the v3applicationcredential auth type (OS_AUTH_TYPE=v3applicationcredential). It refuses a null, empty, or still-scaffolded credential at secrets load time instead of failing later as an opaque 401. Create one credential per cluster (or reuse a name); the credential's project is the only project the session can see.
Required services¶
The provider touches five services during a converge. All must be present and reachable in the configured region (RegionOne by default):
- Keystone (identity) — the
openstack.urlendpoint and the session scoping, including theregionand the project label. - Nova (compute) — flavors and servers; each server is created volume-backed.
- Neutron (network) — the tenant network, subnet, router, ports, security group and floating IPs.
- Glance (image) — the shared Talos boot image, built and uploaded once per
talos.versionand base schematic. Changing the base extension set yields a new image identity under a new name rather than reusing a stale one. The image needs a minimum 20 GB disk and 2 GiB RAM (min_disk=20,min_ram=2048) and thehw_qemu_guest_agent=yesproperty so the baked QEMU guest agent attaches its virtio-serial channel. - Cinder (volume) — the boot volumes behind each server; converge reads a server's boot volume size through Cinder to detect a
diskchange.
Out-of-region or absent services cause a fail-fast error at the phase that needs them. openstack region list shows the available regions; if your cloud's region is not the default (RegionOne), copy your region's name into openstack.region (see The configured region).
Service quotas¶
A single cluster creates the following project-owned resources, so size the project quota accordingly (multiply per node for the per-server items):
| Resource | Count | Notes |
|---|---|---|
| Server (VM) | nodes | one per machine |
| Boot volume | nodes | volume-backed, delete_on_termination |
| Port | nodes + 2 | one per machine plus one each for the API and ingress VIPs |
| Floating IP | 2 | one for the Kubernetes API, one for ingress |
| Network | 1 | the tenant network from network.cidr |
| Subnet | 1 | the subnet underlying network.cidr |
| Router | 1 | attached to the external network |
| Security group | 1 | named for the cluster |
| Image | 1 | shared across all nodes (and potentially clusters) on the same talos.version |
The two floating IPs come from the external network's pool. If the project's floating-IP quota is at its limit, converge fails at the network phase; free one or raise the quota. The boot-volume quota must cover disk (GB) for every node.
The configured region¶
RegionOne is the default region: openstack.region is optional and may be omitted for the common case. The session connects in the configured region, and the same region is what status, the env command, and the ArgoCD cluster-apps values report. If your cloud serves more than one region, set openstack.region to the one hosting your project's resources (the endpoint and service catalog must agree).
External-network selection¶
openstack.external_net names the provider (external) network the cluster router and the two floating IPs attach to. It must be a real external network with available floating-IP addresses and an upstream route; taloscluster does not create one for you. It looks the network up read-only by name and refuses to proceed if it is not found, so use the name exactly as it appears to your project (for example ext-net):
openstack:
url: https://openstack.example.edu:5000/v3/
availability_zone: nova
external_net: ext-net
region: RegionOne
The router gets the external network as its external gateway; the subnet's nodes reach it through the router, and the API and ingress floating IPs are each associated with a reserved port on the private network. Servers themselves get no floating IP — only the router's gateway address and the two floating IPs are exposed.
Availability zones and flavors¶
Pick an availability_zone (for example nova) with enough free capacity. Every server is created volume-backed in that zone from the shared boot image. The Glance image is region-scoped, so it lives in the same region as the servers — no public visibility is required.
Each pool names its flavor (see Pools); the flavor must exist and be public to the credential's project, with at least the image's min_disk/min_ram:
controlplane:
count: 3
flavor: gp.medium
disk: 40 # GB boot volume
workers:
worker:
count: 3
flavor: gp.xlarge
disk: 100
The configured flavor may be a name or an id. disk is the boot volume size in GB, which may exceed the flavor's own disk. Servers are create-only: converge refuses a later flavor, disk, or availability_zone change on an existing node (recreate it by scaling its pool down past it and back up) rather than silently ignoring it, and plan reports the same refusal.
Management access¶
taloscluster reaches the Talos API on port 50000 of a real node address to bootstrap and manage the cluster, and clients reach the Kubernetes API on the floating IP on port 6443. On OpenStack the nodes sit on the private tenant network with no public address and no SSH, so you must get taloscluster to a node address from your management machine — usually through Tailscale:
- Install and connect Tailscale on the machine you run
talosclusterfrom so it is already on the same tailnet; taloscluster does not add it. Each node joins at boot using thetailscale.auth_keyinsecrets.yaml. - On OpenStack without Tailscale, a bastion host or a VPN into the tenant network is your only path to a node; the tool falls back to the provider-reported address, which you must then reach.
- Include the management network and the tailnet in the
securitykubernetes(tcp/6443) andtalos(tcp/50000) allowlists, plus anyhttps/httprules you restrict. The cluster security group carries these rules on every port, and the two VIP ports carry the cluster security group explicitly so the allowlists apply at the floating IPs too.
Converge allocates the Kubernetes API VIP and floating IP for you during the network phase; there is no kubeapi_vip key on OpenStack. Use eval "$(taloscluster env)" to export the connection environment (including the configured region) for troubleshooting with openstack; it prints the credential secret, so use it via eval rather than logging it.