Skip to content

Commit e8e430c

Browse files
author
cortlyons
committed
cloudflare_zero_trust_device_posture_integration state upgrader
1 parent 7669c28 commit e8e430c

File tree

5 files changed

+279
-443
lines changed

5 files changed

+279
-443
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Drift Exemptions for zero_trust_device_posture_integration resource
2+
#
3+
# Resource-specific exemptions for cloudflare_zero_trust_device_posture_integration
4+
#
5+
# SDK v2 stores unset optional fields as empty strings (""), while Framework stores
6+
# them as null. During migration, these fields are converted from "" to null to match
7+
# Framework behavior, which causes expected initial drift.
8+
9+
version: 1
10+
11+
exemptions:
12+
# ONLY empty string to null conversions - no other drift allowed
13+
- name: "empty_string_to_null_only"
14+
description: "Allow ONLY empty string to null conversions (SDK v2 -> Framework)"
15+
patterns:
16+
- '"".*->.*null'
17+
- '-> null # forces replacement'
18+
enabled: true
19+
20+
settings:
21+
apply_exemptions: true
22+
verbose_exemptions: false

integration/v4_to_v5/testdata/zero_trust_device_posture_integration/expected/device_posture_integration.tf

Lines changed: 93 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,35 @@ locals {
2323
ws1_auth_url = "https://na.uemauth.vmwservices.com/connect/token"
2424
}
2525

26+
27+
28+
29+
30+
31+
32+
33+
34+
35+
36+
37+
38+
39+
# Total resource instances:
40+
# - map_integrations: 3 (workspace_one, crowdstrike, uptycs)
41+
# - set_integrations: 3 (intune, kolide, sentinelone_s2s)
42+
# - count_integrations: 3
43+
# - conditional: 2
44+
# - primary: 1
45+
# - secondary: 1
46+
# - lifecycle_test: 1
47+
# - prevent_destroy: 1
48+
# - function_test: 1
49+
# - minimal: 1
50+
# - all_fields: 1
51+
# - no_interval: 1
52+
# - dynamic_test: 1
53+
# TOTAL: 20 resource instances
54+
2655
# Pattern 3: for_each with maps (3-5 resources)
2756
resource "cloudflare_zero_trust_device_posture_integration" "map_integrations" {
2857
for_each = {
@@ -65,6 +94,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "map_integrations" {
6594
}
6695
}
6796

97+
moved {
98+
from = cloudflare_device_posture_integration.map_integrations
99+
to = cloudflare_zero_trust_device_posture_integration.map_integrations
100+
}
101+
68102
# Pattern 4: for_each with sets (3-5 items)
69103
resource "cloudflare_zero_trust_device_posture_integration" "set_integrations" {
70104
for_each = toset(["intune", "kolide", "sentinelone_s2s"])
@@ -80,6 +114,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "set_integrations" {
80114
}
81115
}
82116

117+
moved {
118+
from = cloudflare_device_posture_integration.set_integrations
119+
to = cloudflare_zero_trust_device_posture_integration.set_integrations
120+
}
121+
83122
# Pattern 5: count-based resources (at least 3)
84123
resource "cloudflare_zero_trust_device_posture_integration" "count_integrations" {
85124
count = 3
@@ -96,6 +135,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "count_integrations"
96135
}
97136
}
98137

138+
moved {
139+
from = cloudflare_device_posture_integration.count_integrations
140+
to = cloudflare_zero_trust_device_posture_integration.count_integrations
141+
}
142+
99143
# Pattern 6: Conditional resource creation (count with ternary)
100144
resource "cloudflare_zero_trust_device_posture_integration" "conditional" {
101145
count = var.enable_integrations ? 2 : 0
@@ -111,6 +155,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "conditional" {
111155
}
112156
}
113157

