Skip to content

Commit 4644435

Browse files
committed
allow outputs without top-level ephemeral marks
There is currently no way to construct an output value which does not come directly from an ephemeral resource or input. Even if the constructed value is entirely composed of ephemeral attributes or elements, because there is no action to manually mark something as ephemeral (other than a variable block), the resulting value itself is not marked as ephemeral, and fails validation. Instead of strictly checking for an ephemeral mark on the output value, we can accept any value because the result will always be entirely ephemeral anyway. This mirrors the variable block behavior, which can accept any type of value as input, but is evaluated as ephemeral.
1 parent 10f3524 commit 4644435

File tree

2 files changed

+42
-12
lines changed

2 files changed

+42
-12
lines changed

internal/terraform/context_plan_ephemeral_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,47 @@ resource "ephem_write_only" "test" {
678678
},
679679
},
680680
},
681+
682+
"ad-hoc-ephemeral-output": {
683+
module: map[string]string{
684+
"child/main.tf": `
685+
output "value" {
686+
value = {
687+
applying = terraform.applying
688+
static = "test"
689+
}
690+
691+
// It's valid to assign any partially ephemeral value, the output will always be
692+
// entirely ephemeral.
693+
ephemeral = true
694+
}
695+
`,
696+
"main.tf": `
697+
module "child" {
698+
source = "./child"
699+
}
700+
701+
output "root" {
702+
// We expect a diagnostic here indicating that this value is ephemeral. This
703+
// ensures that the module output was valid and the ephemeral marks were
704+
// correctly re-applied during evaluation.
705+
value = module.child.value
706+
}
707+
`,
708+
},
709+
expectPlanDiagnostics: func(m *configs.Config) (diags tfdiags.Diagnostics) {
710+
return diags.Append(&hcl.Diagnostic{
711+
Severity: hcl.DiagError,
712+
Summary: "Ephemeral value not allowed",
713+
Detail: "This output value is not declared as returning an ephemeral value, so it cannot be set to a result derived from an ephemeral value.",
714+
Subject: &hcl.Range{
715+
Filename: filepath.Join(m.Module.SourceDir, "main.tf"),
716+
Start: hcl.Pos{Line: 10, Column: 13, Byte: 277},
717+
End: hcl.Pos{Line: 10, Column: 31, Byte: 295},
718+
},
719+
})
720+
},
721+
},
681722
} {
682723
t.Run(name, func(t *testing.T) {
683724
m := testModuleInline(t, tc.module)

internal/terraform/node_output.go

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -493,18 +493,7 @@ If you do intend to export this data, annotate the output value as sensitive by
493493
// "flagWarnOutputErrors", because they relate to features that were added
494494
// more recently than the historical change to treat invalid output values
495495
// as errors rather than warnings.
496-
if n.Config.Ephemeral && !marks.Has(val, marks.Ephemeral) {
497-
// An ephemeral output value must always be ephemeral
498-
// This is to prevent accidental persistence upstream
499-
// from here.
500-
diags = diags.Append(&hcl.Diagnostic{
501-
Severity: hcl.DiagError,
502-
Summary: "Value not allowed in ephemeral output",
503-
Detail: "This output value is declared as returning an ephemeral value, so it can only be set to an ephemeral value.",
504-
Subject: n.Config.Expr.Range().Ptr(),
505-
})
506-
return diags
507-
} else if !n.Config.Ephemeral && marks.Contains(val, marks.Ephemeral) {
496+
if !n.Config.Ephemeral && marks.Contains(val, marks.Ephemeral) {
508497
diags = diags.Append(&hcl.Diagnostic{
509498
Severity: hcl.DiagError,
510499
Summary: "Ephemeral value not allowed",

0 commit comments

Comments
 (0)