Files
cluster-autoscaler-with-capi/docs/plans-executions/2026-09-27-0058-mgmt-cluster-ansible.md
T
kacerrandClaude Opus 5.5 bfc0a9e15d Fix mgmt VM nameserver argument; record first vm run
mgmt_dns is a list, passed to qm create as one space-separated argument.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 09:31:57 +02:00

78 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Execution log: idempotent management cluster (Ansible + cluster-api-operator)
Pairs with [docs/plans/2026-09-27-0058-mgmt-cluster-ansible.md](../plans/2026-09-27-0058-mgmt-cluster-ansible.md).
## Status
- [x] Step 0 — Initial import commit + plan commit
- [x] Step 1 — Scaffold `ansible/`, `.gitignore` exception, syntax/lint checks
- [ ] Step 2 — Run the playbook tag by tag against the lab (owner)
- [ ] Step 3 — Idempotency check (second full run `changed=0`)
- [ ] Step 4 — Docs, versions, decisions, changelog
## Step 0 — Initial import + plan
The repo had no commits, so the existing tree went in first as `5fd998c` (after a grep for
token/secret/key material found only placeholders), then the plan alone as `ac7d5a4`.
## Step 1 — Scaffold `ansible/` (2026-09-27 01:02 CEST)
Wrote `ansible/{ansible.cfg,inventory.yml,group_vars/all.yml,secrets.yml.example,mgmt.yml}` and
four templates as planned. `ansible/secrets.yml` was already ignored by `*secret*`; added
`!ansible/secrets.yml.example`.
`ansible-core` is not installed on the laptop, so checks ran through `uvx` (cached, nothing
installed globally), pinned to ansible-core 2.18 (resolved 2.18.19):
```bash
cd ansible
uvx --from 'ansible-core>=2.18,<2.19' ansible-playbook mgmt.yml --syntax-check
uvx --with 'ansible-core>=2.18,<2.19' ansible-lint --profile production mgmt.yml
```
First lint run: 6× `name[casing]`, 5× `no-changed-when`. The commands flagged are the
create/resize/start/install tasks that only run behind a `when:` guard, so they got
`changed_when: true` rather than a fake condition. Second run: production profile passed.
Rendered all templates with dummy values (`-e mgmt_ip=192.0.2.10`, secret `DUMMY`) through a
throwaway local playbook: provider manifest parses as 11 documents (5 Namespaces, Secret, 5
provider CRs), k3s config and kubeconfig rewrite (`server` → VM IP, every `default` name →
`lab-mgmt`) come out as intended.
Connectivity to the PVE host:
```bash
uvx --from 'ansible-core>=2.18,<2.19' ansible pve -m ping -o
# pv1-1 | UNREACHABLE!: ... root@192.168.0.8: Permission denied (publickey,password).
```
**Worth noting:**
- The plan's assumption "root SSH from the laptop to `pv1-1` works" does not hold yet; the host
answers but rejects the laptop's keys. Needed before Step 2.
- Condition-based waits: the playbook waits for `Available` Deployments in each provider
namespace instead of a condition on the provider CRs, so it doesn't depend on the operator's
condition naming (plan left that open).
- VM params (`mgmt_vmid`, `mgmt_ip`, `mgmt_gateway`, `mgmt_dns`) are empty in `group_vars/all.yml`;
Play 1 asserts on them.
- `clusterctl` is not installed on the laptop either (needed for phase-1 Step 3, not for this playbook).
## Step 2 — Playbook runs (in progress)
### `--tags vm`, first attempt (2026-09-27 09:30 CEST, owner)
Owner authorised the laptop key on `pv1-1`, installed ansible locally and filled in VM params
(`mgmt_vmid: 201`, `mgmt_ip: 192.168.4.21/24`, gateway `192.168.4.8`).
```bash
ansible-playbook mgmt.yml --tags vm
# TASK [Create the VM]
# "cmd": [..., "--nameserver", "8.8.8.8,", "2.2.2.2"]
# stderr: 400 too many arguments
```
`mgmt_dns` was the string `"8.8.8.8, 2.2.2.2"`; the command module splits on whitespace, so
`qm` got two positional leftovers. Fix: `mgmt_dns` is now a list and the task passes
`--nameserver '{{ mgmt_dns | join(' ') }}'` as one argument (space-separated is PVE's format for
the cloud-init nameserver list). Image download and key staging had already succeeded and are
idempotent on re-run; `qm status 201` confirmed no half-created VM was left behind.