Skip to content

CLI tool for upgrading the terraform-provider-cloudflare to a new major version

Notifications You must be signed in to change notification settings

cloudflare/tf-migrate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

86 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

tf-migrate - Cloudflare Terraform Provider Migration Tool

A powerful CLI tool for automatically migrating Terraform configurations and state files between different versions of the Cloudflare Terraform Provider.

Overview

tf-migrate helps you upgrade your Terraform infrastructure code by automatically transforming:

  • Configuration files (.tf) - Updates resource types, attribute names, and block structures
  • State files (terraform.tfstate) - Migrates resource state to match new provider schemas

Currently supports migrations:

  • v4 → v5: Cloudflare Provider v4 to v5

Installation

Building from Source

# Clone the repository
git clone <repository-url>
cd tf-migrate

# Build the binary
make

# The binary will be available as ./tf-migrate

Requirements

  • Go 1.25 or later
  • Make
  • Terraform (for testing migrated configurations)

Usage

Authentication

Some resource migrations require access to the Cloudflare API to complete the migration successfully. The tool supports two authentication methods:

Option 1: API Token (Recommended)

export CLOUDFLARE_API_TOKEN="your-api-token"

Option 2: API Key + Email

export CLOUDFLARE_API_KEY="your-api-key"
export CLOUDFLARE_EMAIL="your-email@example.com"

Resources Requiring Authentication

The following resources require API credentials for complete migration:

  • cloudflare_tunnel_routecloudflare_zero_trust_tunnel_cloudflared_route
    • Why: The v4 provider stored network CIDR as the resource ID, but v5 requires the UUID from the API. The migration queries the API to fetch the correct UUID for your tunnel routes.
    • Without credentials: The migration will still update resource types and attributes, but you'll need to run terraform refresh after migration to update the IDs.

Basic Migration

Migrate all Terraform files in the current directory:

tf-migrate migrate --source-version v4 --target-version v5

Migrate Specific Directory

tf-migrate migrate --config-dir ./terraform --source-version v4 --target-version v5

Include State File Migration

tf-migrate migrate \
  --config-dir ./terraform \
  --state-file terraform.tfstate \
  --source-version v4 \
  --target-version v5

Dry Run Mode

Preview changes without modifying files:

tf-migrate migrate --dry-run --source-version v4 --target-version v5

Migrate Specific Resources Only

tf-migrate migrate \
  --resources dns_record,zero_trust_list \
  --source-version v4 \
  --target-version v5

Output to Different Directory

tf-migrate migrate \
  --config-dir ./terraform \
  --output-dir ./terraform-v5 \
  --state-file terraform.tfstate \
  --output-state terraform-v5.tfstate \
  --source-version v4 \
  --target-version v5

Command Reference

Global Flags

Flag Description Default
--config-dir Directory containing Terraform configuration files Current directory
--state-file Path to Terraform state file None
--source-version Source provider version (e.g., v4) Required
--target-version Target provider version (e.g., v5) Required
--resources Comma-separated list of resources to migrate All resources
--dry-run Preview changes without modifying files false
--log-level Set log level (debug, info, warn, error, off) warn

Migrate Command Flags

Flag Description Default
--output-dir Output directory for migrated configuration files In-place
--output-state Output path for migrated state file In-place
--backup Create backup of original files before migration true

Development Tools

Linting Testdata

The project includes a linter to ensure all integration test resources follow naming conventions (prefixed with cftftest):

make lint-testdata

See scripts/README.md for more details on the testdata linter.

Running Tests

Unit Tests

Run all unit tests:

go test ./...

Run tests for a specific package:

go test ./internal/resources/dns_record -v

Run with coverage:

go test ./... -cover

Integration Tests

Integration tests verify the complete migration workflow using real configuration and state files.

# Run all v4 to v5 integration tests
cd integration/v4_to_v5
go test -v

# Run tests for a specific resource
go test -v -run TestV4ToV5Migration/DNSRecord

# Test a single resource using environment variable
TEST_RESOURCE=dns_record go test -v -run TestSingleResource

# Run with detailed diff output (set KEEP_TEMP to see test directory)
KEEP_TEMP=true TEST_RESOURCE=dns_record go test -v -run TestSingleResource
Test Organization

