Repository navigation
Packer templates for the lab domain, built from phoenix (#440) - #792
Merged
Merged
Conversation
…#440) Packer goes in a top-level packer/, not under stacks/. The templates take VMIDs 901-912, and guests are full clones so a template can be rebuilt in place with -force. Every Windows build ends in sysprep /generalize, which gives each clone a fresh SID. The issue proposed rebuilding and renaming the template, but every clone of a rebuilt template would still share one SID. The token and build password stay in phoenix.env. That settles ADR-0043's deferred encrypted-in-repo question: phoenix has no age key to decrypt one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…erver 2025 (#440) Four proxmox-iso sources, run from phoenix through Saruman's API: - Ubuntu installs by autoinstall from a cidata disc. - Kali installs by preseed over Packer's HTTP server. It is written but not built, because its consumer lives on ifrit. - The two Windows editions install from an Autounattend disc with the VirtIO drivers, then sysprep /generalize /quit. scripts/packer-smoke.sh full-clones a template, waits for the guest agent's address, checks the hostname (and SSH for Linux), and destroys the clone. scripts/lint.sh gains packer fmt -check and validate -syntax-only, run from a pinned hashicorp/packer image behind the lint profile. The new runbook, build-the-lab-templates.md, covers the build, the token's added privileges, the SID check and the rebuild. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Changelog entry, roadmap chain, phoenix's architecture row, and pointers from build-the-jumpbox.md (the role has grown; the token's encrypted form was decided against) and build-the-lab-domain.md section 7 (the template is the rebuild path when the evaluation clock runs out). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The ADR, the runbook's section 5, the changelog, the roadmap, packer/README.md and kali.pkr.hcl said "a follow-up issue". It now exists, so they name it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…40-a85459 # Conflicts: # README.md # docs/architecture.md # docs/changelog.md
main took 0071 for the disposable investigation guest (#438) and 0072 for the ISO store (#446) while this branch was open. The file is renamed, and every reference to the Packer ADR follows it. References to #438's ADR-0071 are left as they were. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Windows readiness detection, TLS verification, password validation, Kali instructions, and deployment-status documentation need correction.
Review effort: Balanced
Findings: 1
Open (6)
Enable certificate verification for PhoenixBuilder connections · New Select ifrit storage and validate VMID 902 there · New Enforce Windows password complexity rules during validation · New Gate Windows success on post-SetupComplete readiness · New Correct ADR template status to reflect no builds · New Mark unbuilt templates as pending in the inventory · New
What changed in this PR
Adds Packer-based Proxmox VM templates and supporting automation for the lab.
Changes:
- Defines Ubuntu, Kali, Windows 11, and Server 2025 templates.
- Adds template smoke testing and CI linting.
- Documents build, rebuild, and operational procedures.
| File | Description |
|---|---|
stacks/observability/compose.yaml |
Pins the Packer lint image. |
scripts/packer-smoke.sh |
Adds clone-based template smoke testing. |
scripts/lint.sh |
Runs Packer format and syntax checks. |
scripts/check_container_health.py |
Documents the profiled Packer service. |
README.md |
Updates ADR and runbook counts. |
packer/windows/unattend-oobe.xml.pkrtpl |
Configures clone OOBE. |
packer/windows/scripts/sysprep.ps1 |
Generalizes Windows images. |
packer/windows/scripts/SetupComplete.cmd |
Removes temporary WinRM access. |
packer/windows/scripts/bootstrap.ps1 |
Installs guest tools and enables build WinRM. |
packer/windows/autounattend.xml.pkrtpl |
Automates Windows installation. |
packer/windows.pkr.hcl |
Defines both Windows templates. |
packer/versions.pkr.hcl |
Pins Packer and the Proxmox plugin. |
packer/variables.pkr.hcl |
Defines shared build inputs. |
packer/ubuntu/user-data.pkrtpl |
Provides Ubuntu autoinstall configuration. |
packer/ubuntu.pkr.hcl |
Defines the Ubuntu template. |
packer/README.md |
Documents the template inventory. |
packer/kali/preseed.cfg.pkrtpl |
Provides Kali preseed configuration. |
packer/kali.pkr.hcl |
Defines the deferred Kali template. |
docs/runbooks/build-the-lab-templates.md |
Adds the template build runbook. |
docs/runbooks/build-the-lab-domain.md |
Documents template-based rebuilds. |
docs/runbooks/build-the-jumpbox.md |
Records additional Packer privileges. |
docs/roadmap.md |
Tracks Packer implementation status. |
docs/changelog.md |
Records the unbuilt template sources. |
docs/architecture.md |
Adds Packer to phoenix’s responsibilities. |
docs/adr/0073-build-the-lab-templates-with-packer-from-phoenix.md |
Records the template architecture decision. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…40-a85459 # Conflicts: # README.md # docs/changelog.md
Gerrrt
enabled auto-merge (squash)
October 1, 2026 16:14
) Review on the PR: - TLS is verified. The token rides in a header on VLAN 30, which the attack VM shares, so skipping verification would hand it to any guest answering for 10.0.30.110. phoenix trusts the cluster CA (runbook section 2). packer-smoke.sh drops -k. - build_password needs all four character classes. A password Windows Setup would refuse now fails validation first. - QEMU-GA is disabled before sysprep, and SetupComplete.cmd starts it last. A Windows clone's first agent answer, which the smoke test waits on, now means first-boot Setup has finished. - The Kali steps name ifrit's storage, API and smoke test (#790). - The ADR and packer/README.md say which node each template is for, rather than "built". Also renumbers the Packer ADR to 0074. main took 0073 for the household copy (#455) while this was open. References to #455's ADR-0073 are untouched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gerrrt
added a commit
that referenced
this pull request
Oct 1, 2026
…-iso (#446) #792 merged while this branch was open. Its Packer defaults put the ISOs on local storage (iso_storage = local, local:iso/... file names), and no step verifies a checksum. The roadmap sentence said #440 builds from smaug-iso, which is not true yet. It now says what moving the builds there takes, and that the checksum step still has to come first. Refs #446 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gerrrt
added a commit
that referenced
this pull request
Oct 1, 2026
* docs: the ISO store is built, and Saruman mounts it (#446) build-the-nas.md §5b, done on 2026-10-01: - smaug: erebor/iso at recordsize 1M, owned by pippin (3003:3002), shared over NFSv4 to 10.0.30.110 alone with root mapped to pippin. - morpheus: `Allow NFS from Saruman to smaug` printed directly above igc0.30's Block access to CasaBonita in pfctl -sr -vv. - Saruman: the fstab mount shows the 500G quota, and smaug-iso is an active dir storage. A web-UI upload of virtio-win-0.1.302.iso landed owned by pippin, not root. - alexander and the monitoring host are refused on 2049. The igc0.40 tripwire reads 0 packets after 260,980 evaluations. The rule moves from specified to created in build-the-nas.md §0.5, network.md, security.md and stacks/media/README.md. network.md's ImaginationLAN notes now name the block, as build-the-backup-guest.md §4 asked. The roadmap entry folds into #440's: build from smaug-iso, and verify each ISO's checksum first. Also recorded: the step's apt install finished a half-configured alloy upgrade on Saruman, and /etc/default/alloy was kept. Closes #446. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: remove the changelog's conflict markers, and count the NFS pass (#446) The previous commit carried stash conflict markers in changelog.md. A merge of main auto-stashed the edits, and the re-apply conflicted where #455's entry landed on the same date. Both entries are kept and the markers are gone, which is what failed Lint. Review on the PR: - network.md said "Six exist today" for the Hicks and Winterfell passes, but they were already seven: four, then 4533, 445 and 13378. It now says seven, and the NFS pass makes eight. - stacks/media/README.md names Saruman as a fifth consumer. It also says the 2049 export differs from the three media ports: CasaBonita can open the port, but the export answers 10.0.30.110 alone. Refs #446 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(roadmap): #440's merged templates read from local, not yet smaug-iso (#446) #792 merged while this branch was open. Its Packer defaults put the ISOs on local storage (iso_storage = local, local:iso/... file names), and no step verifies a checksum. The roadmap sentence said #440 builds from smaug-iso, which is not true yet. It now says what moving the builds there takes, and that the checksum step still has to come first. Refs #446 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



What changed
This adds a top-level
packer/with four Proxmox templates: Ubuntu 26.04 (901), Kali (902, written but not built), Windows 11 Pro (911) and Server 2025 evaluation (912). They are built fromphoenixthroughSaruman's API.scripts/packer-smoke.shproves a template by cloning it, booting it, checking the agent's address and the hostname, and destroying the clone.scripts/lint.shnow runspacker fmt -checkandpacker validate -syntax-onlyfrom a pinnedhashicorp/packer:1.16.1image.Nothing runs in the lab until the runbook is followed. No template has been built yet.
Why
#440. When
LabWindowsEvaluationExpiringfires, the only answer today isbuild-the-lab-domain.md§1–§4 done by hand. This makes the image a command.The commits follow this repo's usual order:
maintook 0071 (A disposable investigation stack, so an incident does not touch odin's durable store #438), 0072 (Put the ISO store on smaug, and add the fifth inbound rule ADR-0016 did not write down #446) and 0073 (Buy the off-estate drive, and decide what ADR-0023 needs beyond a drive #455) while this was open, so it was renumbered twice.-force.phoenix.env, which settles ADR-0043's deferred question.sysprep /generalizeis the SID fix. The issue proposed rebuilding and renaming the template, but every clone of one template still shares its SID.build-the-lab-templates.md.architecture.md, and notes inbuild-the-jumpbox.mdandbuild-the-lab-domain.md§7.ifrit.main, resolving the README counts (now 74 ADRs, 39 runbooks), thearchitecture.mdtable and the changelog, each followed by a renumber.1c4b75c:-k.SetupComplete.cmd, so the smoke test proves first-boot setup finished.ifrit's storage, API and smoke test.packer/README.mdno longer read as if a template exists.Blast radius
None at merge. CI gains two
packerlint calls, andstacks/observability/compose.yamlgains alint-profile service thatmake upneither pulls nor starts.When the runbook is followed:
PhoenixBuildergains/storage/large_dataandVM.GuestAgent.Audit(runbook §2).phoenix's trust store gains Saruman's cluster CA,/etc/pve/pve-root-ca.pem(runbook §2). This is the public certificate, not its key. Packer and the smoke script verify the API with it, so the token is never sent to an unverified host on VLAN 30.Builds create VMIDs 901, 911 and 912, and VMID 999 for each smoke test.
No change to network segmentation or firewall rules. Kali's build needs port 8800 on
phoenixwhile it runs, but only onifrit(Build tpl-kali (VMID 902) on ifrit once it exists #790).No new port published to a VLAN that could not already reach the service
No credential added outside
secrets/*.sops.yaml. Deliberately unticked. The newPKR_VAR_build_passwordlives in~/.config/proxmox/phoenix.envbeside the existing token, becausephoenixholds no age key (ADR-0043, ADR-0074 part 4). Nothing secret is in git.Verification
Run on a workstation without Docker:
scripts/lint.shpasses yamllint, markdownlint, shellcheck,packer fmt/validate -syntax-onlyand editorconfig-checker. actionlint was skipped (it needs Docker).A full
packer validatewith the pinned plugin, v1.2.4, passes. The rendered Autounattend and OOBE files parse as XML, and the autoinstall seed parses as YAML.check_docs.py,check_image_pins.py,check-tracked-artefacts.shandcheck-sops-encrypted.shpass, and gitleaks finds no leaks. Microsoft's public generic Windows 11 Pro install key is allowed inline with a comment.pin-digests.shconfirms thehashicorp/packerdigest.make validatepasses. Its Docker-backed checks were skipped here, andcheck_mounted_config.py --self-testfails only because it callsdocker. CI is the real run.Deployed to the lab and confirmed working. Build the lab's VM templates with Packer, so the domain's evaluation clock stops costing a day #440 stays open until runbook §4–§8 on
phoenix: build, smoke-test, SID check, then rebuild with-forceand smoke-test again.Docs updated (
docs/, service README, ordocs/roadmap.md)Refs #440, #790.
🤖 Generated with Claude Code