158+
moved {
159+
from = cloudflare_device_posture_integration.conditional
160+
to = cloudflare_zero_trust_device_posture_integration.conditional
161+
}
162+
114163
# Pattern 7: Cross-resource references
115164
resource "cloudflare_zero_trust_device_posture_integration" "primary" {
116165
account_id = var.cloudflare_account_id
@@ -126,6 +175,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "primary" {
126175
}
127176
}
128177

178+
moved {
179+
from = cloudflare_device_posture_integration.primary
180+
to = cloudflare_zero_trust_device_posture_integration.primary
181+
}
182+
129183
resource "cloudflare_zero_trust_device_posture_integration" "secondary" {
130184
# References the primary integration's name
131185
account_id = var.cloudflare_account_id
@@ -140,6 +194,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "secondary" {
140194
}
141195
}
142196

197+
moved {
198+
from = cloudflare_device_posture_integration.secondary
199+
to = cloudflare_zero_trust_device_posture_integration.secondary
200+
}
201+
143202
# Pattern 8: Lifecycle meta-arguments
144203
resource "cloudflare_zero_trust_device_posture_integration" "lifecycle_test" {
145204
account_id = var.cloudflare_account_id
@@ -161,6 +220,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "lifecycle_test" {
161220
}
162221
}
163222

223+
moved {
224+
from = cloudflare_device_posture_integration.lifecycle_test
225+
to = cloudflare_zero_trust_device_posture_integration.lifecycle_test
226+
}
227+
164228
resource "cloudflare_zero_trust_device_posture_integration" "prevent_destroy" {
165229
account_id = var.cloudflare_account_id
166230
name = "${local.integration_prefix}-prevent-destroy"
@@ -179,6 +243,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "prevent_destroy" {
179243
}
180244
}
181245

246+
moved {
247+
from = cloudflare_device_posture_integration.prevent_destroy
248+
to = cloudflare_zero_trust_device_posture_integration.prevent_destroy
249+
}
250+
182251
# Pattern 9: Terraform functions
183252
resource "cloudflare_zero_trust_device_posture_integration" "function_test" {
184253
account_id = var.cloudflare_account_id
@@ -194,6 +263,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "function_test" {
194263
}
195264
}
196265

266+
moved {
267+
from = cloudflare_device_posture_integration.function_test
268+
to = cloudflare_zero_trust_device_posture_integration.function_test
269+
}
270+
197271
# Additional edge cases
198272
resource "cloudflare_zero_trust_device_posture_integration" "minimal" {
199273
account_id = var.cloudflare_account_id
@@ -206,6 +280,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "minimal" {
206280
}
207281
}
208282

283+
moved {
284+
from = cloudflare_device_posture_integration.minimal
285+
to = cloudflare_zero_trust_device_posture_integration.minimal
286+
}
287+
209288
resource "cloudflare_zero_trust_device_posture_integration" "all_fields" {
210289
account_id = var.cloudflare_account_id
211290
name = "${local.integration_prefix}-all-fields"
@@ -224,6 +303,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "all_fields" {
224303
}
225304
}
226305

306+
moved {
307+
from = cloudflare_device_posture_integration.all_fields
308+
to = cloudflare_zero_trust_device_posture_integration.all_fields
309+
}
310+
227311
resource "cloudflare_zero_trust_device_posture_integration" "no_interval" {
228312
account_id = var.cloudflare_account_id
229313
name = "${local.integration_prefix}-no-interval"
@@ -236,6 +320,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "no_interval" {
236320
}
237321
}
238322

323+
moved {
324+
from = cloudflare_device_posture_integration.no_interval
325+
to = cloudflare_zero_trust_device_posture_integration.no_interval
326+
}
327+
239328
# Dynamic block example
240329
resource "cloudflare_zero_trust_device_posture_integration" "dynamic_test" {
241330
account_id = var.cloudflare_account_id
@@ -253,18 +342,7 @@ resource "cloudflare_zero_trust_device_posture_integration" "dynamic_test" {
253342
}
254343
}
255344

