Skip to content

Commit ba2fb86

Browse files
authored
Merge branch 'main' into feat/healthcheck-v4-to-v5-migration
2 parents 7b5d858 + 914f7a8 commit ba2fb86

File tree

171 files changed

+44031
-447
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

171 files changed

+44031
-447
lines changed

.github/workflows/ci.yml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- '**' # Run on all branches
7+
pull_request:
8+
branches:
9+
- '**' # Run on PRs to any branch
10+
11+
jobs:
12+
unit-tests:
13+
name: Unit Tests
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v4
18+
19+
- name: Setup Go
20+
uses: actions/setup-go@v5
21+
with:
22+
go-version-file: ./go.mod
23+
24+
- name: Get dependencies
25+
run: |
26+
go mod download
27+
go mod tidy
28+
29+
- name: Run unit tests with coverage
30+
run: |
31+
go test -v -race -coverprofile=coverage.out -covermode=atomic ./internal/...
32+
go test -v -race ./cmd/...
33+
34+
- name: Generate coverage report
35+
run: |
36+
echo "Coverage Report:"
37+
go tool cover -func=coverage.out
38+
39+
integration-tests:
40+
name: Integration Tests
41+
runs-on: ubuntu-latest
42+
needs: unit-tests
43+
permissions:
44+
contents: read
45+
steps:
46+
- name: Checkout code
47+
uses: actions/checkout@v4
48+
49+
- name: Setup Go
50+
uses: actions/setup-go@v5
51+
with:
52+
go-version-file: ./go.mod
53+
54+
- name: Get dependencies
55+
run: |
56+
go mod download
57+
go mod tidy
58+
59+
- name: Build tf-migrate
60+
run: |
61+
go build -o tf-migrate ./cmd/tf-migrate
62+
./tf-migrate version
63+
64+
- name: Run integration tests for v4 to v5
65+
run: |
66+
cd integration/v4_to_v5
67+
go test -v -race -timeout 10m
68+
69+
e2e-tests:
70+
name: E2E Tests
71+
runs-on: ubuntu-latest
72+
needs: integration-tests
73+
permissions:
74+
contents: read
75+
steps:
76+
- name: Checkout code
77+
uses: actions/checkout@v4
78+
79+
- name: Setup Go
80+
uses: actions/setup-go@v5
81+
with:
82+
go-version-file: ./go.mod
83+
84+
- name: Setup Terraform
85+
uses: hashicorp/setup-terraform@v3
86+
with:
87+
terraform_version: "1.9.8"
88+
89+
- name: Get dependencies
90+
run: |
91+
go mod download
92+
go mod tidy
93+
94+
- name: Run E2E tests
95+
env:
96+
CLOUDFLARE_API_KEY: ${{ secrets.CLOUDFLARE_API_KEY }}
97+
CLOUDFLARE_EMAIL: ${{ secrets.CLOUDFLARE_EMAIL }}
98+
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
99+
CLOUDFLARE_ZONE_ID: ${{ secrets.CLOUDFLARE_ZONE_ID }}
100+
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
101+
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
102+
run: |
103+
./scripts/run-e2e-tests

.gitignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
tf-migrate
2+
.terraformrc-tf-migrate
3+
4+
# Local provider dev overrides
5+
.terraformrc-tf-migrate
6+
7+
# E2E test files
8+
# Ignore v4 directory except provider.tf and backend.hcl
9+
e2e/tf/v4/*
10+
!e2e/tf/v4/provider.tf
11+
!e2e/tf/v4/backend.hcl
12+
13+
# Migrated output
14+
e2e/migrated-v4_to_v5/
15+
16+
# E2E test outputs
17+
e2e/tmp/
18+
19+
# E2E test state files (stored in remote backend)
20+
e2e/tf/v4/terraform.tfstate*
21+
e2e/tf/v5/terraform.tfstate*
22+
23+
# Backend configuration with secrets (generated at runtime)
24+
e2e/tf/v4/backend.configured.hcl
25+
26+
# Backup files
27+
e2e/*.backup
28+
e2e/*.tfstate.backup

Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# tf-migrate Makefile
2+
3+
BINARY_NAME := tf-migrate
4+
GO := go
5+
MAIN_PACKAGE := ./cmd/tf-migrate
6+
7+
.PHONY: build test
8+
9+
# Build the binary
10+
build:
11+
$(GO) build -v -o $(BINARY_NAME) $(MAIN_PACKAGE)
12+
13+
# Run unit tests
14+
test:
15+
$(GO) test -v -race ./...

README.md

Lines changed: 207 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,207 @@
1-
# tf-migrate
1+
# tf-migrate - Cloudflare Terraform Provider Migration Tool
2+
3+
A powerful CLI tool for automatically migrating Terraform configurations and state files between different versions of the Cloudflare Terraform Provider.
4+
5+
## Overview
6+
7+
`tf-migrate` helps you upgrade your Terraform infrastructure code by automatically transforming:
8+
- **Configuration files** (`.tf`) - Updates resource types, attribute names, and block structures
9+
- **State files** (`terraform.tfstate`) - Migrates resource state to match new provider schemas
10+
11+
Currently supports migrations:
12+
- **v4 → v5**: Cloudflare Provider v4 to v5
13+
14+
## Installation
15+
16+
### Building from Source
17+
18+
```bash
19+
# Clone the repository
20+
git clone <repository-url>
21+
cd tf-migrate
22+
23+
# Build the binary
24+
make
25+
26+
# The binary will be available as ./tf-migrate
27+
```
28+
29+
### Requirements
30+
- Go 1.25 or later
31+
- Make
32+
- Terraform (for testing migrated configurations)
33+
34+
## Usage
35+
36+
### Authentication
37+
38+
Some resource migrations require access to the Cloudflare API to complete the migration successfully. The tool supports two authentication methods:
39+
40+
**Option 1: API Token (Recommended)**
41+
```bash
42+
export CLOUDFLARE_API_TOKEN="your-api-token"
43+
```
44+
45+
**Option 2: API Key + Email**
46+
```bash
47+
export CLOUDFLARE_API_KEY="your-api-key"
48+
export CLOUDFLARE_EMAIL="your-email@example.com"
49+
```
50+
51+
#### Resources Requiring Authentication
52+
53+
The following resources require API credentials for complete migration:
54+
55+
- `cloudflare_tunnel_route``cloudflare_zero_trust_tunnel_cloudflared_route`
56+
- **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.
57+
- **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.
58+
59+
### Basic Migration
60+
61+
Migrate all Terraform files in the current directory:
62+
63+
```bash
64+
tf-migrate migrate --source-version v4 --target-version v5
65+
```
66+
67+
### Migrate Specific Directory
68+
69+
```bash
70+
tf-migrate migrate --config-dir ./terraform --source-version v4 --target-version v5
71+
```
72+
73+
### Include State File Migration
74+
75+
```bash
76+
tf-migrate migrate \
77+
--config-dir ./terraform \
78+
--state-file terraform.tfstate \
79+
--source-version v4 \
80+
--target-version v5
81+
```
82+
83+
### Dry Run Mode
84+
85+
Preview changes without modifying files:
86+
87+
```bash
88+
tf-migrate migrate --dry-run --source-version v4 --target-version v5
89+
```
90+
91+
### Migrate Specific Resources Only
92+
93+
```bash
94+
tf-migrate migrate \
95+
--resources dns_record,zero_trust_list \
96+
--source-version v4 \
97+
--target-version v5
98+
```
99+
100+
### Output to Different Directory
101+
102+
```bash
103+
tf-migrate migrate \
104+
--config-dir ./terraform \
105+
--output-dir ./terraform-v5 \
106+
--state-file terraform.tfstate \
107+
--output-state terraform-v5.tfstate \
108+
--source-version v4 \
109+
--target-version v5
110+
```
111+
112+
## Command Reference
113+
114+
### Global Flags
115+
116+
| Flag | Description | Default |
117+
|------|-------------|---------|
118+
| `--config-dir` | Directory containing Terraform configuration files | Current directory |
119+
| `--state-file` | Path to Terraform state file | None |
120+
| `--source-version` | Source provider version (e.g., v4) | Required |
121+
| `--target-version` | Target provider version (e.g., v5) | Required |
122+
| `--resources` | Comma-separated list of resources to migrate | All resources |
123+
| `--dry-run` | Preview changes without modifying files | false |
124+
| `--log-level` | Set log level (debug, info, warn, error, off) | warn |
125+
126+
### Migrate Command Flags
127+
128+
| Flag | Description | Default |
129+
|------|-------------|---------|
130+
| `--output-dir` | Output directory for migrated configuration files | In-place |
131+
| `--output-state` | Output path for migrated state file | In-place |
132+
| `--backup` | Create backup of original files before migration | true |
133+
134+
### Running Tests
135+
136+
#### Unit Tests
137+
138+
Run all unit tests:
139+
```bash
140+
go test ./...
141+
```
142+
143+
Run tests for a specific package:
144+
```bash
145+
go test ./internal/resources/dns_record -v
146+
```
147+
148+
Run with coverage:
149+
```bash
150+
go test ./... -cover
151+
```
152+
153+
#### Integration Tests
154+
155+
Integration tests verify the complete migration workflow using real configuration and state files.
156+
157+
```bash
158+
# Run all v4 to v5 integration tests
159+
cd integration/v4_to_v5
160+
go test -v
161+
162+
# Run tests for a specific resource
163+
go test -v -run TestV4ToV5Migration/DNSRecord
164+
165+
# Test a single resource using environment variable
166+
TEST_RESOURCE=dns_record go test -v -run TestSingleResource
167+
168+
# Run with detailed diff output (set KEEP_TEMP to see test directory)
169+
KEEP_TEMP=true TEST_RESOURCE=dns_record go test -v -run TestSingleResource
170+
```
171+
172+
##### Test Organization
173+
174+
Integration tests are organized by version migration path:
175+
- `integration/test_runner.go` - Shared test runner used by all version tests
176+
- `integration/v4_to_v5/` - Tests for v4 to v5 migrations
177+
- `integration_test.go` - Test suite specific to v4→v5
178+
- `testdata/` - Test fixtures for each resource
179+
- Future: `integration/v5_to_v6/` - Tests for v5 to v6 migrations
180+
- `integration_test.go` - Test suite specific to v5→v6
181+
- `testdata/` - Test fixtures for each resource
182+
183+
Each version migration has its own test suite with explicit migration registration, while sharing the common test runner infrastructure.
184+
185+
#### End-to-End Tests
186+
187+
E2E tests validate the complete migration workflow with real Cloudflare resources. These tests:
188+
1. Apply v4 Terraform configs to create real infrastructure
189+
2. Run the migration tool to generate v5 configs
190+
3. Apply v5 configs and verify no changes are needed
191+
4. Compare v4 and v5 state to ensure equivalence
192+
193+
**Requirements:**
194+
- Cloudflare API credentials for "Terraform Test" account (set as `CLOUDFLARE_API_KEY` and `CLOUDFLARE_EMAIL`)
195+
- Terraform installed
196+
197+
```bash
198+
# Run all E2E tests
199+
./scripts/run-e2e-tests
200+
201+
# Run E2E tests for specific resources only
202+
./scripts/run-e2e-tests --resources dns_record,api_token
203+
```
204+
205+
**Output:**
206+
- Test logs saved to `e2e/tmp/*.log`
207+
- State snapshots saved to `e2e/tmp/*-state.json`

0 commit comments

Comments
 (0)