golang.org/x/build@v0.0.0-20240506185731-218518f32b70/env/windows-arm64/azure/README.md (about)

     1  <!---
     2  # Copyright 2022 The Go Authors. All rights reserved.
     3  # Use of this source code is governed by a BSD-style
     4  # license that can be found in the LICENSE file.
     5  -->
     6  
     7  # Azure windows arm64 VM setup notes
     8  
     9  This doc contains notes on setup info for deploying windows arm64 Go builders on Azure.
    10  
    11  ## Prerequisites
    12  
    13  You'll need to install the Azure CLI toolset ("az *" commands) to take the various actions (VM creation, setup) below.  You'll also need a Microsoft account into order to do anything with "az" and/or to log into the azure website (e.g. portal.asure.com); recommendation is to use your golang.org account.
    14  
    15  ## CLI install
    16  
    17  Although you can try to install the Azure CLI using "sudo apt-get install azure-cli", this version winds up being broken/non-functional.  Make sure this version is uninstalled via "sudo apt-get remove azure-cli", then install the CLI via
    18  
    19    pip install azure-cli
    20  
    21  ## Authentication
    22  
    23  Authenticate with "az login".
    24  
    25  ## VM strategy for Azure
    26  
    27  At the moment, windows-arm64 Azure VMs are configured as reverse builders, and they are set up with no public IP address and no exposed ports. To interact with the VMs directly (e.g. to log in and poke around) it is recommended to use the Azure "bastion" feature, which provides RDP-like access to VMs from within the portal.  If you need to log in, use the account "gopheradmin" (password in Valentine). You can also run PowerShell scripts on the deployed VMs via "az vm run-command invoke --command-id=RunPowerShellScript ... --scripts @scriptpath" to perform upkeep operations.
    28  
    29  ## Deployment VM creation
    30  
    31  Deployment VMs are set up with invocations of the following az CLI command:
    32  
    33  ```
    34  az vm create \
    35    --name=MyNewVmName \
    36    --resource-group=<dev/prod>_buildlets \
    37    --admin-username=gopheradmin \
    38    --admin-password=<password from valentine> \
    39    --image=microsoftwindowsdesktop:windows11preview-arm64:win11-22h2-ent:latest \
    40    --nsg=<dev/prod>_buildlets-security-group \
    41    --size=Standard_D4ps_v5 \
    42    --subscription=<Development/Production> \
    43    --public-ip-address ""
    44  ```
    45  
    46  and then configure as described below in VM setup. This VM will have no public IP address or open ports, thus will be usable only by the coordinator. 
    47  
    48  Notes:
    49  * the "image" argument above is arm-specific, and in addition "size" argument also encodes the arm64-ness of the VM (strangely)
    50  
    51  ## VM setup (part 1 of 3)
    52  
    53  Once a VM has been created, you can apply Go-specific configuration to it by running the setup script in this directory (startup.ps1), using this command:
    54  
    55  ```
    56  az vm run-command invoke \
    57      --command-id=RunPowerShellScript \
    58      --name="MyNewVM" \
    59      --subscription=<Development/Production> \
    60      --resource-group=<dev/prod>_buildlets \
    61      --scripts @startup.ps1
    62  ```
    63  
    64  Where "startup.ps1" is the path (on your local machine) to the script to be run on the Azure VM, and the value passed to "--name" is the one you used when creating the VM.
    65  
    66  Notes:
    67  
    68  * output from the command is in JSON
    69  * exit status of the "az" command does NOT accurately reflect exit status of the powershell script.
    70  * errors about things already existing are expected
    71  
    72  ## VM setup (part 2 of 3)
    73  
    74  Each VM instance needs a unique hostname; this is handled by starting with a base hostname of "windows-arm64-azure" and then tacking on a numeric "--NN" suffix.  To enable the VM to use the correct hostname, the next step is to write a "bootstrapswarm boot loop" script of the following form for the VM (where `INSTANCE` is replaced with a unique numeric value, such as "00" or "01"):
    75  
    76  ```
    77  if %username%==swarming goto loop
    78  exit 0
    79  :loop
    80  @echo Invoking bootstrapswarm.exe at %date% %time% on %computername%
    81  C:\golang\bootstrapswarm.exe -hostname windows-arm64-azure--<INSTANCE>
    82  timeout 10
    83  goto loop
    84  ```
    85  
    86  The following PowerShell script will write out a script of the proper form to the file "C:\golang\windows-arm64-bootstrapswarm-loop.bat" on the VM (hostname will vary of course):
    87  
    88  ```
    89  Write-Host "Writing windows-arm64-bootstrapswarm-loop.bat"
    90  
    91  mkdir C:\golang
    92  
    93  $path = "C:\golang\windows-arm64-bootstrapswarm-loop.bat"
    94  $line = "rem boostrapswarm loop script"
    95  $hostname | Out-File -Encoding ascii -FilePath $path
    96  
    97  $line = "if %username%==swarming goto loop"
    98  Add-Content -Encoding ascii -Path $path -Value $line
    99  $line = "exit 0"
   100  Add-Content -Encoding ascii -Path $path -Value $line
   101  $line = ":loop"
   102  Add-Content -Encoding ascii -Path $path -Value $line
   103  $line = "@echo Invoking bootstrapswarm.exe at %date% %time% on %computername%"
   104  Add-Content -Encoding ascii -Path $path -Value $line
   105  $line = "C:\golang\bootstrapswarm.exe -hostname windows-arm64-azure--<INSTANCE>"
   106  Add-Content -Encoding ascii -Path $path -Value $line
   107  $line = "timeout 10"
   108  Add-Content -Encoding ascii -Path $path -Value $line
   109  $line = "goto loop"
   110  Add-Content -Encoding ascii -Path $path -Value $line
   111  ```
   112  
   113  Run the script with "az vm run-command invoke" as with the startup script above.
   114  
   115  ## VM setup (part 3 of 3)
   116  
   117  As a final step, you will need to distribute a copy of the private builder key to the VM (for details on keys, see https://github.com/golang/go/wiki/DashboardBuilders#luci-builders).  Because the VM created in step 1 does not have a public IP, we can't use ssh/scp to copy in the file, so instead the recommendation is to do the transfer using "writefilegenpowerscript.go", steps below.
   118  
   119  ```
   120  # Copy key from valentine to a local file
   121  $ cp ... windows-arm64-azure-key.txt
   122  # Encode into powershell script
   123  $ go build writefilegenpowerscript.go
   124  $ ./writefilegenpowerscript -input-file windows-arm64-azure-key.txt -output-file transferFile.ps1 -windows-target-path "C:\tokend\windows-arm64-azure-key.txt" -set-owner tokend -deny-user-read swarming
   125  $ ls transferFile.ps1
   126  transferFile.ps1
   127  $ az vm run-command invoke \
   128      --command-id=RunPowerShellScript \
   129      --name="MyNewVM" \
   130      --subscription=<Development/Production> \
   131      --resource-group=<dev/prod>_buildlets \
   132      --scripts @transferFile.ps1
   133  ```
   134  
   135  ## First login
   136  
   137  Log into the new builder as "swarming" at least once so as to go through the "initial login" Windows workflow. Find the VM in the Azure portal, and enter the login in the Bastion section. Choose "no" on all the setup prompts.
   138  
   139  Check to make sure that the scheduled task to run "luci_machine_tokend.exe" every 10 minutes is working properly. You can do this by looking for the presence of the "C:\golang\token.json" file.
   140  
   141  ## Follow-ons to disable antivirus
   142  
   143  In later versions of windows, it can be very difficult to completely disable the system's antivirus software, due to "features" such as [tamper protection](https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/prevent-changes-to-security-settings-with-tamper-protection?view=o365-worldwide), which make it almost impossible to programmatically turn off windows defender (and which ensure that any changes made are undone when the system reboots).
   144  
   145  Open Windows Security, Virus & threat protection, Manage settings, and turn off Tamper Protection. Then run this command:
   146  
   147  ```
   148  az vm run-command invoke \
   149      --command-id=RunPowerShellScript \
   150      --name="MyNewVM" \
   151      --subscription=<Development/Production> \
   152      --resource-group=<prod/dev>_buildlets \
   153      --scripts @antivirusadditions.ps1
   154  ```
   155  
   156  ## Debugging/testing VM creation
   157  
   158  To create a new windows-arm64 VM named "MyNewVM" that is net accessible (e.g. with a public IP and ssh port exposed), use this command:
   159  
   160  ```
   161  az vm create \
   162    --name=MyNewVM \
   163    --resource-group=dev_buildlets \
   164    --admin-username=<pick your admin account name> \
   165    --admin-password=<pick password> \
   166    --image=microsoftwindowsdesktop:windows11preview-arm64:win11-22h2-ent:latest \
   167    --nsg-rule=SSH \
   168    --size=Standard_D8ps_v5 \
   169    --subscription=<set subscription ID here> \
   170    --public-ip-sku Standard
   171  ```
   172  
   173  Notes:
   174  
   175  * be sure to pick a very strong password
   176  * configure the VM once created as in `VM Setup` above, but with the section that starts boostrapswarm on login commented out (since we don't want the VM to connect to the LUCI)
   177  * delete VM when you are finished with it
   178