Skip to content

Declare eden and ragnarok in tofu (ADR-0076's scope), and settle how ragnarok's isolation proof survives it #1443

Open

Description

@Gerrrt

Finding

ADR-0076's scope names "#421's attack VM and targets". Two guests are built outside the pipeline, so tofu can't rebuild either:

  • eden (BloodHound, VMID 141 on Saruman) is a hand qm clone 901 141 (build-the-bloodhound-guest.md:71);
  • ragnarok (the attack VM, VMID 130 on gandalf) comes from scripts/make-attack-vm.sh.

Decided

Declare both in tofu (owner's choice on audit finding #18, over superseding ADR-0076).

What has to be settled first: why this is an issue and not yet a PR

  1. A second provider. phoenix.env and gandalf.env export the same names (PROXMOX_URL, PROXMOX_TOKEN_ID, PROXMOX_TOKEN_SECRET), and make-attack-vm.sh refuses to run unless PROXMOX_URL is gandalf's. A provider "proxmox" { alias = "gandalf" } needs its own variables (for example TF_VAR_gandalf_endpoint and a token), with gandalf's CA trusted on phoenix (already true, per build-the-lab-templates.md §5), and an ACL so phoenix@pve on gandalf can create VMID 130.

  2. ragnarok is more than a clone. make-attack-vm.sh also:

    • sets net1 on vmbr1 with no gateway (172.30.30.10/24);
    • writes 99-no-forward.conf;
    • proves §8 check three (forwarding off, no NAT) over SSH, against a host key read through the guest agent (ADR-0085).

    tofu can make the VM and its NICs. The no-forward sysctl and the proof are not tofu's job. Either make-attack-vm.sh keeps them as a post-apply --verify-only, or that moves into the module's cloud-init plus a separate proof script. ADR-0017 says the range is "rebuilt, not repaired" by that script, so this probably wants a short ADR that amends 0017 and 0076.

  3. Identities. Both MACs go in tofu/identities.auto.tfvars (tofu/guests.tf publishes 15 full guest MACs and 6 SMBIOS UUIDs, against security.md's do-not-publish list #1420's file); ragnarok has no reservation today (net0 is DHCP from the pool).

  4. Import, then plan. Import both, and require a plan of No changes before any apply. eden holds the BloodHound graph, and a replace would lose it.

Steps once 1 and 2 are decided

tofu/ gets the gandalf provider, then the eden and ragnarok entries, then import blocks. phoenix runs plan (it must say No changes) and then make-attack-vm.sh --verify-only. Then the runbooks (build-the-bloodhound-guest.md, build-the-playground.md §5) switch to the pipeline.

Source: Phase 1 audit, finding #18.

Activity

  1. Gerrrt commented on Nov 11, 2026

    @Gerrrt
    OwnerAuthor

    The owner has made the two design calls:

    1. gandalf is reached through an aliased provider in the same state. provider "proxmox" { alias = "gandalf" } takes its endpoint and token from new TF_VAR_gandalf_endpoint and TF_VAR_gandalf_api_token lines in gandalf.env. phoenix.env is unchanged. The cost, accepted: every plan needs gandalf.env sourced and gandalf reachable.
    2. tofu builds ragnarok, and the script proves it.
      • The guest module gains a second-NIC option.
      • cloud-init gives net1 172.30.30.10/24 with no gateway, and writes 99-no-forward.conf.
      • make-attack-vm.sh becomes a --verify-only proof that runs after every apply: forwarding off and no NAT, checked against a host key read through the guest agent (ADR-0085).
      • A short ADR amends ADR-0017 ("rebuilt by that script") and ADR-0076.

    Order: eden first, in its own PR. It needs neither call, since it is on Saruman behind the existing provider. ragnarok follows, with the gandalf provider and the ADR.


    Generated by Claude Code

  2. Gerrrt commented on Nov 12, 2026

    @Gerrrt
    OwnerAuthor

    Both halves are up: eden in #1463, and ragnarok, with ADR-0116, in the PR that follows it. Two refinements to the calls recorded above:

    • The TF_VAR_gandalf_* lines go in phoenix.env, not gandalf.env. That way every existing runbook step that sources phoenix.env before a plan keeps working. In gandalf.env, six runbooks' steps would need both files.
    • The sysctl file stays in the script (owner's choice). make-attack-vm.sh becomes finish-attack-vm.sh. After every apply it reads the config back, writes 99-no-forward.conf and runs the proof. Putting the file in cloud-init would need tofu to upload a snippet to gandalf over SSH, a second credential path for one file.

    Neither guest can reach "No changes" from an import, because tofu can't read back how a hand-built guest was cloned. Both runbooks therefore rebuild: eden is import, plan (one replace), destroy, apply; ragnarok is destroy, then apply. ADR-0081 and ADR-0017 accept the loss for each.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions