terraform-provider-hcloud keeps Hetzner resources in HCL only
Terraform Hetzner Cloud provider
At a glance
- What is it?
- The Hetzner Cloud Terraform provider is a Go plugin that manages Hetzner Cloud services from HCL, built on the Terraform plugin framework with an older SDK path still in the tree. It suits teams that want infrastructure for Hetzner servers, networks and volumes managed the same way as the rest of their estate, and its Go packages are explicitly not a stable API.
- Who is it for?
- Adopt terraform-provider-hcloud when your infrastructure includes Hetzner Cloud and you want it managed as Terraform resources rather than through the cloud console or a bespoke script, and when you can pin a released provider version. Do not import its Go packages into your own code, because the project states that the Go code may change without a major version increase and guarantees compatibility only through HCL.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A provider for Hetzner Cloud, not a general purpose SDK
This repository is the Terraform provider for the Hetzner Cloud, and the scope is narrow in a way that is easy to appreciate. It is a Go module that implements a Terraform provider for Hetzner Cloud services, sitting on top of the official hcloud-go client, which the go.mod pins at v2.52.0. The provider exposes resources and data sources through Terraform's own plugin protocol, and the documentation for the released version is published on the Terraform registry. The practical consequence is that the way to use this project is through HCL, not through Go. The development section says it plainly: the Go code in this repository may change without a major version increase, and backwards compatibility is guaranteed only for use through Terraform HCL. If you have written a Go program that provisions Hetzner servers by importing provider internals, that code has no stability guarantee at all.
Two plugin frameworks in one binary
The dependency list shows the interesting engineering decision. The go.mod requires both terraform-plugin-framework at v1.19.0, the modern framework, and terraform-plugin-sdk/v2 at v2.40.1, the older SDK, along with terraform-plugin-mux at v0.23.1, which is the component that lets both serve side by side. That combination is how a provider that has existed for years can move new resources onto the newer framework without a breaking change, because the mux dispatches to whichever framework owns a given resource. The plugin protocol requirement is stated as version 6, and the provider should work with any tool that supports it, which is what makes it usable with OpenTofu as well as Terraform. The provider tests run against releases of either tool that are supported upstream, so the test matrix is not an arbitrary choice.
The package layout is mid migration, and the project says so
Currently the code is mostly located in the hcloud package, and in the long term the maintainers want to move most of that package into individual sub-packages located in the internal directory. The stated goal is a structure similar to HashiCorp's Terraform Provider Scaffolding. Two things follow from that sentence. First, the current layout is a transitional state that is intended to change, so an import path you find today may not be one you find next year, which is consistent with the warning about Go code changing without a major version bump. Second, the destination matters, because internal packages are not importable from outside the module at all, so the migration removes the possibility of accidental external dependency on provider internals. The tree also carries the standard provider furniture, with docs/ for the documentation, examples/ split into data-sources, functions, provider and resources, templates/ for the doc templates, tools/ for the tooling, a GNUmakefile, a .goreleaser.yml for the release build, renovate.json for dependency updates, and a .pre-commit-config.yaml.
Building it locally, with a dev override for the provider
Building the provider from source is a make target. The clone instructions place the repository under the GOPATH:
$ mkdir -p $GOPATH/src/github.com/hetznercloud; cd $GOPATH/src/github.com/hetznercloud
$ git clone https://github.com/hetznercloud/terraform-provider-hcloud.gitand then make build compiles it and puts the binary in the $GOPATH/bin directory, with the runnable binary being ./bin/terraform-provider-hcloud. The point of building locally is to test your change, and the way to point Terraform at a local build is a dev override. You choose a CLI config file path:
export TF_CLI_CONFIG_FILE="terraform.tfrc"and inside it you override the lookup path for the hetznercloud/hcloud provider:
provider_installation {
dev_overrides {
"hetznercloud/hcloud" = "$PWD"
}
direct {}
}After a build, running tofu plan produces a warning that provider development overrides are in effect, that the behavior may therefore not match any released version of the provider, and that applying changes may cause the state to become incompatible with published releases. That warning is the important part of the workflow, since a dev override bypasses version pinning for that provider only.
Acceptance tests create real servers and cost money
The test story is split in a way that reflects how provider work is usually done. Unit tests run with make test, and the full acceptance suite runs with make testacc, with the note that acceptance tests create real resources and often cost money to run. The environment for those tests goes in a .env file, and the example shows the shape:
$ cat .env
HCLOUD_TOKEN=YOUR_API_TEST_TOKEN
#TF_ACC=1
TF_LOG=DEBUG
TF_LOG_PATH_MASK=test-%s.logThe variables are a real Hetzner API token, a commented out TF_ACC switch which is the standard Terraform convention for enabling acceptance tests, and Terraform's own logging controls. The token in that file is the thing to protect, since it is a token that can create and destroy billable servers, and the .env pattern is the reason a .gitignore entry matters here. The provider also depends on godotenv to load that file, so the environment is read from disk rather than only from the shell.
Experimental features and deprecations come with rules
Two policy sections in the documentation are worth more than most changelogs, because they tell you what to expect when you turn on a new feature. To publish an experimental feature as part of a regular release, the project requires an announcement including a link to a changelog entry, an Experimental notice added to the resource, datasource and function descriptions, and an Experimental warning logged when the feature is used. Both are implemented by calling into an experimental package, once to append a notice to the schema's MarkdownDescription and once to append a diagnostic to the response diagnostics. The deprecation policy is equally concrete. You mark the attribute as deprecated in the schema and explain the deprecation with a link to the changelog, and for inputs you implement backwards-compatible behaviour where possible, while for outputs you keep writing the attribute for as long as the API returns it, falling back to the user config or previous state, or an empty string under SDKv2 or null under the Plugin Framework, once the API stops returning it. The documentation also asks for a Deprecations section in the resource and datasource docs.
Release pace and the licence
The project is not archived and the last push was on 2026-10-20, with releases v1.70.0 on 2026-10-05, v1.69.0 on 2026-09-11 and v1.68.0 on 2026-07-28. That is roughly one release every six to eight weeks, which for a cloud provider tracking a fast moving API is a reasonable pace, and the version number has passed 1.0 long ago, so the semver line is being used as a normal published provider rather than a pre-1.0 project. The licence is MPL-2.0, which is the weak copyleft choice, so using the provider as a binary in your own tooling imposes no obligation on your proprietary code while modifications to the provider itself stay open. The primary language is Go, the go.mod requires go 1.26.4, and the developer's own instructions mention Go 1.14 or newer as required for working on the provider, which is a note worth ignoring in favour of the version in the module file.
Editorial conclusion
Adopt terraform-provider-hcloud when your infrastructure includes Hetzner Cloud and you want it managed as Terraform resources rather than through the cloud console or a bespoke script, and when you can pin a released provider version. Do not import its Go packages into your own code, because the project states that the Go code may change without a major version increase and guarantees compatibility only through HCL. Verify first that your Terraform or OpenTofu version speaks plugin protocol version 6, that you have an API token with the scopes your resources need, and that a dev_overrides setup is what you want, since it changes the behaviour of plan and apply for that provider only.
Frequently asked questions
Which Terraform versions does terraform-provider-hcloud support?
The provider should work with any tool that supports the terraform plugin protocol version 6, which includes Terraform and OpenTofu, and the provider tests run with releases of either that are supported upstream.
Can I use the Go packages of terraform-provider-hcloud in my own code?
The project states that it guarantees backwards compatibility only for use through Terraform HCL, and that the actual Go code in the repository may change without a major version increase. The code is also being reorganised from the hcloud package into internal sub-packages, which will make those paths unimportable from outside the module.
How do I test a local build of terraform-provider-hcloud?
Build it with make build, then point Terraform at the working directory with a dev_overrides block in the CLI config file for the hetznercloud/hcloud provider, set TF_CLI_CONFIG_FILE to that file, and run a plan. Terraform will warn that provider development overrides are in effect and that the behaviour may not match a released version.
Do the acceptance tests for terraform-provider-hcloud cost money?
Yes. The documentation notes that acceptance tests create real resources and often cost money to run. The environment for them goes in a .env file with an HCLOUD_TOKEN for the API test token, a commented out TF_ACC=1 switch, and the Terraform logging settings.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/hetznercloud-terraform-provider-hcloud)Was this useful?