1
votes

I wonder if, for simplicity reasons, it is possible to create Azure DevOps self-hosted agents locally, reproducing all capabilities of the cloud-hosted ones. I need to use self-hosted agents, but do not want to create installation and upgrade scripts for each and every application on them.

I would imagine there is something like a VM image with all tools preinstalled; possibly the same as in Azure DevOps. This could potentially have the benefit of 100% compatibility.

What I have found so far:

How can I create "the perfect Azure DevOps agent"?

2
Hi Leo, reading, understanding and trying out solutions always takes time. I had voted for your answer to be helpful already; I am not sure what else would be expected while I am trying to understand the answer; please let me know. Back to topic: I've noticed that github.com/actions/virtual-environments/blob/main/help/… explains how exactly to build an image. It actually seems to work by running GenerateResourcesAndImage from helpers\GenerateResourcesAndImage.ps1 as described in the instructions.hey
Thanks for your quickly reply. If the answer below helps you solve your question, you could accept it as an answer, so it could help other community members who get the same issues and we could archive this thread, thanks. If not, please let me know if you would like further assistance.Leo Liu-MSFT

2 Answers

1
votes

How can I create "the perfect Azure DevOps agent"?

I have had the same request as you before, I agree with your views 2 and 3.

But because I am not very proficient in docker technology and need to maintain my docker environment frequently, I choose to use packer to build my image.

You could check below great document for some more details:

Build your own Hosted VSTS Agent Cloud: Part 1 - Build

Build your own Hosted VSTS Agent Cloud: Part 2 - Deploy

0
votes

Looks like we are in the same rabbit-hole. I started out with the same question as you posted, and it looks like you are on to the answer - setup a VM localy or on Azure and you are good to go. The links in the answer from "Leo Liu" is probably a good place to start. However - VMs are not Docker and this doesn't answer your broader question.

If the question is rephrased as "Why don't Microsoft provide an easy way to setup self-hosted agents in docker containers?" I believe the answer lies in their business model. Local VMs need Windows licenses and Azure VMs are billed by the hour...

But, conspiracy theories aside, I don't think there is an easy way to setup a dockerised version of the cloud-hosted agents. It's probably not a very good idea either. Docker containers are meant to be small, and with all of the dependencies on those agents they are anything but small. It's also never going to be "perfect", as you say, since the dockerized windows isn't identical to what's running in their cloud-hosted VMs.

I have started tweeking something that is not perfect, but might work:

  • setup a docker-agent according to the documentation here
  • add the essence from the PS-scripts corresponding to the packages you need from here
  • add commands to the Dockerfile to COPY and RUN the scripts
  • docker build as usual and you should have a container that's a bit more capable and an agent that reports its capabilities in a similar way to the cloud-agents

In an ideal world there would be a repository with all of the tweeked scripts, and a community that kept them updated. In an even more ideal world that would be a Microsoft hosted repository, but like I said - that's probably unlikely.

Here is some code to get you started. Maybe I'll publish a more finished version somewhere in the future.

init.ps1 with some lines borrowed from here:

Write-Host "Install chocolatey"
$chocoExePath = 'C:\ProgramData\Chocolatey\bin'

if ($($env:Path).ToLower().Contains($($chocoExePath).ToLower())) {
    Write-Host "Chocolatey found in PATH, skipping install..."
    Exit
}

$systemPath = [Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::Machine)
$systemPath += ';' + $chocoExePath
[Environment]::SetEnvironmentVariable("PATH", $systemPath, [System.EnvironmentVariableTarget]::Machine)

$userPath = [Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::User)
if ($userPath) {
    $env:Path = $systemPath + ";" + $userPath
}
else {
    $env:Path = $systemPath
}

Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

choco feature enable -n allowGlobalConfirmation

Remove-Item -Path $env:ChocolateyInstall\bin\cpack.exe -Force

Import-Module "$env:ChocolateyInstall\helpers\chocolateyInstaller.psm1" -Force
Get-ToolsLocation

Modified Dockerfile from the Microsoft documentation, that also runs the script on build:

FROM mcr.microsoft.com/windows/servercore:ltsc2019

COPY init.ps1 /Windows/Temp/init.ps1

RUN powershell -executionpolicy bypass C:\Windows\Temp\init.ps1

WORKDIR /azp

COPY start.ps1 .

CMD powershell .\start.ps1