hetzner-coder

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Hetzner Coder

Hetzner Coder

Overview

概述

Hetzner Cloud offers high-performance, cost-effective cloud infrastructure with European data centers. This skill covers OpenTofu/Terraform patterns for Hetzner resources.
Hetzner Cloud 提供高性能、高性价比的云基础设施,数据中心位于欧洲。本技能涵盖了针对Hetzner资源的OpenTofu/Terraform配置模式。

Provider Setup

提供商配置

hcl
terraform {
  required_providers {
    hcloud = {
      source  = "hetznercloud/hcloud"
      version = "~> 1.50"
    }
  }
}

provider "hcloud" {
  # Token from environment: HCLOUD_TOKEN
  # Or explicitly (not recommended):
  # token = var.hcloud_token
}
hcl
terraform {
  required_providers {
    hcloud = {
      source  = "hetznercloud/hcloud"
      version = "~> 1.50"
    }
  }
}

provider "hcloud" {
  # 令牌来自环境变量: HCLOUD_TOKEN
  # 或显式配置(不推荐):
  # token = var.hcloud_token
}

Authentication

身份认证

bash
undefined
bash
undefined

Set token via environment variable

通过环境变量设置令牌

export HCLOUD_TOKEN="your-api-token"
export HCLOUD_TOKEN="your-api-token"

Or with 1Password

或使用1Password

HCLOUD_TOKEN=op://Infrastructure/Hetzner/api_token

**Token Permissions:**
- **Read** - GET requests only (monitoring, auditing)
- **Read & Write** - Full access (required for Terraform)
HCLOUD_TOKEN=op://Infrastructure/Hetzner/api_token

**令牌权限:**
- **只读** - 仅允许GET请求(监控、审计)
- **读写** - 完全访问权限(Terraform配置时需要)

Locations and Datacenters

数据中心与区域

LocationCodeRegionNetwork Zone
Falkenstein
fsn1
Germany
eu-central
Nuremberg
nbg1
Germany
eu-central
Helsinki
hel1
Finland
eu-central
Ashburn
ash
US East
us-east
Hillsboro
hil
US West
us-west
区域代码地区网络区域
Falkenstein
fsn1
德国
eu-central
Nuremberg
nbg1
德国
eu-central
Helsinki
hel1
芬兰
eu-central
Ashburn
ash
美国东部
us-east
Hillsboro
hil
美国西部
us-west

Server Types

服务器实例类型

Shared CPU (Best for general workloads)

共享CPU(适用于通用工作负载)

TypevCPUsRAMStorageBest For
cx22
24 GB40 GBSmall apps
cx32
48 GB80 GBMedium apps
cx42
816 GB160 GBProduction
cx52
1632 GB320 GBHigh traffic
实例类型虚拟CPU核心数内存存储适用场景
cx22
24 GB40 GB小型应用
cx32
48 GB80 GB中型应用
cx42
816 GB160 GB生产环境
cx52
1632 GB320 GB高流量场景

AMD EPYC (CPX - Better single-thread)

AMD EPYC(CPX - 单线程性能更优)

TypevCPUsRAMStorage
cpx11
22 GB40 GB
cpx21
34 GB80 GB
cpx31
48 GB160 GB
cpx41
816 GB240 GB
cpx51
1632 GB360 GB
实例类型虚拟CPU核心数内存存储
cpx11
22 GB40 GB
cpx21
34 GB80 GB
cpx31
48 GB160 GB
cpx41
816 GB240 GB
cpx51
1632 GB360 GB

ARM64 (CAX - Best price/performance)

ARM64(CAX - 性价比最优)

TypevCPUsRAMStorage
cax11
24 GB40 GB
cax21
48 GB80 GB
cax31
816 GB160 GB
cax41
1632 GB320 GB
实例类型虚拟CPU核心数内存存储
cax11
24 GB40 GB
cax21
48 GB80 GB
cax31
816 GB160 GB
cax41
1632 GB320 GB

Dedicated vCPU (CCX - Guaranteed resources)

专属虚拟CPU(CCX - 资源有保障)

