Running a VSTS build/release/deployment agent on a Raspberry Pi

Awww Yeeeaah. That's right.

Aww yeah!

If you're just here for the absolutely-totally-not-supported agent,
you can download it here.

Us VSTS Microsofties like to talk about "Any Language, Any Platform". We do demos with .NET and Java and Node on Macs and Ubuntu machines, and deploy code to Azure and AWS and on-prem.

So when I saw this tweet from Edward Thomson, I was intrigued πŸ€”:


Existing agent flavours

VSTS gives you a really easy way to install agents for Windows, macOS, Red Hat, and Ubuntu 14.04 and 16.04. Unfortunately, the Linux builds don't work on a Raspberry Pi. Probably not a surprise.

BUT, in typical recent-Microsoft style, the agents are open source! And they're written in C# for .NET Core!

vsts-agent-filesize

So it should be totally possible to compile it for the Pi, right?

Well, yes, but there were a few changes needed.

Building a Raspberry Pi agent

Thankfully (for everyone), I didn't have to write any code, because Edward already did that for me. He had a pull request already in the works (don't be surprised if that link breaks soon), so I just grabbed that PR and compiled it on my Pi.

To compile, I needed to run two commands:

> ./dev.sh build
> ./dev.sh package

In fact, that second command is probably totally useless because I just unzipped it again.

But lo and behold, I had a zipped up agent, just like the ones VSTS gave me!

Well, kind of.

Missing bit #1

The agents you download from VSTS include a few things that this compiled agent doesn't have.

The first was the configuration and run scripts. I'd just compiled the pure, unadulterated agent. I imagine the scripts aren't totally necessary to run the agent, but I'm lazy. So...

I downloaded a Linux agent using the "Download agent" link in the Admin settings > Agent pools section of VSTS (https://your-account.visualstudio.com/_settings/agentpools) to pilfer those files and copy them to my new agent folder.

The agent files

Now, I could run config.sh to configure and connect to VSTS, then run.sh to execute... and OMG the agent works!

The build agent runs!

And shows up in my pools

Deployment agents

A small aside.

Did you know the exact same agent is used for builds, releases, and even targets in deployment groups?

Yeah, we're big into reuse.

Same same but also the same

I really just wanted to use the Pi as a machine to deploy to, so I reconfigured it as a target in a deployment group.

What's the difference between those three agent types? Here's my 2 second summary:

  • Build agent - What you build your application with
  • Release agent - What you release your application with (actually the same agents)
  • Deployment agent - What you deploy your application to (different)

The separation isn't that black and white, but I'm getting off track, so ANYWAY...

I configured the agent as a deployment group target, ran it using run.sh again, and hooray, it connected!

Running the agent as a deployment target

Showing as healthy in VSTS

All that's left now is to create a basic release definition using the Deployment Group (the Bash script is just a hello world at this point), and run it!

The basic release definition

Awesome!

Missing bit #2

And it didn't work!

Wot

Why?

Well it turns out all* the tasks run via node. Yep, even if I have a single bash script in my build or release, it runs that baby through node.

There's probably a good reason. I should look into that.

* I don't actually know if it's all of them, but bash and python definitely do

The second missing bit is a packaged version of node. Remember that externals folder? Turns out there's a known version of node in there that the tasks use to run.

The agent files again

Which poses a problem - the versions that come with the supported agents won't work (I tried). They're for other OSs...

So what did I do? I just found similar folders elsewhere on the Pi and naively copied them over!

Hey, if it's stupid and it works, it's not stupid. πŸ‘‰πŸ‘‰

For the record, here's what I copied:

  • externals/node/bin - copy node from /usr/bin, and the npm shortcut from the linux agent (it won't resolve yet, but that's ok)
  • externals/node/lib/node_modules/npm - copy the whole npm folder from /usr/lib/node_modules

Sure enough, success!

Deployment succeeded!

Should I do this?

Probably not.

I mean, don't get me wrong, it's pretty cool being able to deploy directly to the Pi using an agent like this, but what if you have hundreds of devices, or you're actually deploying to 25 light globes or a refrigerator?

This works great for a Pi, but otherwise you're better served using Azure IoT Hub. That's what it's for after all.

So... off to research that!

Done

Damian Brady

I'm an Australian developer, speaker, and author specialising in DevOps, MLOps, developer process, and software architecture. I love Azure DevOps, GitHub Actions, and reducing process waste.

--