Migreringen omfattet tre miljøer, mer enn 50 ressurstyper og godt over 300 Terraform-ressurser.

Teamet som vedlikeholdt miljøet, besto i praksis av én konsulent. Det operative målet var enkelt: få tilgang til nye funksjoner i Cloudflare Provider uten å ødelegge produksjon.

Cloudflare ligger for nær kanten til å migreres uformelt: DNS, WAF, rulesets, Zero Trust, tunneler og omdirigeringer. Blir prosessen rotete, blir tilbakemeldingssløyfen raskt treg.

Jeg behandlet dette som en kontrollert kantmigrering: trinnvis utrulling, ingen automatisk apply, test før produksjon og skriptet reparasjon av state for ressurser leverandøren ikke kunne oppgradere rent.

Før jeg rørte provider v5, etablerte jeg derfor arbeidsmodellen:

  1. blokker farlige kommandoer
  2. start med skrivebeskyttet Cloudflare-tilgang
  3. arbeid først mot en lokal kopi av state
  4. kjør migreringsverktøyet som en dry-run
  5. vurder først deretter import, opprydding av state og apply

Innlegget handler hovedsakelig om hvordan migreringen kan rigges slik at ingeniører kommer gjennom den med mindre gjetting, ikke om hele migreringen ressurs for ressurs.

Kort fortalt
Ikke start med brede Cloudflare-rettigheter og direkte tilgang til det vanlige eksterne backend-et.
Start skrivebeskyttet, blokker terraform apply, hent state lokalt og forvent manuell opprydding.

Hvorfor dette var viktig for virksomheten Lenke til overskrift

Dette var mer enn en Terraform-oppgradering. Det var et Day 2-infrastrukturproblem.

I starten er de fleste team fornøyde bare IaC finnes. Deretter øker produktpresset, hasteendringer gjøres, noen klikker endringer i konsollen og lover å rydde opp senere, og Terraform-dekningen faller fra 100 til 90 og 80 prosent. Da blir hver endring tregere og mindre pålitelig.

Hvis kantkonfigurasjonen ikke er riktig representert i kode:

  • blir leveranser tregere
  • blir produksjonsendringer vanskeligere å gjennomgå
  • trenger nye ingeniører mer taus kunnskap
  • blir selskapet avhengig av minnet til én operatør

Migreringen var viktig fordi den førte kantlaget tilbake til en form der virksomheten kan bevege seg videre uten å være avhengig av manuelle konsollendringer.

Hva dette åpner for utover Terraform Lenke til overskrift

Cloudflare satser nå langt utover tradisjonell CDN og DNS. Utviklerplattformen er en reell produktoverflate.

En utdatert eller halvveis manuelt administrert provider gjør det vanskeligere å ta i bruk:

  • Workers AI for inferens i Cloudflares nettverk
  • AI Gateway for observerbarhet, caching, nye forsøk, hastighetsbegrensning og fallback i AI-applikasjoner
  • Vectorize for vektorsøk og retrieval-arbeidslaster
  • Durable Objects for tilstandsfull koordinering og sanntidssystemer
  • Agents SDK for tilstandsfulle agenter med planlegging, verktøy og human-in-the-loop-flyter
  • Hyperdrive for å koble Workers til eksisterende regionale databaser med bedre global ytelse

Dette holder veien åpen for å bygge applikasjonsfunksjoner på den samme plattformen som allerede står foran produksjonstrafikken. For et lite selskap gir det innflytelse. Verdien er ikke bare at Terraform ble oppgradert, men at nye plattformfunksjoner kan tas i bruk uten først å løse gammel infrastrukturgjeld.

Start med et skrivebeskyttet Cloudflare-token Lenke til overskrift

Jeg gir først et skrivebeskyttet Cloudflare-token. Ikke admin eller «midlertidig full tilgang», bare nok til å inspisere det som finnes.

Hvorfor?

  • jeg vil kartlegge først
  • provider refresh og plan trenger vanligvis API-lesetilgang
  • jeg vil inspisere eksisterende objekter før skrivetilgang tillates
  • hvis tokenet lekker, blir skadeomfanget langt mindre

På dette stadiet trenger jeg bare innsyn i objektene Terraform allerede forvalter: soner, DNS, rulesets, WAF-objekter, Zero Trust-ressurser og tilsvarende objekter i stakken.

Hvis skrivetilgang blir nødvendig, bytter jeg legitimasjon først etter at et menneske har gjennomgått diffen. Kartlegging og API-oppslag bruker det skrivebeskyttede tokenet. Endringer skjer i en separat, kontrollert fase.