TypevCPUsRAMStorage
ccx13
28 GB80 GB
ccx23
416 GB160 GB
ccx33
832 GB240 GB
ccx43
1664 GB360 GB
实例类型虚拟CPU核心数内存存储
ccx13
28 GB80 GB
ccx23
416 GB160 GB
ccx33
832 GB240 GB
ccx43
1664 GB360 GB

Servers (Compute)

服务器(计算资源)

Basic Server

基础服务器

hcl
resource "hcloud_server" "app" {
  name        = "${var.project}-${var.environment}-app"
  server_type = "cx22"
  image       = "ubuntu-24.04"
  location    = "fsn1"

  ssh_keys = [hcloud_ssh_key.deploy.id]

  labels = {
    environment = var.environment
    project     = var.project
    role        = "app"
  }

  public_net {
    ipv4_enabled = true
    ipv6_enabled = true
  }
}
hcl
resource "hcloud_server" "app" {
  name        = "${var.project}-${var.environment}-app"
  server_type = "cx22"
  image       = "ubuntu-24.04"
  location    = "fsn1"

  ssh_keys = [hcloud_ssh_key.deploy.id]

  labels = {
    environment = var.environment
    project     = var.project
    role        = "app"
  }

  public_net {
    ipv4_enabled = true
    ipv6_enabled = true
  }
}

Server with Cloud-Init

配置Cloud-Init的服务器

hcl
resource "hcloud_server" "app" {
  name        = "${var.project}-app"
  server_type = "cx22"
  image       = "ubuntu-24.04"
  location    = "fsn1"

  ssh_keys = [hcloud_ssh_key.deploy.id]

  user_data = <<-EOT
    #cloud-config
    package_update: true
    packages:
      - docker.io
      - docker-compose-plugin

    users:
      - name: deploy
        groups: docker, sudo
        sudo: ALL=(ALL) NOPASSWD:ALL
        shell: /bin/bash
        ssh_authorized_keys:
          - ${var.deploy_ssh_key}

    runcmd:
      - systemctl enable --now docker
      - sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
      - sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
      - systemctl restart sshd
  EOT

  labels = {
    environment = var.environment
    role        = "app"
  }
}
hcl
resource "hcloud_server" "app" {
  name        = "${var.project}-app"
  server_type = "cx22"
  image       = "ubuntu-24.04"
  location    = "fsn1"

  ssh_keys = [hcloud_ssh_key.deploy.id]

  user_data = <<-EOT
    #cloud-config
    package_update: true
    packages:
      - docker.io
      - docker-compose-plugin

    users:
      - name: deploy
        groups: docker, sudo
        sudo: ALL=(ALL) NOPASSWD:ALL
        shell: /bin/bash
        ssh_authorized_keys:
          - ${var.deploy_ssh_key}

    runcmd:
      - systemctl enable --now docker
      - sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
      - sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
      - systemctl restart sshd
  EOT

  labels = {
    environment = var.environment
    role        = "app"
  }
}

ARM64 Server (Cost-Effective)

ARM64服务器(高性价比)

hcl
resource "hcloud_server" "worker" {
  name        = "${var.project}-worker"
  server_type = "cax21"  # ARM64 - great price/performance
  image       = "ubuntu-24.04"
  location    = "fsn1"

  ssh_keys = [hcloud_ssh_key.deploy.id]

  labels = {
    role = "worker"
    arch = "arm64"
  }
}
hcl
resource "hcloud_server" "worker" {
  name        = "${var.project}-worker"
  server_type = "cax21"  # ARM64 - 性价比出色
  image       = "ubuntu-24.04"
  location    = "fsn1"

  ssh_keys = [hcloud_ssh_key.deploy.id]

  labels = {
    role = "worker"
    arch = "arm64"
  }
}

Private Networks

私有网络

Network with Subnet

带子网的网络

hcl
resource "hcloud_network" "private" {
  name     = "${var.project}-network"
  ip_range = "10.0.0.0/16"

  labels = {
    project = var.project
  }
}

resource "hcloud_network_subnet" "private" {
  network_id   = hcloud_network.private.id
  type         = "cloud"
  network_zone = "eu-central"  # Must match server location zone
  ip_range     = "10.0.1.0/24"
}
hcl
resource "hcloud_network" "private" {
  name     = "${var.project}-network"
  ip_range = "10.0.0.0/16"

  labels = {
    project = var.project
  }
}

