Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit a978621

Browse files
committed
refactor: [#28] complete Hetzner token management simplification
- Centralize all Hetzner tokens in provider configuration files - Standardize token names (HETZNER_API_TOKEN, HETZNER_DNS_API_TOKEN) - Remove ~/.config/hetzner/ directory support for simplified workflow - Update provider scripts to use centralized token management - Update DNS management script for new token structure - Update all documentation and setup guides - Add comprehensive refactoring documentation - Remove hetzner.env from git tracking (contains secrets) Tested: E2E tests pass (2m 54s) - fully validated refactoring Files modified: - infrastructure/config/templates/providers/hetzner.env.tpl (standardized template) - infrastructure/terraform/providers/hetzner/provider.sh (removed ~/.config/hetzner support) - scripts/manage-hetzner-dns.sh (updated to use provider config) - docs/guides/providers/hetzner/* (updated setup guides) - docs/refactoring/hetzner-token-simplification.md (new refactoring documentation) Files untracked: - infrastructure/config/providers/hetzner.env (contains secrets, now properly ignored)
1 parent e8fa04c commit a978621

File tree

8 files changed

+322
-188
lines changed

8 files changed

+322
-188
lines changed

docs/guides/providers/hetzner/README.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,17 @@ The Torrust Tracker Demo uses a comprehensive Hetzner setup:
7171
### 2. API Token Setup
7272

7373
```bash
74-
# Create secure token storage
75-
mkdir -p ~/.config/hetzner
76-
chmod 700 ~/.config/hetzner
74+
# Copy provider configuration template
75+
cp infrastructure/config/templates/providers/hetzner.env.tpl infrastructure/config/providers/hetzner.env
7776

78-
# Store Hetzner Cloud API token
79-
echo "YOUR_CLOUD_TOKEN" > ~/.config/hetzner/cloud_api_token
80-
chmod 600 ~/.config/hetzner/cloud_api_token
77+
# Edit the configuration file to add your tokens
78+
# Add these lines to infrastructure/config/providers/hetzner.env:
79+
# HETZNER_API_TOKEN=your_64_character_cloud_api_token_here
80+
# HETZNER_DNS_API_TOKEN=your_dns_api_token_here
8181

82-
# Store Hetzner DNS API token
83-
echo "YOUR_DNS_TOKEN" > ~/.config/hetzner/dns_api_token
84-
chmod 600 ~/.config/hetzner/dns_api_token
82+
# Get your tokens from:
83+
# Cloud API: https://console.hetzner.cloud/ → Project → Security → API Tokens
84+
# DNS API: https://dns.hetzner.com/ → API Tokens
8585
```
8686

8787
### 3. Domain Configuration
@@ -169,7 +169,7 @@ ENVIRONMENT=production-hetzner PROVIDER=hetzner make infra-destroy
169169

170170
**Infrastructure Problems:**
171171

172-
- **API Token Issues**: Verify tokens are stored correctly in `~/.config/hetzner/`
172+
- **API Token Issues**: Verify tokens are configured correctly in `infrastructure/config/providers/hetzner.env`
173173
- **Network Connectivity**: Check Hetzner status page for outages
174174
- **Resource Limits**: Verify account limits in Hetzner console
175175

@@ -183,11 +183,11 @@ ENVIRONMENT=production-hetzner PROVIDER=hetzner make infra-destroy
183183

184184
```bash
185185
# Test Hetzner Cloud API
186-
curl -H "Authorization: Bearer $(cat ~/.config/hetzner/cloud_api_token)" \
186+
curl -H "Authorization: Bearer $HETZNER_API_TOKEN"
187187
"https://api.hetzner.cloud/v1/servers"
188188

189189
# Test Hetzner DNS API
190-
curl -H "Auth-API-Token: $(cat ~/.config/hetzner/dns_api_token)" \
190+
curl -H "Auth-API-Token: $HETZNER_DNS_API_TOKEN"
191191
"https://dns.hetzner.com/api/v1/zones"
192192

193193
# Check DNS propagation
@@ -204,8 +204,9 @@ Hetzner configuration integrates with the main project's twelve-factor approach:
204204
```bash
205205
# infrastructure/config/environments/production-hetzner.env
206206
PROVIDER=hetzner
207-
HETZNER_CLOUD_TOKEN_FILE=~/.config/hetzner/cloud_api_token
208-
HETZNER_DNS_TOKEN_FILE=~/.config/hetzner/dns_api_token
207+
# Token file paths (for reference)
208+
HETZNER_API_TOKEN_CONFIG=infrastructure/config/providers/hetzner.env
209+
HETZNER_DNS_TOKEN_CONFIG=infrastructure/config/providers/hetzner.env
209210
DOMAIN_NAME=your-domain.com
210211
TRACKER_SUBDOMAIN=tracker.your-domain.com
211212
GRAFANA_SUBDOMAIN=grafana.your-domain.com

docs/guides/providers/hetzner/hetzner-cloud-setup-guide.md

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,28 @@ This guide explains how to set up and use the Hetzner Cloud provider with the To
2828
For enhanced security, store your Hetzner Cloud API token using secure file storage
2929
instead of environment variables:
3030

31-
### Option 1: Secure Storage (Recommended)
31+
### Provider Configuration Setup
3232

3333
```bash
34-
# Create secure storage directory
35-
mkdir -p ~/.config/hetzner
36-
chmod 700 ~/.config/hetzner
34+
# Copy provider configuration template
35+
cp infrastructure/config/templates/providers/hetzner.env.tpl infrastructure/config/providers/hetzner.env
3736

38-
# Store the Hetzner Cloud API token (replace YOUR_TOKEN_HERE with actual token)
39-
echo "YOUR_TOKEN_HERE" > ~/.config/hetzner/cloud_api_token
40-
chmod 600 ~/.config/hetzner/cloud_api_token
37+
# Edit the configuration file to add your Hetzner Cloud API token
38+
# Replace REPLACE_WITH_YOUR_HETZNER_API_TOKEN with your actual 64-character token
39+
# HETZNER_API_TOKEN=your_64_character_token_here
4140

42-
# Verify storage
43-
ls -la ~/.config/hetzner/
44-
# Should show: -rw------- 1 user user 65 date time cloud_api_token
41+
# Verify configuration
42+
grep HETZNER_API_TOKEN infrastructure/config/providers/hetzner.env
4543
```
4644

47-
### Test Token Storage
45+
### Test Token Configuration
4846

4947
```bash
50-
# Test that token can be loaded from storage
51-
CLOUD_TOKEN=$(cat ~/.config/hetzner/cloud_api_token)
48+
# Source the provider configuration
49+
source infrastructure/config/providers/hetzner.env
50+
51+
# Test that token is loaded correctly
52+
CLOUD_TOKEN="$HETZNER_API_TOKEN"
5253
echo "Token length: ${#CLOUD_TOKEN} characters"
5354
# Should show: Token length: 64 characters
5455

@@ -63,12 +64,12 @@ curl -H "Authorization: Bearer $CLOUD_TOKEN" \
6364
If you prefer environment variables, you can still use the traditional approach:
6465

6566
```bash
66-
export HETZNER_TOKEN=your_64_character_token_here
67+
export HETZNER_API_TOKEN=your_64_character_token_here
6768
```
6869

69-
> **Note**: The infrastructure scripts will automatically detect tokens from secure
70-
> storage first, then fall back to environment variables. Secure storage is
71-
> recommended for production use.
70+
> **Note**: The infrastructure scripts automatically load the Cloud API token
71+
> from `infrastructure/config/providers/hetzner.env`. You no longer need to set the
72+
> `HETZNER_API_TOKEN` environment variable if using provider configuration.
7273
7374
## Step 3: Configure Provider
7475

@@ -88,7 +89,7 @@ export HETZNER_TOKEN=your_64_character_token_here
8889

8990
```bash
9091
# Required: Your Hetzner API token
91-
HETZNER_TOKEN=your_64_character_token_here
92+
HETZNER_API_TOKEN=your_64_character_token_here
9293

9394
# Optional: Customize server settings
9495
HETZNER_SERVER_TYPE=cx31 # 2 vCPU, 8GB RAM, 80GB SSD
@@ -181,13 +182,13 @@ Hetzner Cloud service limitation makes manual volume attachment the only reliabl
181182

182183
```bash
183184
# Create a 20GB volume for persistent data
184-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud volume create \
185+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud volume create \
185186
--name torrust-data \
186187
--size 20 \
187188
--location fsn1
188189

189190
# Attach volume to server
190-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud volume attach \
191+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud volume attach \
191192
torrust-data torrust-tracker-prod
192193
```
193194

@@ -406,7 +407,7 @@ by Hetzner. Use `hcloud server-type list` for current availability.
406407
export PATH=$PATH:$(go env GOPATH)/bin
407408

408409
# List current server types
409-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud server-type list
410+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud server-type list
410411
```
411412

412413
2. Update your configuration with a valid server type:
@@ -428,7 +429,7 @@ by Hetzner. Use `hcloud server-type list` for current availability.
428429
2. Verify token has Read & Write permissions
429430
3. Check token is correctly set in both:
430431
- `infrastructure/config/providers/hetzner.env`
431-
- Environment variable: `export HETZNER_TOKEN=your_token_here`
432+
- Environment variable: `export HETZNER_API_TOKEN=your_token_here`
432433

433434
#### 3. Provider Configuration Variable Collision
434435

@@ -448,7 +449,7 @@ in provider scripts.
448449
1. Check current locations:
449450

450451
```bash
451-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud location list
452+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud location list
452453
```
453454

454455
2. Try different locations:
@@ -688,10 +689,10 @@ This limitation validates our architectural decision to make volume setup manual
688689

689690
```bash
690691
# Check current server types and availability
691-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud server-type list
692+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud server-type list
692693
693694
# Check available locations
694-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud location list
695+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud location list
695696
696697
# Validate configuration without applying
697698
make infra-plan ENVIRONMENT=production-hetzner PROVIDER=hetzner
@@ -703,8 +704,8 @@ make infra-status ENVIRONMENT=production-hetzner PROVIDER=hetzner
703704
make vm-ssh ENVIRONMENT=production-hetzner
704705
705706
# Check server details (after deployment)
706-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud server list
707-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud server describe torrust-tracker-prod
707+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud server list
708+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud server describe torrust-tracker-prod
708709
```
709710

710711
### Real-Time Information Commands
@@ -713,13 +714,13 @@ Always verify current Hetzner Cloud offerings before deployment:
713714

714715
```bash
715716
# Get current server types with pricing
716-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud server-type list
717+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud server-type list
717718
718719
# Get current datacenter locations
719-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud location list
720+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud location list
720721
721722
# Check image availability
722-
HCLOUD_TOKEN="$HETZNER_TOKEN" hcloud image list --type=system | grep ubuntu
723+
HCLOUD_TOKEN="$HETZNER_API_TOKEN" hcloud image list --type=system | grep ubuntu
723724
```
724725

725726
## Docker Compose Commands on Deployed Server

docs/guides/providers/hetzner/hetzner-dns-setup-guide.md

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,20 @@ This setup provides:
6464
Store the token securely on your system:
6565

6666
```bash
67-
# Create secure storage for API token
68-
mkdir -p ~/.config/hetzner
69-
chmod 700 ~/.config/hetzner
67+
# Configure DNS API token in provider configuration
68+
# Edit infrastructure/config/providers/hetzner.env and add:
69+
# HETZNER_DNS_API_TOKEN=your_dns_api_token_here
7070

71-
# Store the token (replace YOUR_TOKEN_HERE with actual token)
72-
echo "YOUR_TOKEN_HERE" > ~/.config/hetzner/dns_api_token
73-
chmod 600 ~/.config/hetzner/dns_api_token
74-
75-
# Verify storage
76-
ls -la ~/.config/hetzner/
71+
# Verify configuration
72+
grep HETZNER_DNS_API_TOKEN infrastructure/config/providers/hetzner.env
7773
```
7874

7975
### 1.4 Test API Access
8076

8177
```bash
82-
# Load token from secure storage
83-
DNS_TOKEN=$(cat ~/.config/hetzner/dns_api_token)
78+
# Load token from provider configuration
79+
source infrastructure/config/providers/hetzner.env
80+
DNS_TOKEN="$HETZNER_DNS_API_TOKEN"
8481

8582
# Test API access
8683
curl -H "Auth-API-Token: $DNS_TOKEN" \
@@ -117,22 +114,21 @@ stored using the same secure method.
117114
Store the Hetzner Cloud API token alongside the DNS token:
118115

119116
```bash
120-
# Store the Hetzner Cloud API token (replace YOUR_CLOUD_TOKEN_HERE with actual token)
121-
echo "YOUR_CLOUD_TOKEN_HERE" > ~/.config/hetzner/cloud_api_token
122-
chmod 600 ~/.config/hetzner/cloud_api_token
123-
124-
# Verify both tokens are stored securely
125-
ls -la ~/.config/hetzner/
126-
# Should show:
127-
# -rw------- 1 user user 65 date time cloud_api_token
128-
# -rw------- 1 user user 65 date time dns_api_token
117+
# Configure Hetzner Cloud API token in provider configuration
118+
# Edit infrastructure/config/providers/hetzner.env and ensure you have:
119+
# HETZNER_API_TOKEN=your_64_character_cloud_api_token_here
120+
# HETZNER_DNS_API_TOKEN=your_dns_api_token_here
121+
122+
# Verify both tokens are configured
123+
grep "HETZNER.*_TOKEN" infrastructure/config/providers/hetzner.env
129124
```
130125

131126
### 1.5.3 Test Cloud API Access
132127

133128
```bash
134-
# Load token from secure storage
135-
CLOUD_TOKEN=$(cat ~/.config/hetzner/cloud_api_token)
129+
# Load token from provider configuration
130+
source infrastructure/config/providers/hetzner.env
131+
CLOUD_TOKEN="$HETZNER_API_TOKEN"
136132

137133
# Test API access
138134
curl -H "Authorization: Bearer $CLOUD_TOKEN" \
@@ -141,17 +137,18 @@ curl -H "Authorization: Bearer $CLOUD_TOKEN" \
141137
# Expected output: {"servers": []} (empty array for new accounts)
142138
```
143139

144-
> **Note**: The infrastructure scripts will automatically detect and use the token
145-
> from `~/.config/hetzner/cloud_api_token`. You no longer need to set the
146-
> `HETZNER_TOKEN` environment variable if using secure storage.
140+
> **Note**: The infrastructure scripts automatically load tokens
141+
> from `infrastructure/config/providers/hetzner.env`. You no longer need to set
142+
> environment variables separately if using provider configuration.
147143
148144
## 🌐 Step 2: Create DNS Zone
149145

150146
### 2.1 Create Zone for Your Domain
151147

152148
```bash
153149
# Load API token
154-
DNS_TOKEN=$(cat ~/.config/hetzner/dns_api_token)
150+
source infrastructure/config/providers/hetzner.env
151+
DNS_TOKEN="$HETZNER_DNS_API_TOKEN"
155152

156153
# Create DNS zone for torrust-demo.dev
157154
curl -X POST "https://dns.hetzner.com/api/v1/zones" \
@@ -227,7 +224,8 @@ SERVER_IP="138.199.166.49" # Replace with your actual IP
227224

228225
```bash
229226
# Load API configuration
230-
DNS_TOKEN=$(cat ~/.config/hetzner/dns_api_token)
227+
source infrastructure/config/providers/hetzner.env
228+
DNS_TOKEN="$HETZNER_DNS_API_TOKEN"
231229
ZONE_ID="aBcDeFgHiJkLmNoPqRsTuVwXyZ" # Replace with your zone ID
232230
SERVER_IP="138.199.166.49" # Replace with your server IP
233231

@@ -365,7 +363,8 @@ curl -k -I https://grafana.torrust-demo.dev
365363
### View All Zones
366364

367365
```bash
368-
DNS_TOKEN=$(cat ~/.config/hetzner/dns_api_token)
366+
source infrastructure/config/providers/hetzner.env
367+
DNS_TOKEN="$HETZNER_DNS_API_TOKEN"
369368
curl -H "Auth-API-Token: $DNS_TOKEN" \
370369
"https://dns.hetzner.com/api/v1/zones" | jq
371370
```
@@ -443,7 +442,8 @@ cat > scripts/manage-dns.sh << 'EOF'
443442
set -euo pipefail
444443
445444
# Configuration
446-
DNS_TOKEN=$(cat ~/.config/hetzner/dns_api_token)
445+
source infrastructure/config/providers/hetzner.env
446+
DNS_TOKEN="$HETZNER_DNS_API_TOKEN"
447447
DOMAIN="torrust-demo.dev"
448448
BASE_URL="https://dns.hetzner.com/api/v1"
449449
@@ -512,7 +512,8 @@ chmod +x scripts/manage-dns.sh
512512

513513
```bash
514514
# Test token validity
515-
DNS_TOKEN=$(cat ~/.config/hetzner/dns_api_token)
515+
source infrastructure/config/providers/hetzner.env
516+
DNS_TOKEN="$HETZNER_DNS_API_TOKEN"
516517
curl -H "Auth-API-Token: $DNS_TOKEN" \
517518
"https://dns.hetzner.com/api/v1/zones"
518519

0 commit comments

Comments
 (0)