Skip to content

RELOPS-2496 Add Taskcluster ARM template version 2.0 - #315

Merged
jwmossmoz merged 1 commit into
masterfrom
RELOPS-2496-template-spec-v2
Aug 7, 2026
Merged

RELOPS-2496 Add Taskcluster ARM template version 2.0#315
jwmossmoz merged 1 commit into
masterfrom
RELOPS-2496-template-spec-v2

Conversation

@jwmossmoz

Copy link
Copy Markdown
Contributor

Summary

  • Add version 2.0 to the existing Taskcluster ARM Template Spec.
  • Keep version 1.0 unchanged.
  • Keep implicit ephemeral OS disk placement as the default for Standard_F8s_v2.
  • Add optional CacheDisk, ResourceDisk, and NvmeDisk placement.
  • Add optional full caching. It is disabled by default because the feature is in public preview.
  • Use Microsoft.Compute API version 2025-04-01.

Validation

  • uvx pre-commit passed for both changed files.
  • Terraform 1.5.7 validate passed.
  • Azure deployment validation passed for Standard_F8s_v2 with implicit placement.
  • Azure deployment validation passed for Standard_F8alds_v7 with NvmeDisk placement.
  • Azure deployment validation passed for Standard_F8alds_v7 with full caching enabled.
  • Azure what-if showed that the Standard_F8s_v2 payload matches version 1.0.
  • The Terraform plan on top of PR RELOPS-2487: Private (firewalled) NUC install.wim blob storage + downloader SP #313 showed 1 to add, 0 to change, and 0 to destroy.

Deployment dependency

PR #313 must merge before this configuration is applied. Its resources are already in the shared Terraform state. A plan from master cannot load those resources until the provider configuration from that PR is present.

Do not enable full caching in a production worker pool while the Azure feature remains in public preview.

Related

@jwmossmoz

jwmossmoz commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Full local Terraform plan