resource "hcloud_network_subnet" "private" {
  network_id   = hcloud_network.private.id
  type         = "cloud"
  network_zone = "eu-central"  # 必须与服务器所在区域的网络区域匹配
  ip_range     = "10.0.1.0/24"
}

Server in Private Network

加入私有网络的服务器

hcl
resource "hcloud_server" "db" {
  name        = "${var.project}-db"
  server_type = "cpx31"
  image       = "ubuntu-24.04"
  location    = "fsn1"

  ssh_keys = [hcloud_ssh_key.deploy.id]

  # Attach to private network
  network {
    network_id = hcloud_network.private.id
    ip         = "10.0.1.10"  # Optional: specific IP
  }

  # Optionally disable public IP for security
  public_net {
    ipv4_enabled = false
    ipv6_enabled = false
  }

  labels = {
    role = "database"
  }

  depends_on = [hcloud_network_subnet.private]
}
hcl
resource "hcloud_server" "db" {
  name        = "${var.project}-db"
  server_type = "cpx31"
  image       = "ubuntu-24.04"
  location    = "fsn1"

  ssh_keys = [hcloud_ssh_key.deploy.id]

  # 关联到私有网络
  network {
    network_id = hcloud_network.private.id
    ip         = "10.0.1.10"  # 可选:指定静态IP
  }

  # 为了安全,可选择禁用公网IP
  public_net {
    ipv4_enabled = false
    ipv6_enabled = false
  }

  labels = {
    role = "database"
  }

  depends_on = [hcloud_network_subnet.private]
}

Firewalls

防火墙

Web Server Firewall

Web服务器防火墙

hcl
resource "hcloud_firewall" "web" {
  name = "${var.project}-web-firewall"

  # SSH from specific IPs only (NEVER use 0.0.0.0/0!)
  rule {
    description = "SSH"
    direction   = "in"
    protocol    = "tcp"
    port        = "22"
    source_ips  = [var.admin_ip]  # Use variable, no default
  }

  # HTTP/HTTPS from anywhere
  rule {
    description = "HTTP"
    direction   = "in"
    protocol    = "tcp"
    port        = "80"
    source_ips  = ["0.0.0.0/0", "::/0"]
  }

  rule {
    description = "HTTPS"
    direction   = "in"
    protocol    = "tcp"
    port        = "443"
    source_ips  = ["0.0.0.0/0", "::/0"]
  }

  # ICMP for debugging (ping)
  rule {
    description = "ICMP"
    direction   = "in"
    protocol    = "icmp"
    source_ips  = ["0.0.0.0/0", "::/0"]
  }

  # Apply to servers with label
  apply_to {
    label_selector = "role=web"
  }
}
hcl
resource "hcloud_firewall" "web" {
  name = "${var.project}-web-firewall"

  # 仅允许特定IP访问SSH(绝对不要使用0.0.0.0/0!)
  rule {
    description = "SSH"
    direction   = "in"
    protocol    = "tcp"
    port        = "22"
    source_ips  = [var.admin_ip]  # 使用变量,不设置默认值
  }

  # 允许任意IP访问HTTP/HTTPS
  rule {
    description = "HTTP"
    direction   = "in"
    protocol    = "tcp"
    port        = "80"
    source_ips  = ["0.0.0.0/0", "::/0"]
  }

  rule {
    description = "HTTPS"
    direction   = "in"
    protocol    = "tcp"
    port        = "443"
    source_ips  = ["0.0.0.0/0", "::/0"]
  }

  # 允许ICMP用于调试(ping)
  rule {
    description = "ICMP"
    direction   = "in"
    protocol    = "icmp"
    source_ips  = ["0.0.0.0/0", "::/0"]
  }

  # 应用到带有指定标签的服务器
  apply_to {
    label_selector = "role=web"
  }
}

IMPORTANT: admin_ip variable has NO default for security

重要提示:admin_ip变量不设置默认值以保障安全

variable "admin_ip" { description = "Admin IP for SSH access (CIDR) - REQUIRED, no default" type = string

NO DEFAULT - forces explicit value

}

**Security pattern:** Never default SSH access to `0.0.0.0/0`. Force explicit IP:

