Migrating a Terraform Provider from dep to Go Modules
Recently, I've had to start maintaining a fork of
terraform-provider-k8s, as
part of our workflow at work has been applying raw Kubernetes manifests via
Terraform. The official Terraform Kubernetes
provider doesn't
support applying arbitrary YAML manifests. Our teams work with minikube locally
and directly with kubectl in dev. Being able to use the standard form in
later deployment environments gets us the best of both worlds.
We've been running this provider for a while now and it's still using
dep for dependency management. With
Terraform 0.12 recently released and Go modules now on by default, it's time to
modernise the repo. This post covers the migration from dep to Go 1.11
modules and Terraform 0.12 update.
Go Modules?
The Go developer made Modules available in Go 1.11 back in August last year,
with the setting becoming default on via GO111MODULE in Go 1.12 in February.
While dep had its place previously, now the language has official tooling it
is time to migrate.
For us there are a few practical motivations:
- Terraform 0.12 compatibility - Terraform 0.12 landed in May and brings significant changes to the plugin SDK. Since 0.11.12 they have been using Go modules.
- Simpler CI - With modules,
go buildandgo testis all we need. Who doesn't love to drop a tooling dependency.
Migrating
1. Initialise the module
First, we initialise the Go module.
$ go mod init github.com/fiveai/terraform-provider-k8s
This generates a go.mod and go.sum file. The go.mod file is refreshingly
simple compared to Gopkg.toml:
2. Tidy up
$ go mod tidy
This prunes unneeded dependencies and adds any that are missing. Good practice to run this after the initial conversion to make sure everything is clean.
3. Verify and test
$ go build ./...
$ go test ./...
If everything compiles and the tests pass, you're in good shape. For us, this just worked, no need to change or update anything.
4. Remove dep files
Once you're happy, remove the old dep files:
$ rm Gopkg.toml Gopkg.lock
$ rm -rf vendor/
Updating to Terraform 0.12
With modules in place, updating to Terraform 0.12 was just a matter of updating
the dependency versions in go.mod. Terraform 0.12 brings some breaking
changes to the plugin SDK but for our provider the impact is minimal since we
mostly shell out to kubectl rather than using the SDK's resource helpers
extensively.
Release Tooling
While I was making changes, I decided I might as well add cross-compiling to other platforms. The Makefile builds for Linux, macOS and Windows across amd64 which covers our team's needs, every dev likes their own environment. It isn't the year of the Linux Desktop, yet.
BINARY=terraform-provider-k8s
build:
go build -o $(BINARY)
release:
GOOS=linux GOARCH=amd64 go build -o $(BINARY)_linux_amd64
GOOS=darwin GOARCH=amd64 go build -o $(BINARY)_darwin_amd64
GOOS=windows GOARCH=amd64 go build -o $(BINARY)_windows_amd64.exe
Summary
The migration from dep to Go modules was smoother than expected (how many waves of Python package management has there been now?) Combined with Terraform 0.12 and some release tooling, we've brought the provider up to date with where the Go and Terraform ecosystems are heading.
As always, I appreciate any feedback or if you want to reach out, I'm
@neuralsandwich on twitter and most other places.