Building Self-hosted Azure DevOps Agents with Windows Server 2019 Core

We recently needed to rebuild a self-hosted Azure DevOps agent and decided to use the latest Windows Server Core OS (2019). We used an old VMWare server to host the VMs but generally these steps should work regardless of the hosting method (bare metal, cloud VMs, containers, etc).

Server Core

This was our first time using Windows Server Core which is a bit different if you only have experience with the GUI version of Windows. For example, you cannot remote into the server using Remote Desktop, instead you get access to the OS commandline through the hosting console or remoting in via PowerShell. There are many benefits to the non-UI approach of Core OS that far outweigh not having the UI (read more here) on a server.

So if you can’t access the UI how do you configure the OS? Microsoft provides all the configuration tools you need right in the console. For example, here is the final step of the installation process where you set the Administrator password:

image

Hint – You can use tab in the window above to confirm the password.

Configuration

Once the OS is intalled, you can remotely connect to the server with the enter-pssession PowerShell command.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/enter-pssession?view=powershell-7

They also provide a very nice utility, “sconfig”, for performing common tasks on a server:

image

We used this for joining to our domain, setting computer name and installing updates.  After the initial OS install you definitely want to get the latest recommended updates. So run sconfig, choose option 6 and follow the instructions:

image

Build Capabilities

Depending on what you will build with your agent(s), you will need to install any software/tools necessary to complete the build.  If you are using only the latest .NET Core framework you may only need to install the .NET Core SDK:

Invoke-webrequest -uri https://dot.net/v1/dotnet-install.ps1 -UseBasicParsing -OutFile dotnet-install.ps1

.\dotnet-install.ps1 -InstallDir ‘c:\Program Files\dotnet’ –version 3.1.102

setx /M PATH “$Env:PATH;C:\Program Files\dotnet\;”

We remote into the server using Powershell remoting via enter-pssession command then run the above commands.  The script downloads the sdk installer from the web, then installs the SDK and finally updates the OS path to included the dotnet program folder so it can be accessed from any path on the server.

Note – If you only need to build .NET Core code, it will likely be faster and more efficient to create a Linux build agent instead of Windows. 

Older .NET Full Framework Builds

We still have some older code that uses .NET full framework, SQL Database projects and the WebDeploy platform for deployments so we will need a few more capabilities installed.

Luckily all of the dependencies we need can be installed via the Visual Studio Build tools:

invoke-webrequest -uri ‘https://download.visualstudio.microsoft.com/download/pr/378e5eb4-c1d7-4c05-8f5f-55678a94e7f4/a022deec9454c36f75dafe780b797988b6111cfc06431eb2e842c1811151c40b/vs_BuildTools.exe‘ -OutFile vs2019_buildtools.exe -UseBasicParsing

.\vs2019_BuildTools.exe –quiet –wait –norestart –nocache –installPath C:\VSBuildTools –add Microsoft.VisualStudio.Workload.WebBuildTools –add Microsoft.VisualStudio.Component.SQL.SSDTBuildSku –add Microsoft.Net.Component.4.6.1.TargetingPack –add Microsoft.VisualStudio.Component.WebDeploy –add Microsoft.Net.Core.Component.SDK.2.1         –add Microsoft.Net.Core.Component.SDK.3.1Confirm

Here we are installing the build tools for web projects, database projects, WebDeploy and the newer .NET Core SDKs.  The installer isn’t super verbose in its output so its helpful to make sure it installed correctly.  Microsoft wrote a tool, vswhere, specifically for this purpose, which they use as part of their Azure Pipelines build tasks to ensure their dependencies are available.

& ‘C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe’ -products Microsoft.VisualStudio.Product.BuildTools

This command verifies the BuildTools product is installed for example.

The Agent

Lastly we need to install the Azure DevOps agent software.  In the Azure DevOps portal you can go the Project Settings, Pipelines, Agent Pools, select a pool and then click the New Agent button to view instructions and a download for the agent:

image

With that information we can download, unzip and install the agent software via PowerShell:

invoke-webrequest -uri https://vstsagentpackage.azureedge.net/agent/2.165.0/vsts-agent-win-x64-2.165.0.zip -UseBasicParsing -OutFile vsts-agent-win-x64-2.165.0.zip

Cd agent

Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::ExtractToDirectory(“C:\vsts-agent-win-x64-2.165.0.zip”, “$PWD”)

.\config.cmd –unattended –url https://[YourOrg].visualstudio.com –token [YourToken] –runAsService –runAsAutoLogon –windowsLogonAccount svcDeployUser@suturehealth.com –windowsLogonPassword ‘[YourPassword]’

You can create a personal access token (token/password) by going to User settings at the top right of the Azure DevOps portal and selecting “Personal access tokens”:

image

After installation your new agent should be listed in the agent pool.  You can view/adjust the capabilities list of the agent as well. Some Pipeline tasks will require the agent to have particular capabilities which you may need to configure:

image

Add that’s it.  You should now have a functioning and live agent to run your pipelines with. 

If this post was helpful or you have further questions, please share that by leaving a comment below.

Happy Building!

Leave a Reply