k8s-management — Ansible configuration

Ansible project that configures the k8s-management Proxmox LXC container (ID 105) over SSH:

RoleWhat it does
ssh_serverInstalls/enables openssh-server, creates the jan login (member of sudo, passwordless sudo), installs the control-node public key for jan and root, and hardens sshd (key-only logins, root restricted to keys) through /etc/ssh/sshd_config.d/99-k8s-management.conf.
toolsInstalls the base CLI packages plus talosctl and kubectl (latest stable by default) and enables kubectl bash completion.

Layout

a├├├├├└n──────s──────ibahrsgr├││││└lnoeiro──essqtol──/itueuebsi.pss├├├└t├└l.ry_/s────o──eyemh────o──.mmla_lclersdhttsdtfnseeaae/eagt/rfnsmfssavadkpak.leulslusylrle/al/m./trmttmlyssaesam//is/ilmmnmnaa.sa.iiysiynnmhnm..ld.lyy_ymmcmllol#####nfciapuionnlsgnvsae.teiyrdrnbbs/otlo,9loeo9-r.kk-nyp:eko:oy8dssssetis,-hxhmce_saocssnncoehafolrdginlvegtee+macre(ittnini+otneoo.vrntlce'oonsosntlefohst.rotjym+i2,en-vgkneseeryti,wfoibrcekactoaimdoedn)ress

Prerequisites

Usage

cd ansible
ansible-galaxy collection install -r requirements.yml   # once
ansible-playbook site.yml

Logging in from another server

The remote login name is always jan (the account that exists on the container). The client machine does not need a local jan account — it only needs a private key whose public key is authorized on the container:

Notes:

Inventory and the container address

hosts.yml points at the container’s DHCP address on the home network (vmbr0). This is deliberately not 10.10.50.10: that address lives on the isolated vmbr1 bridge and is only reachable from inside the Talos subnet.

If the DHCP lease changes, override it for a run:

ansible-playbook site.yml \
  -e "ansible_host=$(cd .. && tofu output -json management | jq -r .wan_ips.eth0)"

Variables

All defaults live in group_vars/all.yml:

VariableDefaultPurpose
admin_userjanLogin created on the container.
admin_groups[sudo]Supplementary groups for the login.
ssh_public_key_path~/.ssh/id_ed25519.pubKey installed for jan and root.
ssh_extra_authorized_keys[]Extra public keys authorized for jan (other servers/operators).
ssh_authorized_keys_exclusivefalseWhen true, remove any keys not listed above.
sshd_password_authenticationfalseInteractive password logins.
sshd_permit_root_loginprohibit-passwordRoot may log in with a key only.
sshd_allow_usersroot janAccounts sshd accepts.
talosctl_version"" (latest)Pin a talosctl release.
kubectl_version"" (stable)Pin a kubectl release.
tools_packagessee fileBase CLI packages.

Verification

The playbook finishes by asserting the effective sshd configuration is key-only and reporting the installed versions. You can also check by hand:

ssh jan@<container> 'whoami; id; sudo -n whoami'
ssh jan@<container> 'talosctl version --client --short; kubectl version --client'

Relationship to the OpenTofu bootstrap

management.tf only bootstraps the container: it brings the interfaces up and seeds root’s authorized key so Ansible can connect. Everything else — the SSH server, the jan login and the tooling — is owned by this project, so the container’s boot script no longer installs anything.

The container entrypoint is written at creation time, so a change to the boot script only takes effect after a recreate:

tofu apply -refresh=false -auto-approve \
  -replace=proxmox_virtual_environment_container.management \
  -target=proxmox_virtual_environment_container.management

Security notes