Integration tests are organized by version migration path:

  • integration/test_runner.go - Shared test runner used by all version tests
  • integration/v4_to_v5/ - Tests for v4 to v5 migrations
    • integration_test.go - Test suite specific to v4→v5
    • testdata/ - Test fixtures for each resource
  • Future: integration/v5_to_v6/ - Tests for v5 to v6 migrations
    • integration_test.go - Test suite specific to v5→v6
    • testdata/ - Test fixtures for each resource

Each version migration has its own test suite with explicit migration registration, while sharing the common test runner infrastructure.

End-to-End Tests

E2E tests validate the complete migration workflow with real Cloudflare resources using a Go-based CLI test runner.

What E2E Tests Do:

  1. Init: Sync test resources from integration testdata to e2e/tf/v4/
  2. V4 Apply: Create real infrastructure using v4 provider
  3. Migrate: Run tf-migrate to convert v4 → v5 configurations and state
  4. V5 Apply: Apply v5 configs to verify compatibility with existing infrastructure
  5. Drift Check: Verify v5 plan shows "No changes" (validates successful migration)

Key Features:

  • Credential sanitization - Prevents API keys/secrets from leaking in logs
  • Drift detection - Configurable exemptions via e2e/drift-exemptions.yaml
  • Colored output - Clear success/failure indicators
  • Resource filtering - Test specific resources: --resources custom_pages,load_balancer_monitor
  • 88 unit tests - Comprehensive coverage of the e2e-runner itself

Prerequisites:

Set required environment variables:

export CLOUDFLARE_ACCOUNT_ID="your-account-id"
export CLOUDFLARE_ZONE_ID="your-zone-id"
export CLOUDFLARE_DOMAIN="your-test-domain.com"

# Authentication (choose one)
export CLOUDFLARE_API_TOKEN="your-api-token"  # Recommended
# OR
export CLOUDFLARE_EMAIL="your-email@example.com"
export CLOUDFLARE_API_KEY="your-api-key"

Quick Start:

# Build binaries and run full E2E test suite
./scripts/run-e2e-tests.sh --apply-exemptions

# Or build and run manually
make build-all
./bin/e2e-runner run --apply-exemptions

CLI Commands:

# Run full e2e test suite
./bin/e2e-runner run

# Test specific resources only
./bin/e2e-runner run --resources custom_pages,load_balancer_monitor

# Run with drift exemptions applied
./bin/e2e-runner run --apply-exemptions

# Initialize test resources from integration testdata
./bin/e2e-runner init
./bin/e2e-runner init --resources dns_record

# Run migration only
./bin/e2e-runner migrate
./bin/e2e-runner migrate --resources zero_trust_tunnel_cloudflared_route

# Bootstrap: Migrate local state to R2 remote backend (one-time setup)
./bin/e2e-runner bootstrap

# Clean up: Remove modules from remote state
./bin/e2e-runner clean --modules module.dns_record,module.load_balancer

Testing the E2E Runner:

# Run e2e-runner's own unit tests (88 tests)
make test-e2e

# Run all tests (tf-migrate + e2e-runner)
make test

Drift Exemptions:

Configure acceptable drift in e2e/drift-exemptions.yaml:

dns_record:
  - "created_on"      # API-computed timestamp
  - "modified_on"     # API-computed timestamp
  - "metadata"        # Provider-managed field

Use --apply-exemptions to ignore these known drifts during testing.

Project Structure:

cmd/
├── tf-migrate/       # Main migration binary
└── e2e-runner/       # E2E test runner binary
internal/
├── resources/        # Migration implementations
└── e2e-runner/       # E2E runner implementation (88 unit tests)
e2e/
├── drift-exemptions.yaml
├── tf/v4/           # Test fixtures
└── migrated-v4_to_v5/  # Migration output
bin/                 # Built binaries

CI/CD:

E2E tests run automatically in GitHub Actions on push to main or manual workflow dispatch. See .github/workflows/e2e-tests.yml.

⚠️ Important: E2E tests create and destroy real Cloudflare resources. Always use a dedicated test account, never production infrastructure.

About

CLI tool for upgrading the terraform-provider-cloudflare to a new major version

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 8

Languages