```bash
tofu apply -var="admin_ip=$(curl -s ifconfig.me)/32"
variable "admin_ip" { description = "用于SSH访问的管理员IP(CIDR格式) - 必填,无默认值" type = string

无默认值 - 强制用户显式指定

}

**安全最佳实践:** 绝对不要将SSH访问默认设置为`0.0.0.0/0`。强制用户指定具体IP:

```bash
tofu apply -var="admin_ip=$(curl -s ifconfig.me)/32"

Database Firewall (Private Only)

数据库防火墙(仅允许私有网络访问)

hcl
resource "hcloud_firewall" "db" {
  name = "${var.project}-db-firewall"

  # PostgreSQL from private network only
  rule {
    description = "PostgreSQL"
    direction   = "in"
    protocol    = "tcp"
    port        = "5432"
    source_ips  = ["10.0.0.0/16"]  # Private network range
  }

  # SSH from bastion only
  rule {
    description = "SSH from bastion"
    direction   = "in"
    protocol    = "tcp"
    port        = "22"
    source_ips  = ["10.0.1.1/32"]  # Bastion IP
  }

  apply_to {
    label_selector = "role=database"
  }
}
hcl
resource "hcloud_firewall" "db" {
  name = "${var.project}-db-firewall"

  # 仅允许私有网络访问PostgreSQL
  rule {
    description = "PostgreSQL"
    direction   = "in"
    protocol    = "tcp"
    port        = "5432"
    source_ips  = ["10.0.0.0/16"]  # 私有网络地址段
  }

  # 仅允许堡垒机访问SSH
  rule {
    description = "SSH from bastion"
    direction   = "in"
    protocol    = "tcp"
    port        = "22"
    source_ips  = ["10.0.1.1/32"]  # 堡垒机IP
  }

  apply_to {
    label_selector = "role=database"
  }
}

Floating IPs (High Availability)

浮动IP(高可用)

hcl
resource "hcloud_floating_ip" "app" {
  type          = "ipv4"
  name          = "${var.project}-vip"
  home_location = "fsn1"

  labels = {
    project = var.project
    purpose = "failover"
  }
}

resource "hcloud_floating_ip_assignment" "app" {
  floating_ip_id = hcloud_floating_ip.app.id
  server_id      = hcloud_server.app.id
}

output "floating_ip" {
  value = hcloud_floating_ip.app.ip_address
}
hcl
resource "hcloud_floating_ip" "app" {
  type          = "ipv4"
  name          = "${var.project}-vip"
  home_location = "fsn1"

  labels = {
    project = var.project
    purpose = "failover"
  }
}

resource "hcloud_floating_ip_assignment" "app" {
  floating_ip_id = hcloud_floating_ip.app.id
  server_id      = hcloud_server.app.id
}

output "floating_ip" {
  value = hcloud_floating_ip.app.ip_address
}

Load Balancers

负载均衡器

HTTP Load Balancer

HTTP负载均衡器

hcl
resource "hcloud_load_balancer" "web" {
  name               = "${var.project}-lb"
  load_balancer_type = "lb11"
  location           = "fsn1"

  labels = {
    project = var.project
  }
}

resource "hcloud_load_balancer_network" "web" {
  load_balancer_id = hcloud_load_balancer.web.id
  network_id       = hcloud_network.private.id
  ip               = "10.0.1.100"
}

resource "hcloud_load_balancer_service" "http" {
  load_balancer_id = hcloud_load_balancer.web.id
  protocol         = "http"
  listen_port      = 80
  destination_port = 8080

  health_check {
    protocol = "http"
    port     = 8080
    interval = 10
    timeout  = 5
    retries  = 3

    http {
      path         = "/health"
      status_codes = ["200"]
    }
  }
}

resource "hcloud_load_balancer_target" "web" {
  load_balancer_id = hcloud_load_balancer.web.id
  type             = "server"
  server_id        = hcloud_server.app.id
  use_private_ip   = true

  depends_on = [hcloud_load_balancer_network.web]
}
hcl
resource "hcloud_load_balancer" "web" {
  name               = "${var.project}-lb"
  load_balancer_type = "lb11"
  location           = "fsn1"

  labels = {
    project = var.project
  }
}