I ran this plan with Terraform 1.15.5. The shared state already contains the resources from PR #313, so I stacked this PR commit on the PR #313 branch for this plan. PR #313 must merge before this PR.

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # azapi_resource.template_spec_version_taskcluster_arm_template_2_0 will be created
  + resource "azapi_resource" "template_spec_version_taskcluster_arm_template_2_0" {
      + body                      = {
          + properties = {
              + mainTemplate = {
                  + "$schema"      = "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"
                  + contentVersion = "2.0.0.0"
                  + outputs        = {
                      + resourceIds = {
                          + type  = "object"
                          + value = {
                              + nic       = "[variables('nicId')]"
                              + osDisk    = "[resourceId('Microsoft.Compute/disks', variables('osDiskName'))]"
                              + privateIp = "[reference(resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))).ipConfigurations[0].properties.privateIPAddress]"
                              + publicIp  = "[if(parameters('createPublicIp'), variables('publicIpId'), '')]"
                              + vm        = "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]"
                            }
                        }
                    }
                  + parameters     = {
                      + adminPassword     = {
                          + metadata = {
                              + description = "Admin password (provided by worker-manager)"
                            }
                          + type     = "securestring"
                        }
                      + adminUsername     = {
                          + metadata = {
                              + description = "Admin username (provided by worker-manager)"
                            }
                          + type     = "string"
                        }
                      + computerName      = {
                          + metadata = {
                              + description = "Name of the computer name (osProfile, provided by worker-manager)"
                            }
                          + type     = "string"
                        }
                      + createPublicIp    = {
                          + defaultValue = false
                          + metadata     = {
                              + description = "Create a public IP for the VM"
                            }
                          + type         = "bool"
                        }
                      + customData        = {
                          + metadata = {
                              + description = "Custom data attached to osProfile (provided by worker-manager)"
                            }
                          + type     = "string"
                        }
                      + diffDiskOption    = {
                          + allowedValues = [
                              + "Local",
                            ]
                          + defaultValue  = "Local"
                          + metadata      = {
                              + description = "Ephemeral OS disk option"
                            }
                          + type          = "string"
                        }
                      + diffDiskPlacement = {
                          + allowedValues = [
                              + "",
                              + "CacheDisk",
                              + "ResourceDisk",
                              + "NvmeDisk",
                            ]
                          + defaultValue  = ""
                          + metadata      = {
                              + description = "Ephemeral OS disk placement. Leave this value empty to let Azure select the placement."
                            }
                          + type          = "string"
                        }
                      + enableFullCaching = {
                          + defaultValue = false
                          + metadata     = {
                              + description = "Enable full caching for the ephemeral OS disk"
                            }
                          + type         = "bool"
                        }
                      + evictionPolicy    = {
                          + allowedValues = [
                              + "Deallocate",
                              + "Delete",
                            ]
                          + defaultValue  = "Delete"
                          + metadata      = {
                              + description = "Eviction policy for Spot VMs"
                            }
                          + type          = "string"
                        }
                      + imageId           = {
                          + metadata = {
                              + description = "Full resource ID of the VM image"
                            }
                          + type     = "string"
                        }
                      + location          = {
                          + defaultValue = "eastus"
                          + metadata     = {
                              + description = "Azure region for the VM"
                            }
                          + type         = "string"
                        }
                      + osDiskCaching     = {
                          + allowedValues = [
                              + "None",
                              + "ReadOnly",
                              + "ReadWrite",
                            ]
                          + defaultValue  = "ReadOnly"
                          + metadata      = {
                              + description = "OS disk caching mode"
                            }
                          + type          = "string"
                        }
                      + priority          = {
                          + allowedValues = [
                              + "Regular",
                              + "Spot",
                            ]
                          + defaultValue  = "Spot"
                          + metadata      = {
                              + description = "VM priority (Spot or Regular)"
                            }
                          + type          = "string"
                        }
                      + subnetId          = {
                          + metadata = {
                              + description = "Full resource ID of the subnet"
                            }
                          + type     = "string"
                        }
                      + tags              = {
                          + defaultValue = {}
                          + metadata     = {
                              + description = "Tags to apply to all resources"
                            }
                          + type         = "object"
                        }
                      + vmName            = {
                          + metadata = {
                              + description = "Name of the virtual machine (provided by worker-manager)"
                            }
                          + type     = "string"
                        }
                      + vmSize            = {
                          + defaultValue = "Standard_F16s_v2"
                          + metadata     = {
                              + description = "VM size"
                            }
                          + type         = "string"
                        }
                    }
                  + resources      = [
                      + {
                          + apiVersion = "2023-05-01"
                          + condition  = "[parameters('createPublicIp')]"
                          + location   = "[parameters('location')]"
                          + name       = "[variables('publicIpName')]"
                          + properties = {
                              + publicIPAddressVersion   = "IPv4"
                              + publicIPAllocationMethod = "Static"
                            }
                          + sku        = {
                              + name = "Standard"
                            }
                          + tags       = "[parameters('tags')]"
                          + type       = "Microsoft.Network/publicIPAddresses"
                        },
                      + {
                          + apiVersion = "2023-05-01"
                          + dependsOn  = [
                              + "[variables('publicIpId')]",
                            ]
                          + location   = "[parameters('location')]"
                          + name       = "[variables('nicName')]"
                          + properties = {
                              + ipConfigurations = [
                                  + {
                                      + name       = "ipconfig1"
                                      + properties = {
                                          + privateIPAllocationMethod = "Dynamic"
                                          + publicIPAddress           = "[if(parameters('createPublicIp'), variables('publicIPConfig'), json('null'))]"
                                          + subnet                    = {
                                              + id = "[parameters('subnetId')]"
                                            }
                                        }
                                    },
                                ]
                            }
                          + tags       = "[parameters('tags')]"
                          + type       = "Microsoft.Network/networkInterfaces"
                        },
                      + {
                          + apiVersion = "2025-04-01"
                          + dependsOn  = [
                              + "[variables('nicId')]",
                            ]
                          + location   = "[parameters('location')]"
                          + name       = "[parameters('vmName')]"
                          + properties = {
                              + billingProfile     = "[if(equals(parameters('priority'), 'Spot'), createObject('maxPrice', -1), json('null'))]"
                              + diagnosticsProfile = {
                                  + bootDiagnostics = {
                                      + enabled = false
                                    }
                                }
                              + evictionPolicy     = "[if(equals(parameters('priority'), 'Spot'), parameters('evictionPolicy'), json('null'))]"
                              + hardwareProfile    = {
                                  + vmSize = "[parameters('vmSize')]"
                                }
                              + networkProfile     = {
                                  + networkInterfaces = [
                                      + {
                                          + id         = "[variables('nicId')]"
                                          + properties = {
                                              + deleteOption = "Delete"
                                            }
                                        },
                                    ]
                                }
                              + osProfile          = {
                                  + adminPassword        = "[parameters('adminPassword')]"
                                  + adminUsername        = "[parameters('adminUsername')]"
                                  + computerName         = "[parameters('computerName')]"
                                  + windowsConfiguration = {
                                      + enableAutomaticUpdates = false
                                      + timeZone               = "UTC"
                                    }
                                }
                              + priority           = "[parameters('priority')]"
                              + storageProfile     = {
                                  + imageReference = {
                                      + id = "[parameters('imageId')]"
                                    }
                                  + osDisk         = {
                                      + caching          = "[parameters('osDiskCaching')]"
                                      + createOption     = "FromImage"
                                      + deleteOption     = "Delete"
                                      + diffDiskSettings = "[union(createObject('option', parameters('diffDiskOption')), if(empty(parameters('diffDiskPlacement')), createObject(), createObject('placement', parameters('diffDiskPlacement'))), if(parameters('enableFullCaching'), createObject('enableFullCaching', parameters('enableFullCaching')), createObject()))]"
                                      + managedDisk      = {
                                          + storageAccountType = "Standard_LRS"
                                        }
                                      + name             = "[variables('osDiskName')]"
                                      + osType           = "Windows"
                                    }
                                }
                            }
                          + tags       = "[parameters('tags')]"
                          + type       = "Microsoft.Compute/virtualMachines"
                        },
                    ]
                  + variables      = {
                      + nicId          = "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
                      + nicName        = "[concat(parameters('vmName'), '-nic')]"
                      + osDiskName     = "[concat(parameters('vmName'), '-osdisk')]"
                      + publicIPConfig = {
                          + id         = "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpName'))]"
                          + properties = {
                              + deleteOption = "Delete"
                            }
                        }
                      + publicIpId     = "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpName'))]"
                      + publicIpName   = "[concat(parameters('vmName'), '-ip')]"
                    }
                }
            }
        }
      + id                        = (known after apply)
      + ignore_casing             = false
      + ignore_missing_property   = true
      + ignore_null_property      = false
      + location                  = "eastus"
      + name                      = "2.0"
      + output                    = (known after apply)
      + parent_id                 = "/subscriptions/108d46d5-fe9b-4850-9a7d-8c914aa6c1f0/resourceGroups/template-spec/providers/Microsoft.Resources/templateSpecs/taskcluster-arm-template"
      + schema_validation_enabled = true
      + sensitive_body            = (write-only attribute)
      + type                      = "Microsoft.Resources/templateSpecs/versions@2022-02-01"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

I did not apply this plan.

@jwmossmoz
jwmossmoz requested a review from markcor August 7, 2026 18:50
@jwmossmoz
jwmossmoz merged commit 6bb8292 into master Aug 7, 2026
1 check passed
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.

2 participants