Hold autentiseringen kjedelig Lenke til overskrift

Autentiseringsmodellen bør være enkel og eksplisitt:

export CLOUDFLARE_API_TOKEN="..."

Tokenet bør komme fra en egnet kilde:

  • lokal hemmelighetsbehandler
  • CI secret store
  • kortvarig shell-økt

Det skal ikke committes til repositoriet eller kopieres inn i en prompt.

Migreringsplanen Lenke til overskrift

Rekkefølgen min var:

  1. oppgrader først fra 4.52.0 til 4.52.5
  2. kjør tf-migrate som dry-run
  3. utfør HCL-omskrivingen og gjennomgå alle endrede .tf-filer
  4. rett manuelt ressurser som er fjernet eller har fått nytt navn
  5. bytt til provider ~> 5
  6. reparer state-problemer
  7. utfør endringene i test
  8. rør først deretter prod

Jeg deler også arbeidet i flere pull requests:

  • PR1: overgangsoppgradering til provider 4.52.5
  • PR2: HCL-omskriving med tf-migrate og manuelle rettelser
  • PR3: provider ~> 5, opprydding av state, importflyt og endelig validering

Dette holder diffen lesbar, gjør CI-resultater enklere å forstå og gir et tydelig kontrollpunkt etter hver fase. Hvis en fase feiler, vet jeg hvor jeg skal stoppe, rulle tilbake eller planlegge på nytt.

Hent state og arbeid lokalt først Lenke til overskrift

Jeg starter ikke eksperimenteringen mot det vanlige backend-et. Først henter jeg state lokalt:

./tf.sh state pull > migration.tfstate
cp <environment>.tfvars <environment>.auto.tfvars

Kopien til *.auto.tfvars gjør at lokale Terraform-kjøringer laster de samme miljøverdiene uten ekstra flagg. Deretter bytter jeg backend midlertidig:

terraform {
  backend "local" {
    path = "migration.tfstate"
  }
}

Når opprydding, importer og oppgradering av provider-skjema kan bli nødvendig, vil jeg ha en lokal kopi først. Den gir et tryggere sted å inspisere, teste og forstå konsekvensene før den normale backend-flyten berøres, og gir raskere tilbakemeldinger gjennom mange små iterasjoner.

Lokal Terraform-state kan inneholde hemmeligheter og må behandles deretter.

Kjør migreringsverktøyet som dry-run først Lenke til overskrift

Før provider-begrensningen endres, kjører jeg:

tf-migrate migrate --source-version v4 --target-version v5 --dry-run --config-dir .

Advarslene er det interessante. De viste hvor manuelt arbeid fortsatt var nødvendig:

  • Access policies avgrenset til applikasjoner
  • ressurser som var fjernet i v5
  • ressurser som krevde opprydding av state og ny import

Verktøyet trenger ikke fullføre migreringen. Det må vise ingeniørene hvor den manuelle gjennomgangen bør brukes.

Dette fullførte ikke tf-migrate Lenke til overskrift

Access policies på applikasjonsnivå kunne ikke migreres automatisk. I v5 må de ligge inline i cloudflare_zero_trust_access_application.

cloudflare_split_tunnel ble fjernet og måtte flyttes til konfigurasjonen av enhetsprofiler.

cloudflare_zone_settings_override ble også fjernet. Migreringen genererte ressurser per innstilling, men gammel state måtte fortsatt fjernes og de nye ressursene importeres riktig.

Det fantes også feltendringer. min_days_for_renewal forsvant for Origin CA Certificate-ressurser.

Derfor er resultatet fra migreringsverktøyet første gjennomgang, ikke den ferdige migreringen.

Forvent manuell opprydding av state Lenke til overskrift

Migreringen handler ikke bare om nye ressursnavn. Enkelte feil oppstår fordi gammel state ikke kan dekodes av v5-provideren. Terraform feiler da før en nyttig diff produseres.

Jeg så mønsteret for blant annet:

  • Zero Trust Gateway policies
  • load balancer monitors
  • soner og objekter knyttet til soneinnstillinger

Eksempler på dekodingsfeil:

  • rule_settings: expected object, got array
  • header: expected object, got array
  • plan: expected object, got string

Fremgangsmåten er vanligvis:

  1. sikkerhetskopier state
  2. fjern bare adressene som feiler
  3. importer dem på nytt i v5-format
  4. kjør plan på nytt

Det lokale backend-et gir rom til å reparere state kontrollert.

