Skip to content

feat(operating_systems): bootstrap Windows Server 2022 - #83

Merged
NWarila merged 3 commits into
mainfrom
feat/windows-server-2022
Sep 1, 2026
Merged

feat(operating_systems): bootstrap Windows Server 2022#83
NWarila merged 3 commits into
mainfrom
feat/windows-server-2022

Conversation

@NWarila

@NWarila NWarila commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a Windows_Server_2022 bootstrap role beside Windows_Server_2025, so a consumer can
bring up a Server 2022 guest. Today a 2022 host reaches Windows_Server_2025, has its transport
modified, and then fails that role's build == 26100 assertion.

Also widens the product-type assertion in both Windows roles, and documents how a second
release of an already-mapped family is selected.

Type of change

  • New feature (feat:)
  • Documentation update (docs:)

Checklist

  • My commit messages follow Conventional Commits format
  • I have run pre-commit run --all-files locally and all hooks pass — pre-commit is not installed on this workstation; CI will run it
  • I have run ansible-lint and yamllint locally and no errors are reported
  • I have updated documentation where applicable
  • I have tested this change (below)

Testing

ansible-lint and yamllint report identical results for the new role and its 2025 sibling —
24 warnings, 0 failures each — so the addition introduces no new findings. The warnings are the
existing #region banner idiom shared across this repository.

Structural check: every file except tasks/bootstrap.yml is byte-identical to the sibling once
release identity is normalised, and bootstrap.yml differs only in the release comment block.
Banner and region widths match the sibling exactly.

Not yet exercised against a live Server 2022 host. The consumer that needs it
(pdq-deploy-inventory) pins a framework SHA and cannot reach this role until a release is cut
and that pin moves. First live use is the reason for the change, not evidence for it.

Additional notes

Routing. The map is deliberately left alone. Detection yields an OS family, and on Windows
it resolves before facts exist, so os_bootstrap_role_map holds one role per family and cannot
tell 2022 from 2025 — pointing Windows at either routes every Windows host to it and fails the
other's assertion. A consumer running both overrides the map per play, which works because a role
parameter outranks role vars. That is now written down in the os_bootstrap README, because the
"Adding an OS" section previously said to extend the map and following it literally would break
every existing 2025 consumer.

Product type. Both roles previously required os_product_type == 'server'. A domain
controller reports domain_controller, so the equality rejected a legitimate installation of the
release each role is named for. Both now accept either: a domain controller is a server, and
ProductType reports it separately only to name the role the machine holds. This changes
behaviour for Windows_Server_2025 as well, which is why it is called out rather than buried.

Duplication, accepted deliberately. This is a fork of the 2025 role: of 451 lines the diff is
names, comments and the expected build. The two must now be maintained in lockstep, and nothing
enforces that — tests/ is empty in both. The alternative was one role accepting several builds,
which changes the role-per-release shape this repository already uses for Rocky 8/9/10. The
fork was chosen to match that existing pattern.

No OpenSSH handling here. Server 2022 ships without OpenSSH, but installing it is not this
role's job: a guest reached over SSH proves sshd is already installed and running, so a check
here could only re-verify what the connection established. Provisioning installs it — in the AWS
case via the Feature-on-Demand cab that aws-terraform-framework fetches when
windows_fod_source is set.

Adds Windows_Server_2022 beside Windows_Server_2025. The dispatcher detects
Windows before facts are available, so it can only route an OS family to one
role; the mapped role owns strict release validation itself. A consumer with
mixed releases selects this one per play by overriding os_bootstrap_role_map,
which is a role parameter and outranks the utility's own vars.

Server 2022 is NT 10.0 build 20348. No released Windows client shares that
build -- unlike 26100, which Windows 11 24H2 also carries -- but the product
type is asserted regardless so the role states what it supports rather than
relying on a build number happening to be unambiguous.

Both roles now accept product type 'domain_controller' alongside 'server'. A
domain controller IS a server; ProductType reports it separately only to name
the role the machine holds, and the previous equality rejected a legitimate
installation of the release each role is named for.

The role does not install OpenSSH. Server 2022 ships without it, so the guest
arrives over SSH only because something installed and started sshd before
Ansible connected -- reaching the host is itself the proof, and a check here
could only re-verify what the connection already established.
…lected

The Adding an OS section says to extend os_bootstrap_role_map, which is
right for a new family and wrong for a second release of one already
mapped. Windows detection resolves before facts, so the map cannot tell
2022 from 2025; editing it routes every Windows host to one role and
fails the other's support assertion. The consumer overrides the map per
play instead, which works because a role parameter outranks role vars.
Detection resolves an OS FAMILY, and on Windows it resolves before facts
exist because the bootstrap is what repairs the transport those facts
travel over. The map therefore holds one role per family and cannot tell
Server 2022 from Server 2025 -- but the inventory that launched the image
already knows which it is.

os_bootstrap_role, set on a host, now wins over the map. A host variable
is the only override that arrives before detection and does not become a
role parameter, which callers are told never to pass because one outranks
the connection scoping the pre-flip stage depends on. Empty falls through
to the map, so hosts that say nothing keep the default and no existing
consumer changes behaviour.

Replaces the README guidance added a commit ago, which suggested a role
parameter and so contradicted that rule.
@NWarila
NWarila merged commit a372c4a into main Sep 1, 2026
14 checks passed
@NWarila
NWarila deleted the feat/windows-server-2022 branch September 1, 2026 15:05
NWarila pushed a commit that referenced this pull request Sep 1, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.7](v0.1.6...v0.1.7)
(2026-09-01)


### Features

* four namespaces, two site-policy roles, and a readiness role that
knows its platform
([#77](#77))
([363c5b4](363c5b4))
* **operating_systems:** bootstrap Windows Server 2022
([#83](#83))
([a372c4a](a372c4a))
* read deployment secrets through one URL-addressed lookup
([#81](#81))
([c584528](c584528))


### Bug Fixes

* **domain_member:** decide on the machine account, not only the
membership
([#82](#82))
([076eb02](076eb02))
* **windows_disk_manager:** let a host with one declared disk find it
([#80](#80))
([7568f6d](7568f6d))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant