Chris Umbel

Adding a Stand-alone Windows Worker to a bosh-managed Concourse Deployment


In this article I'll demonstrate the procedure for adding a manually-built Windows worker to an existing bosh-managed Concourse deployment. For demonstrative purposes I'll also use our deployment to run a simple pipeline that builds a .NET console application on our newly-created worker.

I'll assume that the Concourse deployment is relatively vanilla and the "tsa" job hasn't substantially changed from the manifest provided by the installation instructions.

This article will *not* be covering building Windows bosh stemcells or deploying Windows workers with bosh. One day when the space matures a little I may do so.


I'll assume provide the following resources. Everything else will be downloaded, generated, built or otherwise conjured.

  • A running Windows server
  • A bosh-managed Concourse deployment
  • A workstation with ssh-keygen
  • The bosh cli targeted at your Concourse's bosh director.
  • A basic understanding of Concourse's architecture, specifically the TSA component.

Generating SSH Keys

In order for a trust relationship to be established and for a worker to register itself with the TSA two ssh RSA keypairs are required.

  • TSA Host Key - the key identifying TSA service.
  • Worker Key - the key identifying the worker(s). Multiple workers can share this key, but you can also have many of these keys spread across many workers.

The TSA Host and Worker keys can respectively be generated with commands similar to the following:

~/ $ ssh-keygen -f tsakey -t rsa  -N ''
~/ $ ssh-keygen -f workerkey -t rsa  -N '' 

which would grant us the files:

~/ $ ls
tsakey	workerkey

The "tsakey" and "workerkey" files are the encoded private keys for the TSA host and workers, respectively, with "" and "" being their public keys.

Preparing the TSA

All of the configuration necessary to prepare the TSA to register our Windows worker involves the keys generated above.

If your Concourse's "tsa" job remains stock it will likely look like this in your deployment manifest:

  - name: tsa
    release: concourse
    properties: {}

We're going to want to add 3 properties to supplement that default configuration:

  • authorized_keys - an array of public keys belonging to workers that TSA should trust. Add this property and a string entry containing the content of "". This establishes trust from our TSA to workers with the corresponding private key.
  • host_key - the private key beling to our deployment's TSA job. Add this property with its content copied from the "tsakey" file.
  • host_public_key - the public key belonging to our deployment's TSA job. Add this property with its content copied from the "" file. Note that we'll be distributing this key to our workers.

resulting in a deployment manifest outlined like this:

  - name: tsa
    release: concourse
       - ""
      host_key: |
        -----BEGIN RSA PRIVATE KEY-----
       - ""
        -----END RSA PRIVATE KEY-----
      host_public_key: ""

After updating our deployment as such

~/ bosh deploy

our TSA will be updated with the keys necessary to register the Windows worker we'll build.

Preparing The Windows Worker

Now we turn our attention to our Windows server that we'll be turning in to a Concourse worker.

First we'll want to establish a directory to house our binaries for the worker service and its data i.e. C:\concourse

C:\> mkdir concourse
C:\> cd concourse

Now download the Windows concourse binary (named something like "concourse_windows_amd64.exe") from the Concourse download page and place it in our working directory. Also, we'll want to copy the "" and "workerkey" files there as well.

The fact that we'll provide our local concourse binary with "" establishes that we cryptographically trust the TSA server from our deployment.

We're now ready to start the worker and have it register itself with the TSA.

C:\concourse> .\concourse_windows_amd64.exe worker \
   /work-dir .\work /tsa-host  \
   /tsa-public-key .\ \
   /tsa-worker-private-key .\workerkey

If all goes well we should see output similar to:


and the new worker should appear in the list via the Concourse CLI as such:

~/  $ fly -t ci workers
name            containers  platform  tags  team
2a334e70-c75c   3           linux     none  none
WORKERSHOSTNAME 0           windows   none  none

Testing Things Out

Assuming the .NET framework is present on our Worker with the build tools in the path we could test this out by building this simple .NET Console app project:

Consider the pipeline:

  - name: code
    type: git
      branch: master
  - name: build
    - aggregate:
      - get: code
        trigger: true
    - task: compile
      privileged: true
      file: code/Pipeline/compile.yml

with the build task:

platform: windows    
  - name: code
  dir: code
  path: msbuild

Note that the platform specified in the build task is "windows". That instructs concourse to place the task on a Windows worker.

If all went well we should see a successful build with output similar to:

~/ $ fly -t ci trigger-job -j datdotnet/build --watch
started datdotnet/build #8

using version of resource found in cache
running msbuild
Microsoft (R) Build Engine version 4.6.1085.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
Build started 11/5/2016 4:04:00 PM.
nces, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. [C:\concourse\work\containers\00000arl2se\tmp\build\36d0981b\code\DatDotNet\DatDotNet.csproj]

    3 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.22

Sat Nov 05 2016 12:00:00 GMT+0000 (UTC)

Follow Chris
RSS Feed