256-
# Total resource instances:
257-
# - map_integrations: 3 (workspace_one, crowdstrike, uptycs)
258-
# - set_integrations: 3 (intune, kolide, sentinelone_s2s)
259-
# - count_integrations: 3
260-
# - conditional: 2
261-
# - primary: 1
262-
# - secondary: 1
263-
# - lifecycle_test: 1
264-
# - prevent_destroy: 1
265-
# - function_test: 1
266-
# - minimal: 1
267-
# - all_fields: 1
268-
# - no_interval: 1
269-
# - dynamic_test: 1
270-
# TOTAL: 20 resource instances
345+
moved {
346+
from = cloudflare_device_posture_integration.dynamic_test
347+
to = cloudflare_zero_trust_device_posture_integration.dynamic_test
348+
}

integration/v4_to_v5/testdata/zero_trust_device_posture_integration/expected/device_posture_integration_e2e.tf

Lines changed: 74 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,31 @@ locals {
4242
e2e_prefix = "tf-e2e-migrate"
4343
}
4444

45+
46+
47+
48+
49+
50+
51+
52+
53+
54+
55+
# Summary of E2E Test Cases:
56+
# Total: 13 resource instances (1 + 1 + 1 + 1 + 2 + 2 + 2 + 1 + 1 + 1)
57+
#
58+
# Coverage:
59+
# - Deprecated resource name rename: 6 instances (deprecated_name, with_identifier, foreach_deprecated x2, primary, with_comments)
60+
# - Current resource name (no rename): 7 instances (current_name, no_interval, count_test x2, secondary, lifecycle_test)
61+
# - Identifier field removal: 1 instance (with_identifier)
62+
# - Different interval values: All instances (1h, 2h, 6h, 12h, 24h, 168h)
63+
# - Config block → attribute: All instances
64+
# - Count-based: 2 instances (count_test[0], count_test[1])
65+
# - for_each with map: 2 instances (foreach_deprecated["hourly"], foreach_deprecated["daily"])
66+
# - Cross-resource references: 2 instances (primary, secondary)
67+
# - Lifecycle meta-arguments: 1 instance (lifecycle_test)
68+
# - Comments preservation: 1 instance (with_comments)
69+
4570
# Test Case 1: Deprecated resource name with all fields
4671
# Tests: cloudflare_device_posture_integration → cloudflare_zero_trust_device_posture_integration rename
4772
# Tests: config block → attribute transformation
@@ -59,6 +84,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "deprecated_name" {
5984
}
6085
}
6186

87+
moved {
88+
from = cloudflare_device_posture_integration.deprecated_name
89+
to = cloudflare_zero_trust_device_posture_integration.deprecated_name
90+
}
91+
6292
# Test Case 2: Current resource name with all fields
6393
# Tests: No resource name change (already using current name)
6494
# Tests: config block → attribute transformation
@@ -76,6 +106,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "current_name" {
76106
}
77107
}
78108

109+
moved {
110+
from = cloudflare_device_posture_integration.current_name
111+
to = cloudflare_zero_trust_device_posture_integration.current_name
112+
}
113+
79114
# Test Case 3: Non-standard interval value
80115
# Tests: Various interval formats (not just 24h)
81116
# Tests: config block → attribute transformation
@@ -93,6 +128,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "no_interval" {
93128
}
94129
}
95130

131+
moved {
132+
from = cloudflare_device_posture_integration.no_interval
133+
to = cloudflare_zero_trust_device_posture_integration.no_interval
134+
}
135+
96136
# Test Case 4: With deprecated identifier field
97137
# Tests: identifier field is removed during migration
98138
# Tests: Deprecated resource name → current name
@@ -111,6 +151,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "with_identifier" {
111151
}
112152
}
113153

