How I added CircleCI Runner support for Terraform provider
Published: 2024-01-21 02:35:41

---
title: How I added CircleCI Runner support for Terraform provider
published: true
date: 2023-06-25 02:40:19 UTC
tags: 
canonical_url: https://write.as/kelvintaywl/how-i-added-circleci-runner-support-for-terraform-provider?pk_campaign=rss-feed
---

I have released support for the CircleCI Runner resource-class and token in [my **unofficial** Terraform provider for CircleCI](https://registry.terraform.io/providers/kelvintaywl/circleci/latest), as per v0.10.3.

Developers can now manage the provisioning (and teardown) of [CircleCI self-hosted Runners](https://circleci.com/docs/runner-overview/) within Terraform. You can explore an example [here](https://registry.terraform.io/providers/kelvintaywl/circleci/latest/docs/resources/runner_token).

This was a fun challenge, and I wanted to document my journey on this work.

## Investigation

Unlike other resources, self-hosted runners are not manageable under [the official V2 API](https://circleci.com/docs/api/v2/index.html). Developers had to use [the CircleCI CLI](https://circleci-public.github.io/circleci-cli/circleci_runner.html) to manage resource-classes and tokens instead.

To port this into my Terraform provider, I was hoping there was a HTTP API available. This way, I can continue using my approach of abstracting the HTTP API away to [a Go SDK](https://github.com/kelvintaywl/circleci-go-sdk).

I assumed (wrongly) the CLI was using GraphQL under the hood for Runner operations, as with many others (e.g., for Orbs).

Digging into the source-code, I then [realized Runner resource-classes and tokens can be managed via a HTTP API](https://github.com/kelvintaywl/terraform-provider-circleci/issues/35#issuecomment-1588587765); It was simply **not publicly documented, yet**.

## Glue

After the legwork mentioned above, I tested the HTTP APIs with [an OpenAPI (Swagger 2.0) document](https://github.com/kelvintaywl/circleci-runner-go-sdk/blob/main/openapi.yaml). This enabled me to generate [a Go SDK for Runner APIs](https://pkg.go.dev/github.com/kelvintaywl/circleci-runner-go-sdk).

_Why are the Go SDKs separated? Wouldn't it be easier to keep it all in one?_

That was something I mulled over for some time indeed. I have [documented my reasons](https://github.com/kelvintaywl/circleci-runner-go-sdk#notes) for keeping them **separate**.

## Assembly

With the Go SDK published, I “simply” have to then expose the Runner resource-classes and tokens in the Terraform provider codebase.

The main work was done within [a pull request here](https://github.com/kelvintaywl/terraform-provider-circleci/pull/40). This also included acceptance tests, and examples.

Ultimately, I noted self-hosted (machine) runners are also available for CircleCI's Server customers (i.e., self-hosted CircleCI). We would want to extend and ensure this addition can be used by platform teams using CircleCI Server.

It turned out that the Runner API:

- is via [https://runner.circleci.com](https://runner.circleci.com) for CircleCI Cloud
- is via [https://YOUR-SELF-HOSTED-DOMAIN](https://YOUR-SELF-HOSTED-DOMAIN) for CircleCI Server

Thankfully, this was [a quick patch](https://github.com/kelvintaywl/terraform-provider-circleci/pull/42). I was also able to verify this fix against my own CircleCI Server instance.

## Things I learnt

This feature was satisfying for me to build, and I had many learning points along the journey.

1. Read the code: This feature would not have been completed if I did not dig deeper into the publicly-available source code 📖

2. Keep trying: I am still learning (and failing) at Go. However, I think it is important to keep trying and learning. Keeping this source code open-sourced forces me to keep myself honest too about my lack of knowledge. For fellow engineers out there, let's keep at it! 🤓

[#terraform](https://write.as/kelvintaywl/tag:terraform) [#circleci](https://write.as/kelvintaywl/tag:circleci) [#runner](https://write.as/kelvintaywl/tag:runner) [#go](https://write.as/kelvintaywl/tag:go)

[buy Kelvin a cup of coffee](https://www.buymeacoffee.com/kelvintaywl) ☕