Skip to content

RELOPS-2487: Private (firewalled) NUC install.wim blob storage + downloader SP#313

Open
markcor wants to merge 6 commits into
masterfrom
nuc-wim-storage
Open

RELOPS-2487: Private (firewalled) NUC install.wim blob storage + downloader SP#313
markcor wants to merge 6 commits into
masterfrom
nuc-wim-storage

Conversation

@markcor

@markcor markcor commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

What

Adds the Azure storage backend for the pre-baked NUC install.wim pipeline (RELOPS-2487), plus the Entra service principal the on-site MDC1 server uses to download the baked WIM. Access model: Entra-only.

terraform/azure_fxci/nuc-wim-storage.tf

  • Storage account nucwimfxci (Central US): public endpoint open to all networks (no IP firewall), but:
    • no anonymous/public blob access,
    • shared account keys disabled (shared_access_key_enabled = false) — no key/SAS; every caller must use an Entra identity,
    • TLS1.2, HTTPS-only.
  • Containers base (bring-your-own starting WIM) and captured (baked golden WIM).
  • Data-plane RBAC (the only way in):
    • Relops group — Blob Data Owner + Contributor (operators upload/manage from anywhere).
    • Downloader SP (mdc1_wim_ro) — Blob Data Reader, scoped to captured (MDC1 download).
    • Packer SP (packer_wim_rw) — Blob Data Contributor.
    • Relops also granted Queue + File Data roles only so Terraform can read the account's queue/file service properties via AAD (keys are off); not used by the WIM workflow.
  • Account + containers are managed via an aliased azurerm provider with storage_use_azuread = true, scoped to this file so the rest of azure_fxci (which still manages other storage via keys) is untouched.

terraform/azure_ad/sp_nuc_wim_downloader.tf

  • SP sp-relops-nuc-wim-downloader (+ client secret, expiry 2027-07-21) for the MDC1 download. Secret is not committed and not in Key Vault (MDC1 is not Entra-joined; kept as a local file on the box). Lives only in Terraform state.

.gitignore

  • Ignore *tfplan* (plan output can embed sensitive values).

Notes

  • Applied to FXCI DevTest; post-apply terraform plan reports no changes.
  • Verified: Entra blob access works from a non-allow-listed IP; account-key auth is refused (KeyBasedAuthenticationNotPermitted).
  • History: started IP-firewalled ("Tier 1"), but split-tunnel VPN made per-workstation IP allow-listing unworkable, so moved to Entra-only.
  • Fixed provider deprecations found via validate/plan: role-assignment scope resource_manager_id -> .id; container storage_account_name -> storage_account_id.

Follow-ups (not in this PR)

  • MDC1 must retain outbound reach to login.microsoftonline.com for SP auth even though it isn't Entra-joined.
  • Deploy-side WIM download wiring on MDC1 (separate from this infra).

🤖 Generated with Claude Code

markcor and others added 2 commits July 21, 2026 10:35
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>
@markcor
markcor requested a review from jwmossmoz July 23, 2026 20:48
markcor and others added 3 commits July 23, 2026 14:03
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant