From watzon-claude-code
Use when deploying, managing, or troubleshooting Hetzner Cloud infrastructure via hcloud CLI. Triggers: "hetzner cloud", "hcloud", "hetzner server", "create server on hetzner", "hetzner network", "hetzner firewall", "hetzner load balancer", "provision hetzner", "deploy to hetzner", "hetzner volume", "hetzner floating ip", "hetzner snapshot". Provides comprehensive workflows for server management, networking, storage, security, and production-ready automation patterns with the official Hetzner Cloud CLI.
npx claudepluginhub joshuarweaver/cascade-code-languages-misc-2 --plugin watzon-claude-codeThis skill uses the workspace's default tool permissions.
Comprehensive management of Hetzner Cloud infrastructure using the official `hcloud` CLI. Covers servers, networks, firewalls, load balancers, volumes, floating IPs, and automation workflows.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Comprehensive management of Hetzner Cloud infrastructure using the official hcloud CLI. Covers servers, networks, firewalls, load balancers, volumes, floating IPs, and automation workflows.
| Task | Command | Notes |
|---|---|---|
| Create Server | hcloud server create --name <name> --type <type> --image <image> | Add --ssh-key, --network, --firewall for production |
| List Servers | hcloud server list | Use --output json for scripting |
| Server Control | hcloud server [poweron|shutdown|reboot|reset] <name> | reset is hard reset |
| SSH Access | hcloud server ssh <name> | Direct SSH connection |
| Create Snapshot | hcloud server create-image <name> --type snapshot | For backups before changes |
| Create Network | hcloud network create --name <name> --ip-range <cidr> | Private networking |
| Create Firewall | hcloud firewall create --name <name> --rules-file <file> | JSON format for rules |
| Create Load Balancer | hcloud load-balancer create --name <name> --type <type> | Add services and targets after |
| Context Switch | hcloud context use <context> | Multi-project management |
| JSON Output | hcloud <command> --output json | Pipe to jq for parsing |
The hcloud CLI is organized into these main resource types:
| Category | Purpose | Key Commands |
|---|---|---|
| server | Virtual machines | create, list, delete, poweron, shutdown, ssh, create-image |
| network | Private networks | create, add-subnet, add-route, expose-routes-to-vswitch |
| firewall | Security rules | create, add-rule, apply-to-resource, replace-rules |
| load-balancer | Traffic distribution | create, add-service, add-target, change-algorithm |
| volume | Block storage | create, attach, detach, resize |
| floating-ip | Static IPs | create, assign, unassign, set-rdns |
| ssh-key | SSH key management | create, list, delete |
| placement-group | Server distribution | create spread, create anti-affinity |
| primary-ip | IP management | create, assign, unassign |
| certificate | SSL/TLS certs | create, list, delete |
| datacenter | View datacenters | list, describe |
| location | View locations | list, describe |
| server-type | View server types | list, describe |
| image | OS images | list, describe, delete |
| context | Multi-project auth | create, list, use, active, delete |
# macOS (Homebrew)
brew install hcloud
# Linux (snap)
sudo snap install hcloud
# Or download binary from GitHub releases
# https://github.com/hetznercloud/cli/releases
hcloud version
# Expected: hcloud v1.60.0 or later
# 1. Get API token from Hetzner Cloud Console
# https://console.hetzner.cloud → Project → Security → API Tokens
# Create Read & Write token (64 characters)
# 2. Create context (interactive)
hcloud context create my-project
# Paste token when prompted
# 3. Verify authentication
hcloud server list
# 4. Show active context
hcloud context active
# Create contexts for different projects
hcloud context create production
# Enter production token
hcloud context create staging
# Enter staging token
# List all contexts
hcloud context list
# Switch between contexts
hcloud context use production
hcloud server list # Lists production servers
hcloud context use staging
hcloud server list # Lists staging servers
# Show active context
hcloud context active
# Export token (no config file created)
export HCLOUD_TOKEN="your-64-character-api-token"
# Run commands
hcloud server list
# In CI/CD pipelines (GitHub Actions example)
- name: Deploy to Hetzner
env:
HCLOUD_TOKEN: ${{ secrets.HETZNER_TOKEN }}
run: |
hcloud server create --name ci-server --type cpx11 --image ubuntu-24.04
Default: ~/.config/hcloud/cli.toml
# Global settings
active_context = "production"
[[contexts]]
name = "production"
token = "your-64-char-token"
[[contexts]]
name = "staging"
token = "another-64-char-token"
# Minimal server creation
hcloud server create \
--name my-server \
--type cpx11 \
--image ubuntu-24.04 \
--location fsn1
# Server types (common):
# cpx11 - 2 vCPU, 2 GB RAM (shared)
# cpx21 - 3 vCPU, 4 GB RAM (shared)
# cpx31 - 4 vCPU, 8 GB RAM (shared)
# cpx41 - 8 vCPU, 16 GB RAM (shared)
# ccx13 - 2 vCPU, 8 GB RAM (dedicated)
# ccx23 - 4 vCPU, 16 GB RAM (dedicated)
# Locations:
# fsn1 - Falkenstein, Germany
# nbg1 - Nuremberg, Germany
# hel1 - Helsinki, Finland
# ash - Ashburn, USA
# hil - Hillsboro, USA
# Images:
# ubuntu-24.04, ubuntu-22.04
# debian-12, debian-11
# fedora-40, rocky-9, alma-9
# 1. Create SSH key first (if not exists)
hcloud ssh-key create \
--name deploy-key \
--public-key-from-file ~/.ssh/id_rsa.pub
# 2. Create network (for private networking)
hcloud network create --name app-network --ip-range 10.0.0.0/16
hcloud network add-subnet app-network \
--type cloud \
--network-zone eu-central \
--ip-range 10.0.1.0/24
# 3. Create firewall rules file
cat > firewall-rules.json <<'EOF'
{
"rules": [
{
"direction": "in",
"protocol": "tcp",
"port": "22",
"source_ips": ["0.0.0.0/0", "::/0"],
"description": "SSH"
},
{
"direction": "in",
"protocol": "tcp",
"port": "80",
"source_ips": ["0.0.0.0/0", "::/0"],
"description": "HTTP"
},
{
"direction": "in",
"protocol": "tcp",
"port": "443",
"source_ips": ["0.0.0.0/0", "::/0"],
"description": "HTTPS"
}
]
}
EOF
# 4. Create firewall
hcloud firewall create --name web-firewall --rules-file firewall-rules.json
# 5. Create server with all options
hcloud server create \
--name web-01 \
--type cpx21 \
--image ubuntu-24.04 \
--location fsn1 \
--ssh-key deploy-key \
--network app-network \
--firewall web-firewall \
--labels environment=production,service=web,team=platform \
--enable-backup \
--user-data-from-file cloud-init.yaml
# 6. Enable deletion protection
hcloud server enable-protection web-01 --delete
# 7. Get server details
hcloud server describe web-01
# Power operations
hcloud server poweron my-server # Start server
hcloud server shutdown my-server # Graceful shutdown (ACPI)
hcloud server reboot my-server # Graceful reboot
hcloud server reset my-server # Hard reset (force)
# Check status
hcloud server describe my-server --output json | jq -r '.status'
# Enable/disable rescue mode
hcloud server enable-rescue my-server --ssh-key deploy-key
hcloud server reboot my-server # Boot into rescue
# ... do maintenance ...
hcloud server disable-rescue my-server
hcloud server reboot my-server # Boot normally
# SSH access
hcloud server ssh my-server
# SSH with custom user
hcloud server ssh my-server --user root
# Get server IP
hcloud server describe my-server --output json | jq -r '.public_net.ipv4.ip'
# Create snapshot (manual backup)
hcloud server create-image my-server \
--type snapshot \
--description "Before upgrade to v2.0" \
--labels version=1.9,backup_type=manual
# Enable automatic backups (daily, 7-day retention)
hcloud server enable-backup my-server
# Disable backups
hcloud server disable-backup my-server
# List snapshots
hcloud image list --type snapshot
# List backups
hcloud image list --type backup
# Delete old snapshot
hcloud image delete snapshot-123456
# Restore from snapshot (create new server from image)
hcloud server create \
--name my-server-restored \
--image snapshot-123456 \
--type cpx21 \
--location fsn1
# List available server types
hcloud server-type list
# Power off server (required for resize)
hcloud server shutdown my-server
# Wait for shutdown
while [ "$(hcloud server describe my-server -o json | jq -r '.status')" != "off" ]; do
echo "Waiting for shutdown..."
sleep 2
done
# Change server type (upgrade/downgrade)
hcloud server change-type my-server --upgrade-disk cpx31
# Power on
hcloud server poweron my-server
# Note: --upgrade-disk increases disk size permanently (cannot shrink)
# Without --upgrade-disk, disk size stays the same
# 1. Create private network
hcloud network create \
--name app-network \
--ip-range 10.0.0.0/16 \
--labels environment=production
# 2. Add cloud subnet (for Hetzner Cloud servers)
hcloud network add-subnet app-network \
--type cloud \
--network-zone eu-central \
--ip-range 10.0.1.0/24
# 3. Add another subnet for different services
hcloud network add-subnet app-network \
--type cloud \
--network-zone eu-central \
--ip-range 10.0.2.0/24
# 4. Add route (for external gateway)
hcloud network add-route app-network \
--destination 192.168.0.0/16 \
--gateway 10.0.1.1
# 5. Attach existing server to network
hcloud server attach-to-network my-server \
--network app-network \
--ip 10.0.1.10
# 6. Detach server from network
hcloud server detach-from-network my-server --network app-network
# 7. List network details
hcloud network describe app-network
# 1. Create firewall with rules file
cat > app-firewall.json <<'EOF'
{
"rules": [
{
"direction": "in",
"protocol": "tcp",
"port": "22",
"source_ips": ["YOUR_IP/32"],
"description": "SSH from office"
},
{
"direction": "in",
"protocol": "tcp",
"port": "443",
"source_ips": ["0.0.0.0/0", "::/0"],
"description": "HTTPS"
},
{
"direction": "in",
"protocol": "icmp",
"source_ips": ["0.0.0.0/0", "::/0"],
"description": "Ping"
}
]
}
EOF
hcloud firewall create --name app-firewall --rules-file app-firewall.json
# 2. Apply firewall to server
hcloud firewall apply-to-resource app-firewall \
--type server \
--server web-01
# 3. Apply firewall to all servers with label
hcloud firewall apply-to-resource app-firewall \
--type label \
--label environment=production
# 4. Add individual rule
hcloud firewall add-rule app-firewall \
--direction in \
--protocol tcp \
--port 8080 \
--source-ips 10.0.0.0/16 \
--description "Internal API"
# 5. Remove rule (by index, get from describe)
hcloud firewall describe app-firewall
hcloud firewall delete-rule app-firewall --index 2
# 6. Replace all rules
hcloud firewall replace-rules app-firewall --rules-file new-rules.json
# 7. Remove firewall from resource
hcloud firewall remove-from-resource app-firewall \
--type server \
--server web-01
# 8. List firewalls
hcloud firewall list
# 1. Create load balancer
hcloud load-balancer create \
--name app-lb \
--type lb11 \
--location fsn1 \
--labels service=frontend
# Load balancer types:
# lb11 - Up to 20,000 connections
# lb21 - Up to 40,000 connections
# lb31 - Up to 60,000 connections
# 2. Add HTTP service
hcloud load-balancer add-service app-lb \
--protocol http \
--listen-port 80 \
--destination-port 8080 \
--http-sticky-sessions
# 3. Add HTTPS service with certificate
hcloud certificate create \
--name app-cert \
--type managed \
--domain example.com \
--domain www.example.com
hcloud load-balancer add-service app-lb \
--protocol https \
--listen-port 443 \
--destination-port 8080 \
--http-certificates app-cert \
--http-sticky-sessions \
--http-redirect-http
# 4. Add health check
hcloud load-balancer update-service app-lb \
--listen-port 80 \
--health-check-protocol http \
--health-check-port 8080 \
--health-check-interval 15 \
--health-check-timeout 10 \
--health-check-retries 3 \
--health-check-http-path /health
# 5. Add server targets
hcloud load-balancer add-target app-lb --type server --server web-01
hcloud load-balancer add-target app-lb --type server --server web-02
# 6. Or add target by label (auto-includes all matching servers)
hcloud load-balancer add-target app-lb \
--type label \
--label service=web
# 7. Change algorithm
hcloud load-balancer change-algorithm app-lb --type round_robin
# Options: round_robin, least_connections
# 8. Get metrics
hcloud load-balancer metrics app-lb --type open_connections
hcloud load-balancer metrics app-lb --type requests_per_second
# 9. Enable deletion protection
hcloud load-balancer enable-protection app-lb --delete
# 1. Create volume
hcloud volume create \
--name data-vol \
--size 50 \
--location fsn1 \
--format ext4 \
--labels service=database
# 2. Attach volume to server
hcloud volume attach data-vol --server db-01
# 3. Mount volume (on server)
# SSH into server and mount
hcloud server ssh db-01
sudo mkdir -p /mnt/data
sudo mount /dev/disk/by-id/scsi-0HC_Volume_* /mnt/data
# 4. Detach volume
hcloud volume detach data-vol
# 5. Resize volume (server must be off or volume detached)
hcloud volume resize data-vol --size 100
# 6. Enable protection
hcloud volume enable-protection data-vol --delete
# 7. List volumes
hcloud volume list
# 8. Delete volume
hcloud volume delete data-vol
# 1. Create floating IP
hcloud floating-ip create \
--type ipv4 \
--home-location fsn1 \
--description "Primary web IP" \
--labels service=web
# 2. Create IPv6
hcloud floating-ip create \
--type ipv6 \
--home-location fsn1
# 3. Assign to server
hcloud floating-ip assign 1.2.3.4 --server web-01
# 4. Configure on server (manual step)
# SSH into server and add IP to network interface
hcloud server ssh web-01
sudo ip addr add 1.2.3.4/32 dev eth0
# 5. Set reverse DNS
hcloud floating-ip set-rdns 1.2.3.4 --hostname web.example.com
# 6. Unassign from server
hcloud floating-ip unassign 1.2.3.4
# 7. Enable protection
hcloud floating-ip enable-protection 1.2.3.4 --delete
# 8. List floating IPs
hcloud floating-ip list
#!/bin/bash
set -euo pipefail
# Configuration
PROJECT="my-app"
LOCATION="fsn1"
NETWORK_CIDR="10.0.0.0/16"
SUBNET_CIDR="10.0.1.0/24"
# 1. Create private network
echo "Creating network..."
hcloud network create --name "${PROJECT}-network" --ip-range "$NETWORK_CIDR"
hcloud network add-subnet "${PROJECT}-network" \
--type cloud \
--network-zone eu-central \
--ip-range "$SUBNET_CIDR"
# 2. Create firewall
echo "Creating firewall..."
cat > firewall.json <<'EOF'
{
"rules": [
{"direction": "in", "protocol": "tcp", "port": "22", "source_ips": ["0.0.0.0/0", "::/0"], "description": "SSH"},
{"direction": "in", "protocol": "tcp", "port": "80", "source_ips": ["0.0.0.0/0", "::/0"], "description": "HTTP"},
{"direction": "in", "protocol": "tcp", "port": "443", "source_ips": ["0.0.0.0/0", "::/0"], "description": "HTTPS"}
]
}
EOF
hcloud firewall create --name "${PROJECT}-firewall" --rules-file firewall.json
# 3. Create SSH key
echo "Creating SSH key..."
hcloud ssh-key create --name "${PROJECT}-key" --public-key-from-file ~/.ssh/id_rsa.pub || true
# 4. Create web servers
echo "Creating web servers..."
for i in 1 2 3; do
hcloud server create \
--name "${PROJECT}-web-${i}" \
--type cpx21 \
--image ubuntu-24.04 \
--location "$LOCATION" \
--network "${PROJECT}-network" \
--firewall "${PROJECT}-firewall" \
--ssh-key "${PROJECT}-key" \
--labels "app=${PROJECT},role=web,index=${i}" \
--enable-backup &
done
wait
# 5. Wait for servers to be ready
echo "Waiting for servers..."
for i in 1 2 3; do
while [ "$(hcloud server describe "${PROJECT}-web-${i}" -o json | jq -r '.status')" != "running" ]; do
sleep 2
done
echo "${PROJECT}-web-${i} is running"
done
# 6. Create load balancer
echo "Creating load balancer..."
hcloud load-balancer create \
--name "${PROJECT}-lb" \
--type lb11 \
--location "$LOCATION"
# 7. Add HTTP service
hcloud load-balancer add-service "${PROJECT}-lb" \
--protocol http \
--listen-port 80 \
--destination-port 80 \
--health-check-protocol http \
--health-check-port 80 \
--health-check-http-path /health
# 8. Add targets by label (automatically includes all web servers)
hcloud load-balancer add-target "${PROJECT}-lb" \
--type label \
--label "role=web"
# 9. Output summary
echo ""
echo "Infrastructure created:"
echo "======================"
hcloud server list --output columns=name,ipv4,status | grep "${PROJECT}"
echo ""
LB_IP=$(hcloud load-balancer describe "${PROJECT}-lb" -o json | jq -r '.public_net.ipv4.ip')
echo "Load Balancer IP: $LB_IP"
echo ""
echo "Test: curl http://$LB_IP"
#!/bin/bash
# Monitor server health and send alerts
# Get all production servers
SERVERS=$(hcloud server list -o json | jq -r '.[] | select(.labels.environment == "production") | .name')
for server in $SERVERS; do
STATUS=$(hcloud server describe "$server" -o json | jq -r '.status')
if [ "$STATUS" != "running" ]; then
echo "⚠️ $server is $STATUS"
# Send alert (example: Slack webhook)
# curl -X POST -H 'Content-type: application/json' \
# --data "{\"text\":\"Server $server is $STATUS\"}" \
# "$SLACK_WEBHOOK_URL"
else
echo "✅ $server is running"
fi
# Check server metrics (CPU)
CPU=$(hcloud server metrics "$server" --type cpu --start=$(date -u -d '5 minutes ago' +%s) -o json | jq -r '.time_series.cpu.values[-1][1]')
echo " CPU: ${CPU}%"
if (( $(echo "$CPU > 90" | bc -l) )); then
echo " ⚠️ High CPU usage!"
fi
done
#!/bin/bash
# Clean up temporary/stopped resources
# Delete stopped servers with 'temp' label
echo "Cleaning up temporary servers..."
hcloud server list -o json | jq -r '.[] | select(.labels.temp == "true") | select(.status == "off") | .name' | while read server; do
echo "Deleting $server..."
hcloud server delete "$server"
done
# Delete unattached volumes older than 7 days
echo "Cleaning up unattached volumes..."
hcloud volume list -o json | jq -r '.[] | select(.server == null) | "\(.id) \(.created)"' | while read id created; do
AGE=$(( ($(date +%s) - $(date -d "$created" +%s)) / 86400 ))
if [ $AGE -gt 7 ]; then
echo "Deleting volume $id (${AGE} days old)..."
hcloud volume delete "$id"
fi
done
# Delete old snapshots (keep last 3)
echo "Cleaning up old snapshots..."
hcloud image list --type snapshot -o json | \
jq -r 'sort_by(.created) | reverse | .[3:] | .[] | .id' | \
while read image_id; do
echo "Deleting snapshot $image_id..."
hcloud image delete "$image_id"
done
# Get IPs of all running web servers
hcloud server list -o json | \
jq -r '.[] | select(.labels.role == "web") | select(.status == "running") | "\(.name): \(.public_net.ipv4.ip)"'
# Generate Ansible inventory
echo "[web_servers]"
hcloud server list -o json | \
jq -r '.[] | select(.labels.role == "web") | "\(.public_net.ipv4.ip) hostname=\(.name)"'
# Shutdown all dev servers
hcloud server list -o json | \
jq -r '.[] | select(.labels.environment == "dev") | .name' | \
xargs -I {} hcloud server shutdown {}
# Apply firewall to all servers with label
FIREWALL="prod-firewall"
hcloud server list -o json | \
jq -r '.[] | select(.labels.environment == "production") | .name' | \
while read server; do
hcloud firewall apply-to-resource "$FIREWALL" --type server --server "$server"
done
# Use consistent labeling scheme
--labels environment=production,service=api,team=platform,version=v2.0
# Label-based operations
hcloud server list --selector environment=production
hcloud server list --selector service=web
# Use descriptive names
--name prod-web-01 # Good
--name server-123 # Bad
# Enable protection on critical resources
hcloud server enable-protection prod-db-01 --delete --rebuild
hcloud volume enable-protection prod-data --delete
# 1. Restrict SSH to specific IPs
{
"rules": [
{
"direction": "in",
"protocol": "tcp",
"port": "22",
"source_ips": ["YOUR_OFFICE_IP/32"],
"description": "SSH from office only"
}
]
}
# 2. Use private networks for inter-server communication
# Don't expose databases/APIs on public internet
# 3. Enable backups on critical servers
hcloud server enable-backup prod-db-01
# 4. Use SSH keys, never passwords
hcloud ssh-key create --name deploy-key --public-key-from-file ~/.ssh/id_rsa.pub
# 5. Regular security updates (cloud-init example)
#cloud-config
package_upgrade: true
packages:
- unattended-upgrades
# 1. Use appropriate server types (don't over-provision)
hcloud server-type list # Review pricing
# 2. Shutdown dev/staging servers when not in use
hcloud server shutdown dev-*
# 3. Use snapshots instead of keeping servers running
hcloud server create-image dev-server --type snapshot --description "Dev environment"
hcloud server delete dev-server
# Restore when needed
# 4. Clean up old snapshots/backups
hcloud image list --type snapshot
hcloud image delete old-snapshot-id
# 5. Use placement groups to reduce costs
# Spread: Distributes across physical hosts (HA)
# Max 10 servers per spread group
hcloud placement-group create spread --name ha-group
# 1. Use multiple locations
hcloud server create --name web-fsn1 --location fsn1
hcloud server create --name web-nbg1 --location nbg1
# 2. Use load balancers with health checks
hcloud load-balancer add-service app-lb \
--health-check-protocol http \
--health-check-retries 3 \
--health-check-interval 15
# 3. Use floating IPs for failover
# Assign floating IP to primary
hcloud floating-ip assign 1.2.3.4 --server primary
# On failure, reassign to secondary
hcloud floating-ip assign 1.2.3.4 --server secondary
# 4. Use placement groups for distribution
hcloud placement-group create spread --name web-spread
hcloud server create --placement-group web-spread
# 5. Enable backups
hcloud server enable-backup prod-server
# Check active context
hcloud context active
# List all contexts
hcloud context list
# Verify token works
hcloud server list
# If error: "unable to authenticate", token is invalid
# Re-authenticate
hcloud context delete my-project
hcloud context create my-project
# Enter new token
# Check config file
cat ~/.config/hcloud/cli.toml
# Check location capacity
hcloud location list
hcloud server-type list
# Check if server type available in location
hcloud datacenter list
# Common errors:
# "insufficient resources" - Try different location
# "placement_group_limit_reached" - Max 10 servers per spread group
# "limit_reached" - Check project limits in console
# Verbose output for debugging
hcloud server create --name test --type cpx11 --image ubuntu-24.04 --debug
# Check firewall rules
hcloud firewall describe my-firewall
# Check server network attachment
hcloud server describe my-server -o json | jq '.private_net'
# Check network routes
hcloud network describe my-network
# Test connectivity (from server)
hcloud server ssh my-server
ping -c 3 10.0.1.10 # Test private network
# Check if firewall is applied
hcloud firewall list
hcloud server describe my-server -o json | jq '.firewall_ids'
# Check server metrics
hcloud server metrics my-server --type cpu
hcloud server metrics my-server --type network
hcloud server metrics my-server --type disk
# Check load balancer metrics
hcloud load-balancer metrics my-lb --type open_connections
hcloud load-balancer metrics my-lb --type requests_per_second
# Review server type specs
hcloud server-type describe cpx21
# Consider upgrading
hcloud server shutdown my-server
hcloud server change-type my-server --upgrade-disk cpx31
hcloud server poweron my-server
| Error | Cause | Solution |
|---|---|---|
unable to authenticate | Invalid/expired token | Re-create context with valid token |
server not found | Wrong context or server name | Check hcloud context active |
insufficient resources | Location at capacity | Try different location |
limit_reached | Project limit exceeded | Contact support or upgrade |
protected | Resource has deletion protection | Disable protection first |
server_already_attached | Already in network | Detach first, then re-attach |
ip_not_available | IP already assigned | Unassign from other resource |
# JSON output (recommended for scripts)
hcloud server list --output json
# Parse with jq
hcloud server list -o json | jq '.[] | {name: .name, ip: .public_net.ipv4.ip}'
# YAML output
hcloud server describe my-server --output yaml
# Custom Go template
hcloud server list --output format='{{range .}}{{.Name}}: {{.PublicNet.IPv4.IP}}{{"\n"}}{{end}}'
# Table without header (for parsing)
hcloud server list --output noheader
# Select specific columns
hcloud server list --output columns=name,ipv4,status
# Combine options
hcloud server list -o noheader -o columns=name,ipv4 | while read name ip; do
echo "Server: $name -> $ip"
done
# Create spread group (HA - different physical hosts)
hcloud placement-group create spread --name ha-web
# Create servers in group
hcloud server create --name web-01 --placement-group ha-web --type cpx21
hcloud server create --name web-02 --placement-group ha-web --type cpx21
# Max 10 servers per spread group
# Use multiple groups for larger deployments
# Create primary IPv4 (replaces default server IP)
hcloud primary-ip create \
--type ipv4 \
--assignee-type server \
--datacenter fsn1-dc14 \
--name web-primary-ip
# Assign to server during creation
hcloud server create \
--name my-server \
--type cpx11 \
--image ubuntu-24.04 \
--primary-ipv4 web-primary-ip
# Benefit: Keep IP when recreating server
# Create cloud-init file
cat > cloud-init.yaml <<'EOF'
#cloud-config
package_upgrade: true
packages:
- docker.io
- git
- curl
write_files:
- path: /etc/docker/daemon.json
content: |
{"log-driver": "json-file", "log-opts": {"max-size": "10m"}}
runcmd:
- systemctl enable docker
- systemctl start docker
- usermod -aG docker ubuntu
EOF
# Create server with user data
hcloud server create \
--name docker-server \
--type cpx21 \
--image ubuntu-24.04 \
--user-data-from-file cloud-init.yaml
# Create DNS zone
hcloud zone create --name example.com
# Add records
hcloud zone add-record example.com --type A --name www --value 1.2.3.4
hcloud zone add-record example.com --type AAAA --name www --value 2001:db8::1
# List zones
hcloud zone list
# Export zone
hcloud zone export example.com
This skill is based on hcloud CLI v1.60.0 (January 2026).