diff --git a/terraform/azure_foofrix/README.md b/terraform/azure_foofrix/README.md index 6d033dbb..147b83ef 100644 --- a/terraform/azure_foofrix/README.md +++ b/terraform/azure_foofrix/README.md @@ -14,9 +14,9 @@ The harness source and image provisioning scripts are in This Terraform stack manages the subscription, a resource group in Central US, a Key Vault available for Windows worker secrets, and a managed identity for the VMs. -Terraform manages the `foofrix` Compute Gallery and its `win11_64_24h2` image -definition. It uses the existing FXCI Windows 11 24H2 properties: Windows, x64, -Hyper-V V2, generalized, and `MicrosoftWindowsDesktop/Windows-11/win11-24h2-avd`. +Terraform manages the `foofrix` Compute Gallery for `win11_64_24h2` and a +dedicated `win11_64_25h2` gallery and image definition. They use the existing FXCI properties: +Windows, x64, Hyper-V V2, generalized, and the matching 24H2 or 25H2 AVD SKU. The worker-images workflow publishes image versions. A private `artifacts` Blob Storage container holds Azure build and image files in Standard LRS storage. The GCP launcher manages the VMs through `sp-foofrix-azure-devtest`. The application and @@ -28,7 +28,7 @@ service principal are managed in `../azure_ad/foofrix.tf`. | `sp-foofrix-azure-devtest` | Subscription Contributor; Key Vault Secrets Officer; blob read/write | | `id-foofrix-worker` | Read vault secrets; blob read/write | | Platform Performance | Subscription Contributor; Key Vault Secrets Officer; blob read/write | -| `sp-foofrix-image-build` | Contributor on the build resource group and gallery; blob read; attach the build identity | +| `sp-foofrix-image-build` | Contributor on the build resource group and galleries; blob read; attach the build identity | | `id-foofrix-image-build` | Blob read during image creation | The GCP launcher uses a tenant ID, client ID, and client secret to @@ -63,8 +63,10 @@ No image-build client secret is needed. Configure Packer to use the existing `image_build_resource_group` output for temporary resources. Publish to `image_gallery_name` in -`image_gallery_resource_group`, using the definition from -`windows_image_definition_id`. The workflow logs in with `image_build_client_id`. +`image_gallery_resource_group`, using `windows_image_definition_id` for 24H2. +For 25H2, use `windows_25h2_image_gallery_name` and +`windows_25h2_image_definition_id`. The workflow logs in with +`image_build_client_id`. Attach `image_build_identity_id` to the temporary VM. The guest bootstrap must use that managed identity to authenticate artifact downloads, with `image_build_identity_client_id` to select it. The GitHub login does not provide diff --git a/terraform/azure_foofrix/images.tf b/terraform/azure_foofrix/images.tf index d1daa5ab..2b5c8f0e 100644 --- a/terraform/azure_foofrix/images.tf +++ b/terraform/azure_foofrix/images.tf @@ -8,6 +8,16 @@ resource "azurerm_shared_image_gallery" "foofrix" { depends_on = [azurerm_resource_provider_registration.this["Microsoft.Compute"]] } +resource "azurerm_shared_image_gallery" "windows_25h2" { + name = "win11_64_25h2" + resource_group_name = azurerm_resource_group.foofrix.name + location = local.location + description = "Shared Image Gallery for win11-25h2-avd" + tags = local.common_tags + + depends_on = [azurerm_resource_provider_registration.this["Microsoft.Compute"]] +} + resource "azurerm_storage_account" "foofrix" { name = "safoofrix${substr(azurerm_subscription.foofrix.subscription_id, 0, 8)}" resource_group_name = azurerm_resource_group.foofrix.name @@ -73,6 +83,25 @@ resource "azurerm_shared_image" "windows" { } } +resource "azurerm_shared_image" "windows_25h2" { + name = "win11_64_25h2" + gallery_name = azurerm_shared_image_gallery.windows_25h2.name + resource_group_name = azurerm_resource_group.foofrix.name + location = local.location + os_type = "Windows" + release_note_uri = "https://github.com/mozilla-platform-ops/worker-images/releases" + hyper_v_generation = "V2" + architecture = "x64" + disk_controller_type_nvme_enabled = true + tags = local.common_tags + + identifier { + publisher = "MicrosoftWindowsDesktop" + offer = "Windows-11" + sku = "win11-25h2-avd" + } +} + data "azuread_service_principal" "foofrix_image_build" { display_name = "sp-foofrix-image-build" } @@ -94,8 +123,9 @@ resource "azurerm_user_assigned_identity" "image_build" { resource "azurerm_role_assignment" "image_build_contributor" { for_each = { - build = azurerm_resource_group.image_build.id - gallery = azurerm_shared_image_gallery.foofrix.id + build = azurerm_resource_group.image_build.id + gallery = azurerm_shared_image_gallery.foofrix.id + gallery_25h2 = azurerm_shared_image_gallery.windows_25h2.id } scope = each.value role_definition_name = "Contributor" diff --git a/terraform/azure_foofrix/outputs.tf b/terraform/azure_foofrix/outputs.tf index 7d1ef253..dec14ff8 100644 --- a/terraform/azure_foofrix/outputs.tf +++ b/terraform/azure_foofrix/outputs.tf @@ -38,6 +38,18 @@ output "windows_image_definition_id" { value = azurerm_shared_image.windows.id } +output "windows_25h2_image_definition_id" { + value = azurerm_shared_image.windows_25h2.id +} + +output "windows_25h2_image_gallery_id" { + value = azurerm_shared_image_gallery.windows_25h2.id +} + +output "windows_25h2_image_gallery_name" { + value = azurerm_shared_image_gallery.windows_25h2.name +} + output "image_build_client_id" { value = data.azuread_service_principal.foofrix_image_build.client_id } diff --git a/terraform/azure_foofrix/tests/access.tftest.hcl b/terraform/azure_foofrix/tests/access.tftest.hcl index 03bba726..4d9042f3 100644 --- a/terraform/azure_foofrix/tests/access.tftest.hcl +++ b/terraform/azure_foofrix/tests/access.tftest.hcl @@ -18,6 +18,12 @@ override_resource { values = { id = "/subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/rg-foofrix/providers/Microsoft.Compute/galleries/foofrix" } } +override_resource { + target = azurerm_shared_image_gallery.windows_25h2 + override_during = plan + values = { id = "/subscriptions/00000000-0000-0000-0000-000000000001/resourceGroups/rg-foofrix/providers/Microsoft.Compute/galleries/win11_64_25h2" } +} + override_resource { target = azurerm_user_assigned_identity.image_build override_during = plan @@ -35,9 +41,11 @@ run "build_and_team_access" { assert { condition = ( - length(azurerm_role_assignment.image_build_contributor) == 2 && + length(azurerm_role_assignment.image_build_contributor) == 3 && azurerm_role_assignment.image_build_contributor["build"].scope == azurerm_resource_group.image_build.id && azurerm_role_assignment.image_build_contributor["gallery"].scope == azurerm_shared_image_gallery.foofrix.id && + azurerm_role_assignment.image_build_contributor["gallery_25h2"].scope == azurerm_shared_image_gallery.windows_25h2.id && + azurerm_shared_image.windows_25h2.disk_controller_type_nvme_enabled && azurerm_role_assignment.image_build_identity_operator.scope == azurerm_user_assigned_identity.image_build.id && alltrue([for grant in azurerm_role_assignment.image_build_blob_reader : grant.scope == azurerm_storage_container.artifacts.id]) && alltrue([for grant in azurerm_role_assignment.image_build_contributor : grant.role_definition_name == "Contributor"]) && @@ -45,7 +53,7 @@ run "build_and_team_access" { length(azurerm_role_assignment.image_build_blob_reader) == 2 && azurerm_role_assignment.image_build_identity_operator.role_definition_name == "Managed Identity Operator" ) - error_message = "The builder needs two Contributor grants, identity attachment, and read access for both build identities." + error_message = "The builder needs three Contributor grants, identity attachment, and read access for both build identities." } assert {