Ressurser som krever manuell gjennomgang Lenke til overskrift

Følg særlig med på:

  • Access policies knyttet til applikasjoner
  • split tunnel-konfigurasjon
  • zone settings overrides
  • rulesets
  • load balancer-ressurser

Application Access policies er ikke bare et problem med nye navn. I v5 må enkelte flyttes til inline policies i applikasjonsressursen. Dette bør ikke overlates til automatisk omskriving uten kontroll.

Gamle override-ressurser for soneinnstillinger kan bli mange ressurser, én per innstilling. Det krever ofte eksplisitt opprydding av state og importer, ikke bare HCL-endringer.

Bruk små shell-skript som migreringshjelpere Lenke til overskrift

Små engangsskript er bedre enn å huske hver state rm-kommando og hvert importformat. De er enkle, eksplisitte og lette å gjennomgå.

Jeg brukte tre kategorier:

  1. skript som fjerner utdaterte state-oppføringer
  2. skript som importerer ressurser med nye navn
  3. skript som spør Cloudflare API og matcher objekter automatisk

Alle ID-er nedenfor er eksempler.

Eksempel 1: Masserydding av state Lenke til overskrift

#!/usr/bin/env bash
set -euo pipefail

terraform state rm \
  'cloudflare_ruleset.example' \
  'cloudflare_access_policy.example' \
  'cloudflare_zone_settings_override.this' \
  'cloudflare_worker_domain.this' \
  'cloudflare_tunnel_virtual_network.default'

Dette er tryggere enn å skrive en lang liste manuelt når du er sliten og allerede har gjennomgått mange planer.

Eksempel 2: Miljøbevisst importskript Lenke til overskrift

For ressurser som finnes i alle miljøer, men har ulike ID-er, bruker jeg en wrapper som oppdager AWS-kontoen og velger riktig import-ID.

#!/usr/bin/env bash
set -euo pipefail

ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"

case "$ACCOUNT_ID" in
  "123456789012")
    ENV_NAME="test"
    CLOUDFLARE_ACCOUNT_ID="7f3c5a0b1d4e6f8899aabbccddeeff00"
    RESOURCE_ID="2c9d4a8f7b6e5d4c3b2a1908fedcba76"
    ;;
  "210987654321")
    ENV_NAME="prod"
    CLOUDFLARE_ACCOUNT_ID="7f3c5a0b1d4e6f8899aabbccddeeff00"
    RESOURCE_ID="8a7b6c5d4e3f2109fedcba9876543210"
    ;;
  *)
    echo "Unsupported account: $ACCOUNT_ID"
    exit 1
    ;;
esac

echo "Detected environment: $ENV_NAME"
terraform import cloudflare_load_balancer_monitor.default "$CLOUDFLARE_ACCOUNT_ID/$RESOURCE_ID"

Mønsteret var nyttig for load balancer monitors, pools, load balancers, worker domains og flere andre ressurser.

Eksempel 3: Tolk plan og importer eksisterende rulesets på nytt Lenke til overskrift

Noen ganger ville Terraform opprette et ruleset som allerede fantes i Cloudflare. Hvis planen inneholder nok metadata til å identifisere objektet, vil jeg ikke importere hvert objekt manuelt.

Et hjelpeskript kan:

  1. lese plan.txt
  2. finne cloudflare_ruleset.* will be created
  3. hente ut zone ID, navn, phase og beskrivelse
  4. kalle Cloudflare API
  5. finne samsvarende ruleset ID
  6. kjøre terraform import
#!/usr/bin/env bash
set -euo pipefail

PLAN_FILE="${1:-plan.txt}"
ZONE_ID="f1e2d3c4b5a697887766554433221100"
RULESET_ID="9b8a7c6d5e4f32100123456789abcdef"

# parse plan output here
# call Cloudflare API here
# match by zone_id + name + phase
# terraform import "cloudflare_ruleset.example" "zones/$ZONE_ID/$RULESET_ID"

Her sparer automatisering tid uten å øke risikoen. Den reduserer også personavhengighet: En annen ingeniør kan følge samme rekkefølge og gjenta reparasjonen uten å rekonstruere hele stakken.

Legg verktøy bak rekkverk Lenke til overskrift

Jeg bruker kodeassistenter til å skanne mange .tf-filer, oppdage ressurser med nye navn, oppsummere advarsler og forberede repeterende endringer. Grensen er enkel:

  • les repositoriet
  • les provider-dokumentasjonen
  • forbered kodeendringer
  • oppsummer migreringsadvarsler
  • utfør aldri infrastrukturendringer på egen hånd