resource "hcloud_load_balancer_network" "web" {
  load_balancer_id = hcloud_load_balancer.web.id
  network_id       = hcloud_network.private.id
  ip               = "10.0.1.100"
}

resource "hcloud_load_balancer_service" "http" {
  load_balancer_id = hcloud_load_balancer.web.id
  protocol         = "http"
  listen_port      = 80
  destination_port = 8080

  health_check {
    protocol = "http"
    port     = 8080
    interval = 10
    timeout  = 5
    retries  = 3

    http {
      path         = "/health"
      status_codes = ["200"]
    }
  }
}

resource "hcloud_load_balancer_target" "web" {
  load_balancer_id = hcloud_load_balancer.web.id
  type             = "server"
  server_id        = hcloud_server.app.id
  use_private_ip   = true

  depends_on = [hcloud_load_balancer_network.web]
}

HTTPS Load Balancer with Certificate

带证书的HTTPS负载均衡器

hcl
resource "hcloud_managed_certificate" "web" {
  name         = "${var.project}-cert"
  domain_names = [var.domain, "www.${var.domain}"]

  labels = {
    project = var.project
  }
}

resource "hcloud_load_balancer_service" "https" {
  load_balancer_id = hcloud_load_balancer.web.id
  protocol         = "https"
  listen_port      = 443
  destination_port = 8080

  http {
    certificates = [hcloud_managed_certificate.web.id]
    redirect_http = true
  }

  health_check {
    protocol = "http"
    port     = 8080
    interval = 10
    timeout  = 5
  }
}
hcl
resource "hcloud_managed_certificate" "web" {
  name         = "${var.project}-cert"
  domain_names = [var.domain, "www.${var.domain}"]

  labels = {
    project = var.project
  }
}

resource "hcloud_load_balancer_service" "https" {
  load_balancer_id = hcloud_load_balancer.web.id
  protocol         = "https"
  listen_port      = 443
  destination_port = 8080

  http {
    certificates = [hcloud_managed_certificate.web.id]
    redirect_http = true
  }

  health_check {
    protocol = "http"
    port     = 8080
    interval = 10
    timeout  = 5
  }
}

Volumes (Persistent Storage)

存储卷(持久化存储)

hcl
resource "hcloud_volume" "data" {
  name      = "${var.project}-data"
  size      = 100  # GB
  location  = "fsn1"
  format    = "ext4"

  labels = {
    project = var.project
    purpose = "database"
  }
}

resource "hcloud_volume_attachment" "data" {
  volume_id = hcloud_volume.data.id
  server_id = hcloud_server.db.id
  automount = true
}
hcl
resource "hcloud_volume" "data" {
  name      = "${var.project}-data"
  size      = 100  # GB
  location  = "fsn1"
  format    = "ext4"

  labels = {
    project = var.project
    purpose = "database"
  }
}

resource "hcloud_volume_attachment" "data" {
  volume_id = hcloud_volume.data.id
  server_id = hcloud_server.db.id
  automount = true
}

SSH Keys

SSH密钥

hcl
resource "hcloud_ssh_key" "deploy" {
  name       = "${var.project}-deploy"
  public_key = file(var.ssh_public_key_path)

  labels = {
    project = var.project
    purpose = "deployment"
  }
}
See Ansible Integration for Hetzner+Ansible patterns, Kamal-ready playbooks, and provisioning scripts.
hcl
resource "hcloud_ssh_key" "deploy" {
  name       = "${var.project}-deploy"
  public_key = file(var.ssh_public_key_path)

  labels = {
    project = var.project
    purpose = "deployment"
  }
}
查看 Ansible集成 获取Hetzner+Ansible的配置模式、适配Kamal的剧本以及自动化部署脚本。

Additional Resources

更多资源

  • resources/best-practices.md - Labels, cost optimization, placement groups, snapshots
  • resources/object-storage.md - S3-compatible Object Storage with AWS provider configuration
  • resources/production-stack.md - Complete production setup with app servers, database, load balancer, firewalls, volumes, and networking
  • resources/best-practices.md - 标签规范、成本优化、放置组、快照
  • resources/object-storage.md - 兼容S3的对象存储及AWS提供商配置
  • resources/production-stack.md - 完整生产环境架构,包含应用服务器、数据库、负载均衡器、防火墙、存储卷及网络配置