Cloudflare Tunnel - Configuration Terraform
Configuration Terraform pour gérer un tunnel Cloudflare avec support multi-applications et intégration Vault.
📋 Prérequis
- Terraform >= 1.7.5
- Accès à Vault (https://vault.tips-of-mine.com)
- Compte Cloudflare avec accès Zero Trust
- Token Vault avec permissions de lecture sur
secret/cloudflare
🔐 Configuration Vault
1. Structure des secrets dans Vault
Les secrets Cloudflare doivent être stockés dans Vault au chemin secret/cloudflare :
# Se connecter à Vault
vault login
# Créer les secrets Cloudflare
vault kv put secret/cloudflare \
api_token="votre_token_cloudflare" \
zone_id="votre_zone_id" \
account_id="votre_account_id" \
email="admin@tips-of-mine.org"
2. Vérifier les secrets
vault kv get secret/cloudflare
3. Créer un token Vault pour la CI/CD
# Créer une politique pour Terraform
vault policy write terraform-cloudflare - <<EOF
path "secret/data/cloudflare" {
capabilities = ["read"]
}
EOF
# Créer un token avec cette politique
vault token create -policy=terraform-cloudflare -ttl=1h
🚀 Utilisation
Configuration locale (développement)
# Initialiser Terraform
terraform init
# Définir le token Vault
export VAULT_TOKEN="votre_token_vault"
export TF_VAR_vault_token="$VAULT_TOKEN"
# Planifier les changements
terraform plan
# Appliquer la configuration
terraform apply
Ajouter une nouvelle application
Éditez terraform.tfvars et ajoutez une nouvelle entrée dans applications :
applications = {
# Applications existantes...
# Nouvelle application
"mon-app" = {
subdomain = "mon-app"
origin_url = "http://10.0.4.200:3000"
no_tls_verify = false
access_enabled = true
access_team_name = "tips-of-mine"
access_aud_tags = ["mon-app-tag"]
}
}
🔧 Configuration CI/CD
Variables d'environnement requises
La CI/CD doit définir :
# Token Vault (obligatoire)
VAULT_TOKEN="hvs.xxxxxxxxxxxxx"
# Ou via TF_VAR
TF_VAR_vault_token="hvs.xxxxxxxxxxxxx"
Exemple de commandes CI/CD
# Pipeline steps
terraform init
terraform validate
terraform plan -out=tfplan
terraform apply tfplan
📊 Outputs
Après l'apply, Terraform affichera :
- tunnel_id : ID du tunnel Cloudflare
- tunnel_cname : CNAME technique du tunnel
- tunnel_token : Token pour cloudflared (sensible)
- applications_urls : URLs publiques de toutes les applications
- applications_details : Détails complets de chaque application
Récupérer le tunnel token
terraform output -raw tunnel_token
🔒 Sécurité
✅ Ce qui est sécurisé
- Tous les secrets Cloudflare sont dans Vault
- Le tunnel token est marqué comme sensible
- Pas de secrets en clair dans le code
- Variables sensibles protégées
⚠️ Points d'attention
- Ne jamais commiter
terraform.tfstate(contient le tunnel token) - Ne jamais commiter
.terraform/ - Le
vault_tokendoit être fourni par la CI/CD - Utiliser un backend distant pour le state (S3, GCS, Terraform Cloud)
.gitignore recommandé
# Terraform
.terraform/
*.tfstate
*.tfstate.*
*.tfvars.backup
.terraform.lock.hcl
# Secrets
*.pem
*.key
.env
secrets/
# OS
.DS_Store
Thumbs.db
📁 Structure du projet
.
├── main.tf # Configuration principale et Vault
├── variables.tf # Déclaration des variables
├── terraform.tfvars # Valeurs des variables (sans secrets)
├── providers.tf # Configuration des providers
├── tunnels.tf # Configuration du tunnel et applications
├── outputs.tf # Outputs Terraform
└── README.md # Cette documentation
🔄 Backend Terraform distant (recommandé)
Pour la CI/CD, configurez un backend distant dans providers.tf :
terraform {
backend "s3" {
bucket = "votre-bucket-terraform-state"
key = "cloudflare-tunnel/terraform.tfstate"
region = "eu-west-1"
}
}
Ou avec Terraform Cloud :
terraform {
cloud {
organization = "votre-org"
workspaces {
name = "cloudflare-tunnel"
}
}
}
📖 Exemples d'applications
Application simple sans Access
"app-simple" = {
subdomain = "app"
origin_url = "http://10.0.4.10:80"
no_tls_verify = false
access_enabled = false
}
Application avec HTTPS auto-signé
"app-https" = {
subdomain = "secure-app"
origin_url = "https://10.0.4.20:443"
no_tls_verify = true # Accepter les certificats auto-signés
access_enabled = false
}
Application avec Cloudflare Access
"app-protected" = {
subdomain = "admin"
origin_url = "http://10.0.4.30:8080"
no_tls_verify = false
access_enabled = true
access_team_name = "tips-of-mine"
access_aud_tags = ["admin-access"]
}
🆘 Dépannage
Erreur : "Invalid Vault token"
# Vérifier que le token est valide
vault token lookup
# Renouveler si nécessaire
vault token renew
Erreur : "Permission denied on secret/cloudflare"
# Vérifier les permissions du token
vault token capabilities secret/cloudflare
Le tunnel ne se connecte pas
# Récupérer le token et le tester
TOKEN=$(terraform output -raw tunnel_token)
cloudflared tunnel run --token $TOKEN
📝 Notes
- Le
lifecycle { ignore_changes = [config] }permet de modifier manuellement la config dans le Dashboard Cloudflare sans conflit - Chaque application obtient son propre enregistrement DNS CNAME
- Le tunnel supporte un nombre illimité d'applications
- Les règles Access sont optionnelles par application