154+
moved {
155+
from = cloudflare_device_posture_integration.with_identifier
156+
to = cloudflare_zero_trust_device_posture_integration.with_identifier
157+
}
158+
114159
# Test Case 5: Count-based resources
115160
# Tests: Multiple resources with count
116161
# Tests: Different interval values
@@ -131,6 +176,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "count_test" {
131176
}
132177
}
133178

179+
moved {
180+
from = cloudflare_device_posture_integration.count_test
181+
to = cloudflare_zero_trust_device_posture_integration.count_test
182+
}
183+
134184
# Test Case 6: for_each with map
135185
# Tests: for_each with map iteration
136186
# Tests: Variable interval values
@@ -154,6 +204,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "foreach_deprecated"
154204
}
155205
}
156206

207+
moved {
208+
from = cloudflare_device_posture_integration.foreach_deprecated
209+
to = cloudflare_zero_trust_device_posture_integration.foreach_deprecated
210+
}
211+
157212
# Test Case 7: Cross-resource reference
158213
# Tests: References between resources work after migration
159214
# Tests: Deprecated name → current name for referenced resource
@@ -171,6 +226,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "primary" {
171226
}
172227
}
173228

229+
moved {
230+
from = cloudflare_device_posture_integration.primary
231+
to = cloudflare_zero_trust_device_posture_integration.primary
232+
}
233+
174234
resource "cloudflare_zero_trust_device_posture_integration" "secondary" {
175235
account_id = var.cloudflare_account_id
176236
name = "${cloudflare_zero_trust_device_posture_integration.primary.name}-secondary"
@@ -185,6 +245,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "secondary" {
185245
}
186246
}
187247

248+
moved {
249+
from = cloudflare_device_posture_integration.secondary
250+
to = cloudflare_zero_trust_device_posture_integration.secondary
251+
}
252+
188253
# Test Case 8: Lifecycle meta-arguments
189254
# Tests: Lifecycle blocks are preserved during migration
190255
# Tests: config block → attribute transformation with lifecycle
@@ -206,6 +271,11 @@ resource "cloudflare_zero_trust_device_posture_integration" "lifecycle_test" {
206271
}
207272
}
208273

274+
moved {
275+
from = cloudflare_device_posture_integration.lifecycle_test
276+
to = cloudflare_zero_trust_device_posture_integration.lifecycle_test
277+
}
278+
209279
# Test Case 9: Comments preservation
210280
# Tests: Comments are preserved during migration
211281
resource "cloudflare_zero_trust_device_posture_integration" "with_comments" {
@@ -224,17 +294,7 @@ resource "cloudflare_zero_trust_device_posture_integration" "with_comments" {
224294
}
225295
}
226296

227-
# Summary of E2E Test Cases:
228-
# Total: 13 resource instances (1 + 1 + 1 + 1 + 2 + 2 + 2 + 1 + 1 + 1)
229-
#
230-
# Coverage:
231-
# - Deprecated resource name rename: 6 instances (deprecated_name, with_identifier, foreach_deprecated x2, primary, with_comments)
232-
# - Current resource name (no rename): 7 instances (current_name, no_interval, count_test x2, secondary, lifecycle_test)
233-
# - Identifier field removal: 1 instance (with_identifier)
234-
# - Different interval values: All instances (1h, 2h, 6h, 12h, 24h, 168h)
235-
# - Config block → attribute: All instances
236-
# - Count-based: 2 instances (count_test[0], count_test[1])
237-
# - for_each with map: 2 instances (foreach_deprecated["hourly"], foreach_deprecated["daily"])
238-
# - Cross-resource references: 2 instances (primary, secondary)
239-
# - Lifecycle meta-arguments: 1 instance (lifecycle_test)
240-
# - Comments preservation: 1 instance (with_comments)
297+
moved {
298+
from = cloudflare_device_posture_integration.with_comments
299+
to = cloudflare_zero_trust_device_posture_integration.with_comments
300+
}

0 commit comments

Comments
 (0)