Part one | The first problem with VSTS is the default agent pools, they are awfully slow and the solution is to deploy your own agent pool. So why not? This is the first part of how to deploy your new VSTS agent pool from VSTS to Azure using ARM templates and Powershell DSC.
We are actually starting in the reverse order by doing the last step of the deployment first. By now everyone that works and lives in the cloud should at least know that ARM and DSC is. I dont know about you but i personally think that DSC is the harder one to learn. So thats going to be my starting point, in this blog we are going to look at the DSC that will configure your newly installed VM to be a agent in the VSTS pool and also install node.js.
DSC
The DSC only have one configuration and all node names get the same configuration. Because we are going to deploy this DSC through our Azure resource manager (ARM) template we don’t need any complex logic of which computer gets which configuration.
To be able to compile the DSC below you will need to install two DSC modules
Find-Module xPSDesiredStateConfiguration | install-module
Find-Module PackageManagement -MaximumVersion “1.1.7.0” | install-module
Configuration Main {
Param ( [string] $nodeName )
$AgentzipName = "vsts-agent-win-x64-2.127.0.zip"
$AgentDownloadUrl = ("https://vstsagentpackage.azureedge.net/agent/2.127.0/{0}" -f $AgentzipName)
$installsource = "C:\vstsAgent"
$PATToken = "[your vsts pat token]"
$poolName = "AzureAgents"
$VSTSUrl = "https://XXXXXXX.visualstudio.com"
Import-DscResource -ModuleName PSDesiredStateConfiguration
Import-DscResource -Module xPSDesiredStateConfiguration
Import-DSCResource -ModuleName PackageManagement -ModuleVersion "1.1.7.0"
Node $nodeName
{
File InstallFolder {
#Create Installation folder
Ensure = "Present"
DestinationPath = $installsource
Type = "Directory"
}
Script Chocolatey {
SetScript = {
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
}
TestScript = {
try{[boolean](cver all)} catch {[boolean]($fasle)}
}
GetScript = { @{ Result = "OK" } }
}
Script nodejs {
SetScript = {
Start-Process -FilePath "chocolatey" -ArgumentList "feature enable -n allowGlobalConfirmation" -Wait
start-process -FilePath "cinst" -ArgumentList "nodejs.install --force --safe" -Wait
}
TestScript = {
try{
$res = (clist nodejs --localonly)
-not ($res[1] -match "0 packages installed")
} catch {[boolean]($fasle)}
}
GetScript = { @{ Result = "OK" } }
dependsOn = "[Script]Chocolatey"
}
Script DownloadAgentFiles {
#Download agent
SetScript = {
wget -OutFile "$using:installsource\$using:AgentzipName" -Uri $using:AgentDownloadUrl
}
TestScript = {
Test-Path "$using:installsource\$using:AgentzipName"
}
GetScript = { @{ Result = "OK" } }
DependsOn = "[File]InstallFolder"
}
Archive UnzipAgentFiles {
Destination = "${installsource}\agent"
Path = "${installsource}\${AgentzipName}"
DependsOn = @(
"[Script]DownloadAgentFiles"
)
}
Script ConfigureAgent {
SetScript = {
$Argument = "configure --unattended --agent $env:COMPUTERNAME --url $using:VSTSUrl --auth PAT --token $using:PATToken --pool `"$using:poolName`" --work d:\build --runAsService --windowsLogonAccount 'NT AUTHORITY\SYSTEM' --acceptTeeEula --replace"
Write-Host "$using:installsource\agent\bin\Agent.Listener.exe"
start-process -FilePath "$using:installsource\agent\bin\Agent.Listener.exe" -ArgumentList $Argument -Wait -RedirectStandardOutput o
}
TestScript = {
[boolean](get-service -DisplayName "VSTS*")
}
GetScript = { @{ Result = "OK" } }
DependsOn = @(
"[Archive]UnzipAgentFiles",
"[Script]nodejs"
)
}
}
}
Now do the following:
- Save the code to your project folder
- Change the $PATToken variable in the DSC, follow this link for instructions how to get the pat token.
https://docs.microsoft.com/en-us/vsts/accounts/use-personal-access-tokens-to-authenticate?view=vsts - (Optional) Change $AgentzipName and $AgentDownloadUrl to match the latest VSTS agent.
- Change the $poolName variable to match you VSTS Agent pool namn.
- Change the $VSTSUrl variable to match the url of your VSTS instance
DSC Resources
Let’s walk through the resources in the DSC.
- File InstallFolder – We ensure there is a folder to hold the agent binaries.
- Script Chocolatey – The script tries to run cver (chocolatey command) to detect if chocolatey is installed, if not we run the hosted ps1 script to install it.
- Script nodejs – Another script that uses chocolatey to install node.js. To be able to do this from a DSC, we first need to enable the allowGlobalConfirmation feature. Otherwise the –force –safe switches doesnt work.
- Script DownloadAgentFiles – This script downloads the VSTS agent binaries.
- Archive UnzipAgentFiles – Unzip the VSTS agent installation files.
- Script ConfigureAgent – Last step is to install and configure the agent.
The end
Congratulations you are done for now. At this point you can manually run the DSC configuration on any windows server to configure it to be an VSTS build agent.
But we are not going to. Instead in my next post we will create a ARM template and add the DSC to it.