@@ -292,6 +292,68 @@ func TestContext2Plan_filesystemFunctionImpureApply(t *testing.T) {
292292 }
293293}
294294
295+ // TestContext2Plan_templatefileWithImpureFunctions verifies that templatefile
296+ // works correctly when templates contain impure function calls like timestamp()
297+ // by marking templatefile as impure to defer evaluation until apply
298+ func TestContext2Plan_templatefileWithImpureFunctions (t * testing.T ) {
299+ m , snap := testModuleWithSnapshot (t , "templatefile-timestamp" )
300+
301+ p := testProvider ("test" )
302+
303+ ctx := testContext2 (t , & ContextOpts {
304+ Providers : map [addrs.Provider ]providers.Factory {
305+ addrs .NewDefaultProvider ("test" ): testProviderFuncFixed (p ),
306+ },
307+ })
308+
309+ // Plan should succeed with templatefile result showing as unknown
310+ plan , diags := ctx .Plan (m , states .NewState (), SimplePlanOpts (plans .NormalMode , testInputValuesUnset (m .Module .Variables )))
311+ tfdiags .AssertNoErrors (t , diags )
312+
313+ // The output should be unknown during plan since templatefile is now marked as impure
314+ outChangeSrc := plan .Changes .OutputValue (addrs .RootModuleInstance .OutputValue ("result" ))
315+ if outChangeSrc == nil {
316+ t .Fatal ("expected output change to exist" )
317+ }
318+ outChange , err := outChangeSrc .Decode ()
319+ if err != nil {
320+ t .Fatalf ("failed to decode output change: %s" , err )
321+ }
322+ if outChange .After .IsKnown () {
323+ t .Fatalf ("expected templatefile result to be unknown during plan, got: %#v" , outChange .After )
324+ }
325+
326+ // Write / Read plan to simulate running it through a Plan file
327+ ctxOpts , m , plan , err := contextOptsForPlanViaFile (t , snap , plan )
328+ if err != nil {
329+ t .Fatalf ("failed to round-trip through planfile: %s" , err )
330+ }
331+
332+ ctxOpts .Providers = map [addrs.Provider ]providers.Factory {
333+ addrs .NewDefaultProvider ("test" ): testProviderFuncFixed (p ),
334+ }
335+ ctx = testContext2 (t , ctxOpts )
336+
337+ // Apply should succeed - no "inconsistent result" error even though
338+ // timestamp() will return different values
339+ state , diags := ctx .Apply (plan , m , nil )
340+ tfdiags .AssertNoErrors (t , diags )
341+
342+ // The output should now be known and contain a timestamp
343+ outputVal := state .OutputValue (addrs .RootModuleInstance .OutputValue ("result" ))
344+ if outputVal == nil {
345+ t .Fatal ("expected output to exist" )
346+ }
347+ if ! outputVal .Value .IsKnown () {
348+ t .Fatal ("expected output to be known after apply" )
349+ }
350+
351+ result := outputVal .Value .AsString ()
352+ if ! strings .Contains (result , "Generated at:" ) {
353+ t .Fatalf ("expected output to contain timestamp, got: %s" , result )
354+ }
355+ }
356+
295357func TestContext2Validate_providerFunctionDiagnostics (t * testing.T ) {
296358 provider := & testing_provider.MockProvider {
297359 GetProviderSchemaResponse : & providers.GetProviderSchemaResponse {
0 commit comments