@@ -159,44 +159,102 @@ def run(self, dry_run, show_queries, on_failure, output_file=None):
159159 ignore_errors = True
160160
161161 #
162- # OPTIMIZED exists and state check - try exports first for happy path
162+ # State checking logic
163163 #
164164 exports_result_from_proxy = None # Track exports result if used as proxy
165165
166166 if createorupdate_query :
167+ # Skip all existence and state checks for createorupdate
167168 pass
168169 else :
169- # OPTIMIZATION: Try exports first if available for one-query solution
170- if exports_query :
170+ # Determine the validation strategy based on available queries
171+ if statecheck_query :
172+ #
173+ # Flow 1: Traditional flow when statecheck exists
174+ # exists → create/update → statecheck → exports
175+ #
176+ if exists_query :
177+ resource_exists = self .check_if_resource_exists (
178+ resource_exists ,
179+ resource ,
180+ full_context ,
181+ exists_query ,
182+ exists_retries ,
183+ exists_retry_delay ,
184+ dry_run ,
185+ show_queries
186+ )
187+ else :
188+ # Use statecheck as exists check
189+ is_correct_state = self .check_if_resource_is_correct_state (
190+ is_correct_state ,
191+ resource ,
192+ full_context ,
193+ statecheck_query ,
194+ statecheck_retries ,
195+ statecheck_retry_delay ,
196+ dry_run ,
197+ show_queries
198+ )
199+ resource_exists = is_correct_state
200+
201+ # Pre-deployment state check for existing resources
202+ if resource_exists and not is_correct_state :
203+ if resource .get ('skip_validation' , False ):
204+ self .logger .info (
205+ f"skipping validation for [{ resource ['name' ]} ] as skip_validation is set to true."
206+ )
207+ is_correct_state = True
208+ else :
209+ is_correct_state = self .check_if_resource_is_correct_state (
210+ is_correct_state ,
211+ resource ,
212+ full_context ,
213+ statecheck_query ,
214+ statecheck_retries ,
215+ statecheck_retry_delay ,
216+ dry_run ,
217+ show_queries
218+ )
219+
220+ elif exports_query :
221+ #
222+ # Flow 2: Optimized flow when only exports exists (no statecheck)
223+ # Try exports first with FAST FAIL (no retries)
224+ # If fails: exists → create/update → exports (with retries as statecheck)
225+ #
171226 self .logger .info (
172- f"🔄 trying exports query first for optimal single-query validation "
227+ f"🔄 trying exports query first (fast-fail) for optimal validation "
173228 f"for [{ resource ['name' ]} ]"
174229 )
175230 is_correct_state , exports_result_from_proxy = self .check_state_using_exports_proxy (
176231 resource ,
177232 full_context ,
178233 exports_query ,
179- exports_retries ,
180- exports_retry_delay ,
234+ 1 , # Fast fail: only 1 attempt
235+ 0 , # No delay
181236 dry_run ,
182237 show_queries
183238 )
184239 resource_exists = is_correct_state
185240
186- # If exports succeeded, we're done with validation for happy path
241+ # If exports succeeded, we're done with validation ( happy path)
187242 if is_correct_state :
188243 self .logger .info (
189- f"✅ [{ resource ['name' ]} ] validated successfully with single exports query"
244+ f"✅ [{ resource ['name' ]} ] validated successfully with fast exports query"
190245 )
191246 else :
192- # If exports failed, fall back to traditional exists check
247+ # Exports failed, fall back to exists check
193248 self .logger .info (
194- f"📋 exports validation failed, falling back to exists check "
249+ f"📋 fast exports validation failed, falling back to exists check "
195250 f"for [{ resource ['name' ]} ]"
196251 )
252+ # Clear the failed exports result
253+ exports_result_from_proxy = None
254+
197255 if exists_query :
198256 resource_exists = self .check_if_resource_exists (
199- False , # Reset this since exports failed
257+ False ,
200258 resource ,
201259 full_context ,
202260 exists_query ,
@@ -205,23 +263,14 @@ def run(self, dry_run, show_queries, on_failure, output_file=None):
205263 dry_run ,
206264 show_queries
207265 )
208- elif statecheck_query :
209- # statecheck can be used as an exists check fallback
210- is_correct_state = self .check_if_resource_is_correct_state (
211- False , # Reset this
212- resource ,
213- full_context ,
214- statecheck_query ,
215- statecheck_retries ,
216- statecheck_retry_delay ,
217- dry_run ,
218- show_queries
219- )
220- resource_exists = is_correct_state
221- # Reset is_correct_state since we need to re-validate after create/update
222- is_correct_state = False
266+ else :
267+ # No exists query, assume resource doesn't exist
268+ resource_exists = False
269+
223270 elif exists_query :
224- # Traditional path: exports not available, use exists
271+ #
272+ # Flow 3: Basic flow with only exists query
273+ #
225274 resource_exists = self .check_if_resource_exists (
226275 resource_exists ,
227276 resource ,
@@ -232,59 +281,12 @@ def run(self, dry_run, show_queries, on_failure, output_file=None):
232281 dry_run ,
233282 show_queries
234283 )
235- elif statecheck_query :
236- # statecheck can be used as an exists check
237- is_correct_state = self .check_if_resource_is_correct_state (
238- is_correct_state ,
239- resource ,
240- full_context ,
241- statecheck_query ,
242- statecheck_retries ,
243- statecheck_retry_delay ,
244- dry_run ,
245- show_queries
246- )
247- resource_exists = is_correct_state
248284 else :
249285 catch_error_and_exit (
250286 "iql file must include either 'exists', 'statecheck', or 'exports' anchor." ,
251287 self .logger
252288 )
253289
254- #
255- # state check with optimizations (only if we haven't already validated via exports)
256- #
257- if resource_exists and not is_correct_state and exports_result_from_proxy is None :
258- # bypass state check if skip_validation is set to true
259- if resource .get ('skip_validation' , False ):
260- self .logger .info (
261- f"skipping validation for [{ resource ['name' ]} ] as skip_validation is set to true."
262- )
263- is_correct_state = True
264- elif statecheck_query :
265- is_correct_state = self .check_if_resource_is_correct_state (
266- is_correct_state ,
267- resource ,
268- full_context ,
269- statecheck_query ,
270- statecheck_retries ,
271- statecheck_retry_delay ,
272- dry_run ,
273- show_queries
274- )
275- elif exports_query :
276- # This shouldn't happen since we tried exports first, but keeping for safety
277- self .logger .info (f"🔄 using exports query as proxy for statecheck for [{ resource ['name' ]} ]" )
278- is_correct_state , _ = self .check_state_using_exports_proxy (
279- resource ,
280- full_context ,
281- exports_query ,
282- exports_retries ,
283- exports_retry_delay ,
284- dry_run ,
285- show_queries
286- )
287-
288290 #
289291 # resource does not exist
290292 #
@@ -319,10 +321,11 @@ def run(self, dry_run, show_queries, on_failure, output_file=None):
319321 )
320322
321323 #
322- # check state again after create or update with optimizations
324+ # check state again after create or update
323325 #
324326 if is_created_or_updated :
325327 if statecheck_query :
328+ # Use statecheck for post-deploy validation
326329 is_correct_state = self .check_if_resource_is_correct_state (
327330 is_correct_state ,
328331 resource ,
@@ -334,17 +337,23 @@ def run(self, dry_run, show_queries, on_failure, output_file=None):
334337 show_queries ,
335338 )
336339 elif exports_query :
337- # OPTIMIZATION: Use exports as statecheck proxy for post-deploy validation
340+ # Use exports as statecheck proxy with proper retries
341+ # This handles the case where statecheck doesn't exist
338342 self .logger .info (
339- f"🔄 using exports query as proxy for post-deploy statecheck "
343+ f"🔄 using exports query as post-deploy statecheck "
340344 f"for [{ resource ['name' ]} ]"
341345 )
346+ # Need to determine retries: if we have statecheck config, use it
347+ # Otherwise fall back to exports config
348+ post_deploy_retries = statecheck_retries if statecheck_retries > 1 else exports_retries
349+ post_deploy_delay = statecheck_retry_delay if statecheck_retries > 1 else exports_retry_delay
350+
342351 is_correct_state , exports_result_from_proxy = self .check_state_using_exports_proxy (
343352 resource ,
344353 full_context ,
345354 exports_query ,
346- exports_retries ,
347- exports_retry_delay ,
355+ post_deploy_retries ,
356+ post_deploy_delay ,
348357 dry_run ,
349358 show_queries
350359 )
0 commit comments