Terraform module for managing Hetzner Cloud servers with full support for all provider features including private networks, firewalls, placement groups, and advanced configuration options.
- Multi-server management: Manage multiple servers with a single module invocation.
- Private networking: Attach servers to Hetzner Cloud private networks with static IPs.
- Firewall integration: Apply firewalls at server creation time.
- Placement groups: Control server placement for high availability or performance.
- Flexible configuration: Support for all hcloud_server resource attributes.
- Common settings: Apply SSH keys, labels, and firewalls to all servers.
- Rich outputs: Detailed server information grouped by location, type, and more.
module "server" {
source = "danylomikula/server/hcloud"
version = "~> 1.0"
servers = {
web-1 = {
server_type = "cx23"
location = "nbg1"
image = "ubuntu-24.04"
ssh_keys = [12345]
labels = {
role = "webserver"
}
}
}
}module "network" {
source = "danylomikula/network/hcloud"
version = "~> 1.0"
create_network = true
name = "app-network"
ip_range = "10.0.0.0/16"
subnets = {
main = {
type = "cloud"
network_zone = "eu-central"
ip_range = "10.0.1.0/24"
}
}
}
module "servers" {
source = "danylomikula/server/hcloud"
version = "~> 1.0"
servers = {
app-01 = {
server_type = "cx23"
location = "nbg1"
image = "ubuntu-24.04"
networks = [{
network_id = module.network.network_id
ip = "10.0.1.10"
}]
}
app-02 = {
server_type = "cx23"
location = "fsn1"
image = "ubuntu-24.04"
networks = [{
network_id = module.network.network_id
ip = "10.0.1.11"
}]
}
}
common_ssh_keys = [12345]
common_labels = {
cluster = "app"
managed_by = "terraform"
}
}# Generate SSH key.
module "ssh_key" {
source = "danylomikula/ssh-key/hcloud"
version = "~> 1.0"
create_key = true
name = "cluster-key"
algorithm = "ED25519"
}
# Create network.
module "network" {
source = "danylomikula/network/hcloud"
version = "~> 1.0"
create_network = true
name = "web-network"
ip_range = "10.100.0.0/16"
subnets = {
web = {
type = "cloud"
network_zone = "eu-central"
ip_range = "10.100.1.0/24"
}
}
}
# Create servers.
module "server" {
source = "danylomikula/server/hcloud"
version = "~> 1.0"
servers = {
web-1 = {
server_type = "cx23"
location = "nbg1"
image = "ubuntu-24.04"
networks = [{
network_id = module.network.network_id
ip = "10.100.1.10"
}]
labels = {
role = "webserver"
}
}
}
common_ssh_keys = [module.ssh_key.ssh_key_id]
common_labels = {
managed_by = "terraform"
}
}See complete example for a full working configuration.
Install hcloud CLI:
brew install hcloudSetup guide: https://github.com/hetznercloud/cli/blob/main/docs/tutorials/setup-hcloud-cli.md
List server types:
hcloud server-type listList locations:
hcloud location listDocumentation: https://docs.hetzner.com/cloud/general/locations/
List available images:
# List all system images.
hcloud image list --type system
# Filter for specific OS.
hcloud image list --type system | grep ubuntu
hcloud image list --type system | grep rockyUse hcloud_image data source to automatically select the latest image:
# Find latest Rocky Linux 9 for x86 architecture.
data "hcloud_image" "rocky9" {
with_selector = "os-flavor=rocky"
with_architecture = "x86"
most_recent = true
}
# Find latest Ubuntu for ARM64.
data "hcloud_image" "ubuntu_arm" {
name = "ubuntu-24.04"
with_architecture = "arm64"
}
# Use in server configuration.
module "servers" {
source = "danylomikula/server/hcloud"
version = "~> 1.0"
servers = {
app-01 = {
server_type = "cx23"
image = data.hcloud_image.rocky9.name # Uses latest Rocky 9.
location = "nbg1"
}
app-arm = {
server_type = "cax11" # ARM64 server.
image = data.hcloud_image.ubuntu_arm.name
location = "fsn1"
}
}
}Data source reference: https://registry.terraform.io/providers/hetznercloud/hcloud/latest/docs/data-sources/image
Available selectors:
os-flavor=ubuntu/rocky/debian/fedoraos-version=22.04/9/12
Architectures:
x86- Standard Intel/AMD (cx, ccx series)arm- ARM64 (cax series)
- Use private networks for inter-server communication.
- Enable backups for production servers.
- Apply firewalls to restrict access.
- Use placement groups for high availability.
- Set labels for organization and management.
- Use common_* variables** to reduce duplication.
- Generate SSH keys via the ssh-key module.
The module uses ignore_changes for:
ssh_keys: Prevents recreation when keys are added manually.user_data: Prevents recreation when cloud-init data changes.
| Name | Version |
|---|---|
| terraform | >= 1.12.0 |
| hcloud | >= 1.45.0 |
| Name | Version |
|---|---|
| hcloud | >= 1.45.0 |
No modules.
| Name | Type |
|---|---|
| hcloud_server.this | resource |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| common_firewall_ids | List of firewall IDs to apply to all servers in addition to per-server firewalls. | list(number) |
[] |
no |
| common_labels | Labels to apply to all servers in addition to per-server labels. | map(string) |
{} |
no |
| common_ssh_keys | List of SSH key IDs to add to all servers in addition to per-server keys. | list(number) |
[] |
no |
| servers | Map of server configurations keyed by friendly name. | map(object({ |
{} |
no |
| Name | Description |
|---|---|
| private_network_ips | Map of server names to their private network IP addresses. |
| server_ids | Map of server names to their IDs. |
| server_ipv4_addresses | Map of server names to their IPv4 addresses. |
| server_ipv6_addresses | Map of server names to their IPv6 addresses. |
| servers | Map of all server resources with complete attributes. |
| servers_by_location | Map of locations to lists of server IDs in each location. |
| servers_by_type | Map of server types to lists of server IDs of each type. |
| Module | Description | GitHub | Terraform Registry |
|---|---|---|---|
| terraform-hcloud-network | Manage Hetzner Cloud networks and subnets | GitHub | Registry |
| terraform-hcloud-firewall | Manage Hetzner Cloud firewalls | GitHub | Registry |
| terraform-hcloud-ssh-key | Manage Hetzner Cloud SSH keys | GitHub | Registry |
Module managed by Danylo Mikula.
Contributions are welcome! Please read the Contributing Guide for details on the process and commit conventions.
Apache 2.0 Licensed. See LICENSE for full details.