RELOPS-2487: create hardware-imaging stack alongside nucwimfxci (migrate-first phase 1) - #317
Merged
Conversation
Tier-1 private storage for NUC install.wim files: public endpoint retained but network_rules default Deny, allowing only the Packer subnet (Microsoft.Storage service endpoint) and the MDC1 egress IP(s). No anonymous access; auth via Entra RBAC (Storage Blob Data Contributor for Packer, Reader on 'captured' for the MDC1 downloader SP) or a read-only SAS from kv-central-us-key. - azure_fxci/nuc-wim-storage.tf: RG, VNet/subnet (svc endpoint), storage account (deny-by-default firewall), base+captured containers, data-plane role assignments. - azure_ad/sp_nuc_wim_downloader.tf: Entra SP for the on-site MDC1 downloader. MDC1 egress IP (default 63.245.208.251/32) and SP-vs-SAS auth are parameterized pending confirmation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e tfplan - mdc1_egress_cidrs default 63.245.208.129 (bare IP; Azure storage firewall rejects /31 and /32 masks) - nuc_wim_downloader_object_id default set to the applied SP object_id so the mdc1_wim_ro Blob Data Reader grant on 'captured' stays active across plans - fix provider deprecations: role-assignment scope resource_manager_id -> id; container storage_account_name -> storage_account_id - .gitignore: ignore *tfplan* (plan output can embed sensitive values) Applied to FXCI DevTest: storage nucwimfxci (deny-by-default) + base/captured containers + packer_wim_rw (Blob Data Contributor) + mdc1_wim_ro (Blob Data Reader, scoped to captured). SP secret kept off-repo (state only). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add admin_egress_cidrs (default = Mozilla VPN netblocks, bare IPs since Azure storage firewall rejects /32) and merge into the storage firewall ip_rules so operators on the corp VPN can manage the store (e.g. upload the base WIM) from outside the MDC1 IP. Deny-by-default posture unchanged. Ref base/outputs.tf mozilla_vpn_netblocks + mana Mozilla VPN wiki. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…to MDC1 IP - Grant the Relops Entra group Storage Blob Data Owner + Contributor on the account so operators manage the store with their own Entra identity. - Revert the firewall ip_rules back to the single MDC1 egress IP (drop the Mozilla VPN netblocks / admin_egress_cidrs added earlier). Note: RBAC clears the data-plane auth gate, but the storage firewall still applies — Relops members must reach the account from an allow-listed network. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…keys) Rework access so Relops members and the downloader SP reach the store by Entra identity from any network (split-tunnel VPN made IP allow-listing unworkable): - network_rules default_action Deny -> Allow; drop ip_rules + the packer subnet rule and the now-unused mdc1_egress_cidrs var. Access is gated purely by RBAC. - shared_access_key_enabled = false (no account key / SAS; Entra-only). - Manage the account + containers via an aliased azurerm provider with storage_use_azuread = true (scoped to this file, so the rest of azure_fxci is untouched), since keys are disabled. - Grant the Relops group Storage Queue Data Contributor + Storage File Data Privileged Contributor so whoever runs Terraform can read the account's queue/file service properties via AAD (the account itself only uses blob). RBAC access paths unchanged: Relops (Blob Data Owner+Contributor), downloader SP (Blob Data Reader on captured), Packer SP (Blob Data Contributor). Verified: Entra blob access works from a non-allow-listed IP; key auth is refused. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a user-assigned managed identity (id-central-us-wim-builder) pre-granted Storage Blob Data Contributor — attached to each ephemeral build VM so no per-run role assignment is needed. Grant the workflow SP (worker_images_fxci) modest, RG-scoped rights: Contributor on rg-central-us-nuc-wim (create/delete VM + run-command; NOT role-assignment) + Managed Identity Operator on the UAMI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ure containers Prod-prep: rename the storage account and reorganize the blob layout. - account nucwimfxci -> hardwareimaging - container 'base' -> 'resources' (SOURCES): folders WIMs/ ISOs/ drivers/ tools/ - 'captured' (OUTPUTS): folders WIMs/ ISOs/ - new 'legacy-images' container for old/previously-built images (empty at creation) - TF-managed .keep folder markers for the prefixes above Data migration (old -> new) and apply are separate, deliberate steps. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts: # terraform/azure_ad/sp_nuc_wim_downloader.tf # terraform/azure_fxci/nuc-wim-storage.tf
Full rebrand (names + resource labels + refs): resource_group, virtual_network, subnet, and the user-assigned identity, matching the storage-account rename. Provider alias (nuc_wim_aad), role-assignment labels, and the downloader SP kept. validate clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jwmossmoz
approved these changes
Aug 10, 2026
markcor
added a commit
that referenced
this pull request
Aug 26, 2026
…hardwareimaging Phase 2 of the nuc-wim -> hardware-imaging migration, completing the phase-1 create-alongside (#317). Removes nuc-wim-storage.tf entirely: the old 'nucwimfxci' account, its base/ and captured/ containers, the nuc-wim RG/VNet/subnet, the wim_builder identity and the nine wim_* role assignments. Every blob the old account held has a verified counterpart under hardwareimaging resources/ and captured/, and worker-images has provisioned exclusively into rg-central-us-hardware-imaging since the cutover - no code in win-hw-wim/ or ci/ references the old RG, VNet, subnet or identity. Adds azurerm_role_assignment.mdc1_hwimg_ro: Storage Blob Data Reader for the MDC1 downloader SP, scoped to the new account's 'captured' container. That grant existed only on nucwimfxci, so since the cutover the SP has had no access to the account the images actually live in. This is the "point the SP at the right ones" fix. The aliased AAD provider (azurerm.nuc_wim_aad) and the relops_group_object_id / nuc_wim_downloader_object_id variables lived in the deleted file and are moved into hardware-imaging-storage.tf unchanged. Deliberately NOT doing the cosmetic resource renames the phase-1 header proposed (state mv captured_hwimg -> captured, dropping _hwimg suffixes): hand-run state surgery adds risk to a change that already destroys a storage account. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
markcor
added a commit
that referenced
this pull request
Aug 26, 2026
…hardwareimaging (#326) Phase 2 of the nuc-wim -> hardware-imaging migration, completing the phase-1 create-alongside (#317). Removes nuc-wim-storage.tf entirely: the old 'nucwimfxci' account, its base/ and captured/ containers, the nuc-wim RG/VNet/subnet, the wim_builder identity and the nine wim_* role assignments. Every blob the old account held has a verified counterpart under hardwareimaging resources/ and captured/, and worker-images has provisioned exclusively into rg-central-us-hardware-imaging since the cutover - no code in win-hw-wim/ or ci/ references the old RG, VNet, subnet or identity. Adds azurerm_role_assignment.mdc1_hwimg_ro: Storage Blob Data Reader for the MDC1 downloader SP, scoped to the new account's 'captured' container. That grant existed only on nucwimfxci, so since the cutover the SP has had no access to the account the images actually live in. This is the "point the SP at the right ones" fix. The aliased AAD provider (azurerm.nuc_wim_aad) and the relops_group_object_id / nuc_wim_downloader_object_id variables lived in the deleted file and are moved into hardware-imaging-storage.tf unchanged. Deliberately NOT doing the cosmetic resource renames the phase-1 header proposed (state mv captured_hwimg -> captured, dropping _hwimg suffixes): hand-run state surgery adds risk to a change that already destroys a storage account. Co-authored-by: Claude Opus 5 (1M context) <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.
Phase 1 of the nuc-wim -> hardware-imaging migration (migrate-first, no data loss).
Adds hardware-imaging-storage.tf: a NEW stack (RG
rg-central-us-hardware-imaging,account
hardwareimaging, VNet/subnet, UAMI, containersresources/captured/legacy-images,RBAC) created alongside the existing
nucwimfxci— 0 destroys. This is what's currentlyapplied; ~30 GB of blobs were then azcopy-migrated old -> new with the folder remap
(base/* -> resources/WIMs|ISOs|drivers|tools; captured/* -> captured/WIMs|ISOs).
Temp labels (
captured_hwimg,relops_hwimg_*,*_hwimg) avoid clashing with the oldstack's labels while both coexist. Retire (follow-up):
state mv captured_hwimg -> captured, fold into the end-state config (PR #316), and destroy the oldnuc-wimstack.🤖 Generated with Claude Code