diff --git a/internal/terraform/context_plan_actions_test.go b/internal/terraform/context_plan_actions_test.go index 2dfd0854c196..8758f4254ae7 100644 --- a/internal/terraform/context_plan_actions_test.go +++ b/internal/terraform/context_plan_actions_test.go @@ -1351,6 +1351,52 @@ resource "test_object" "a" { }, }, + "ephemeral values": { + module: map[string]string{ + "main.tf": ` +variable "secret" { + type = string + ephemeral = true +} +action "test_action" "hello" { + config { + attr = var.secret + } +} +resource "test_object" "a" { + lifecycle { + action_trigger { + events = [before_create] + actions = [action.test_action.hello] + } + } +} +`, + }, + planOpts: &PlanOpts{ + Mode: plans.NormalMode, + SetVariables: InputValues{ + "secret": &InputValue{ + Value: cty.StringVal("secret"), + SourceType: ValueFromCLIArg, + }}, + }, + expectPlanActionCalled: false, + assertValidateDiagnostics: func(t *testing.T, diags tfdiags.Diagnostics) { + if len(diags) != 1 { + t.Fatalf("expected exactly 1 diagnostic but had %d", len(diags)) + } + + if diags[0].Severity() != tfdiags.Error { + t.Error("expected error diagnostic") + } + + if diags[0].Description().Summary != "Invalid use of ephemeral value" { + t.Errorf("expected diagnostics to be because of ephemeral values but was %s", diags[0].Description().Summary) + } + }, + }, + "write-only attributes": { module: map[string]string{ "main.tf": ` diff --git a/internal/terraform/node_action_instance.go b/internal/terraform/node_action_instance.go index cec79da1d564..cfcc89338d7b 100644 --- a/internal/terraform/node_action_instance.go +++ b/internal/terraform/node_action_instance.go @@ -64,7 +64,14 @@ func (n *NodeActionDeclarationInstance) Execute(ctx EvalContext, _ walkOperation configVal, _, configDiags = ctx.EvaluateBlock(n.Config.Config, n.Schema.ConfigSchema.DeepCopy(), nil, keyData) diags = diags.Append(configDiags) - if diags.HasErrors() { + if configDiags.HasErrors() { + return diags + } + + valDiags := validateResourceForbiddenEphemeralValues(ctx, configVal, n.Schema.ConfigSchema) + diags = diags.Append(valDiags.InConfigBody(n.Config.Config, n.Addr.String())) + + if valDiags.HasErrors() { return diags } } diff --git a/internal/terraform/node_action_validate.go b/internal/terraform/node_action_validate.go index 8c36de6309ec..f80e2e204b6c 100644 --- a/internal/terraform/node_action_validate.go +++ b/internal/terraform/node_action_validate.go @@ -102,6 +102,9 @@ func (n *NodeValidatableAction) Execute(ctx EvalContext, _ walkOperation) tfdiag } } + valDiags = validateResourceForbiddenEphemeralValues(ctx, configVal, schema.ConfigSchema) + diags = diags.Append(valDiags.InConfigBody(config, n.Addr.String())) + // Use unmarked value for validate request unmarkedConfigVal, _ := configVal.UnmarkDeep() log.Printf("[TRACE] Validating config for %q", n.Addr)