Saltar a contenido

Cloudflare como IaC

Cómo se gestiona Cloudflare con Terraform y cómo reimportar si hace falta.

Estructura

  • Root: terraform/cloudflare/, state remoto en R2 (cloudflare.tfstate).
  • Autosync: cloudflare-plan.yml (PR) y cloudflare-apply.yml (main).

Credenciales

  • CLOUDFLARE_API_TOKEN (permisos mínimos) por GitHub Secrets / .env.
  • R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY para el backend (se exportan como AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY).
  • GOOGLE_CLIENT_SECRET (Access) por GitHub Secrets / .env.

Rotar el client_secret de Google (Access)

El client_secret del IdP es write-only: en access.tf lleva lifecycle { ignore_changes = [config.client_secret] } (v5) para no ver un diff perpetuo. Para rotarlo:

  1. Actualizar GOOGLE_CLIENT_SECRET en .env (y GitHub Secret) con el nuevo.
  2. Quitar temporalmente el bloque lifecycle { ignore_changes = ... } de cloudflare_zero_trust_access_identity_provider.google.
  3. terraform apply (actualiza el secret en Cloudflare).
  4. Volver a poner el bloque lifecycle { ignore_changes = ... }.
  5. terraform plan hasta No changes. y commitear.

Import (solo si hay que recuperar estado)

  1. terraform init
  2. Importar cada recurso con terraform import (formato por recurso, ver plan docs/plans/2026-09-01-cloudflare-iac.md).
  3. terraform plan hasta No changes.

Precauciones

  • Nunca aplicar si el plan muestra destroy/replace de DNS, zona o túnel.
  • El bucket R2 y el login method de Zero Trust son manuales (fuera de TF).

Fuera de alcance (deliberado)

  • Dirección destino de Email Routing (cloudflare_email_routing_address): ya está verificada y no hace falta gestionarla para el reenvío; requeriría el permiso account-level "Email Routing Addresses" en el token.
  • Registro DKIM (cf2024-1._domainkey): lo gestiona Email Routing y no se puede modificar por la API DNS (error 1046).
  • Settings de zona: se gestionan solo 12 (sin minify, que da error 1007).