I Cursor er beforeShellExecution en enkel kontroll som kan avvise kommandoer før de utføres:

"beforeShellExecution": [
  {
    "command": "~/.cursor/hooks/block-apply.sh"
  }
]

En liten hook:

#!/usr/bin/env bash
set -euo pipefail

input="$(cat 2>/dev/null || echo '{}')"
cmd="$(echo "$input" | jq -r '.command // .cmd // .shell_command // empty')"

case "$cmd" in
  *"terraform apply"*|*"terraform destroy"*|*"terraform import"*|*"terraform state rm"*|*"terraform state mv"*|*"auto-approve"*)
    echo "Blocked by policy during migration window: $cmd" >&2
    exit 2
    ;;
esac

I første fase kunne verktøyet fortsatt skanne moduler, sammenligne v4 og v5, forberede refaktorering og skrive kontrollnotater, men ikke gå rett til endringer.

Avvisningsregelen gjelder assistentdrevet kartlegging og forberedelse av diff. Etter gjennomgang kjører jeg selv godkjente terraform import, terraform state rm og terraform apply i en separat, overvåket shell-økt. Hooken stopper for tidlige endringer; den forbyr ikke migreringen permanent.

Det som hjalp mest Lenke til overskrift

  • bruk test først og hold prod bak gjennomgang
  • kjør tf-migrate som dry-run før provider-versjonen endres
  • forvent arbeid med state rm og terraform import
  • behold hjelpeskript for gjentatte importer
  • kjør CI-planer gjennom alle faser
  • fjern -auto-approve i migreringsvinduet

Til sammen gjør dette migreringen langt enklere å gjennomføre og reduserer senere vedlikeholdskostnader ved å gjøre engangsritualer til dokumenterte driftsverktøy.

Arbeidsflyten i første fase Lenke til overskrift

Før et trinn med skrivetilgang:

  1. les Terraform-koden
  2. kjør migreringen som dry-run
  3. forbered kodeendringer
  4. kjør trygge kontroller som terraform fmt og terraform validate
  5. forbered kommandoer for import og opprydding av state til gjennomgang
  6. gjennomgå diffen

Det første målet er ikke å fullføre migreringen, men å fjerne usikkerhet.

Test før produksjon, og hold CI i gang Lenke til overskrift

Utrullingsregelen var:

  1. migrer og utfør endringene i test
  2. bekreft at planen etterpå er ren
  3. la CI fortsatt planlegge både test og prod
  4. åpne først deretter veien til prod

Midlertidig ustabilitet i prod-planen kan oppstå under mellomliggende navne- og state-endringer. Det er akseptabelt i en kort periode. En blind apply mot prod er ikke det. -auto-approve holdes helt utenfor flyten.

Resultat Lenke til overskrift

Oppgraderingen var ikke helautomatisk, men dry-run, lokal state, skriptede importer og trinnvis utrulling gjorde den forutsigbar nok til å utføres trygt.

Målet var ikke en elegant migrering, men å komme gjennom uten å ødelegge produksjon eller gjøre minnet til én ingeniør til eneste runbook. Resultatet ga:

  • bedre vei til nyere funksjoner i Cloudflare-plattformen
  • mindre avhengighet av konsollendringer og én persons hukommelse
  • tryggere utrulling av en produksjonskritisk kantmigrering
  • tydeligere signal om at en annen ingeniør senere kan vedlikeholde miljøet

Definer tilbakestillingsveien på forhånd Lenke til overskrift

Etter lokal reparasjon vil jeg ha en eksplisitt vei tilbake:

  • gjenopprett den vanlige backend-blokken
  • initialiser Terraform på nytt
  • migrer backend-metadata ved behov
  • fjern midlertidige filer som kopierte tfvars, midlertidige planer og lokal state

Uten dette hoper midlertidige filer seg opp, folk glemmer hvilken plan som er nyest, og risikoen for dårlige beslutninger øker.

Avsluttende tanker Lenke til overskrift

Den vanskelige delen er ikke HCL-omskrivingen. Det vanskelige er å holde prosessen så forutsigbar at andre ingeniører også kan følge den.

Regelen er enkel:

  • skrivebeskyttet først
  • lokal state først
  • dry-run først
  • små hjelpeskript fremfor manuell repetisjon
  • menneskelig gjennomgang før endringer

Slik foretrekker jeg å starte en migrering av Cloudflare Provider fra v4 til v5 og hjelpe neste ingeniør gjennom den raskere.