Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/v1.14/NEW FEATURES-20250903-131921.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: NEW FEATURES
body: "New top-level Actions block: Actions are provider defined and meant to codify use cases outside the normal CRUD model in your Terraform configuration. Providers can define Actions like `aws_lambda_invoke` or `aws_cloudfront_create_invalidation` that do something imparative outside of Terraforms normal CRUD model. You can configure such a side-effect with an action block and have actions triggered through the lifecycle of a resource or through passing the `-invoke` CLI flag."
time: 2025-09-03T13:19:21.097051+02:00
custom:
Issue: "37553"
11 changes: 1 addition & 10 deletions internal/command/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,11 @@ func (c *ApplyCommand) OperationRequest(
opReq.Type = backendrun.OperationTypeApply
opReq.View = view.Operation()
opReq.StatePersistInterval = c.Meta.StatePersistInterval()
opReq.ActionTargets = args.ActionTargets

// EXPERIMENTAL: maybe enable deferred actions
if c.AllowExperimentalFeatures {
opReq.DeferralAllowed = args.DeferralAllowed
opReq.ActionTargets = args.ActionTargets
} else if args.DeferralAllowed {
// Belated flag parse error, since we don't know about experiments
// support at actual parse time.
Expand All @@ -288,15 +288,6 @@ func (c *ApplyCommand) OperationRequest(
"The -allow-deferral flag is only valid in experimental builds of Terraform.",
))
return nil, diags
} else if len(args.ActionTargets) > 0 {
// Belated flag parse error, since we don't know about experiments
// support at actual parse time.
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
"Failed to parse command-line flags",
"The -invoke flag is only valid in experimental builds of Terraform.",
))
return nil, diags
}

var err error
Expand Down
11 changes: 1 addition & 10 deletions internal/command/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,11 @@ func (c *PlanCommand) OperationRequest(
opReq.ForceReplace = args.ForceReplace
opReq.Type = backendrun.OperationTypePlan
opReq.View = view.Operation()
opReq.ActionTargets = args.ActionTargets

// EXPERIMENTAL: maybe enable deferred actions
if c.AllowExperimentalFeatures {
opReq.DeferralAllowed = args.DeferralAllowed
opReq.ActionTargets = args.ActionTargets
} else if args.DeferralAllowed {
// Belated flag parse error, since we don't know about experiments
// support at actual parse time.
Expand All @@ -178,15 +178,6 @@ func (c *PlanCommand) OperationRequest(
"The -allow-deferral flag is only valid in experimental builds of Terraform.",
))
return nil, diags
} else if len(args.ActionTargets) > 0 {
// Belated flag parse error, since we don't know about experiments
// support at actual parse time.
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
"Failed to parse command-line flags",
"The -invoke flag is only valid in experimental builds of Terraform.",
))
return nil, diags
}

var err error
Expand Down
2 changes: 1 addition & 1 deletion internal/command/testdata/show-json-actions/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ resource "test_instance" "test" {
lifecycle {
action_trigger {
events = [before_create]
actions = [action.test_action.hello]
actions = [action.test_action.hello[0]]
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions internal/configs/parser_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,10 @@ func parseConfigFile(body hcl.Body, diags hcl.Diagnostics, override, allowExperi
}

case "action":
if allowExperiments {
cfg, cfgDiags := decodeActionBlock(block)
diags = append(diags, cfgDiags...)
if cfg != nil {
file.Actions = append(file.Actions, cfg)
}
cfg, cfgDiags := decodeActionBlock(block)
diags = append(diags, cfgDiags...)
if cfg != nil {
file.Actions = append(file.Actions, cfg)
}

default:
Expand Down
11 changes: 4 additions & 7 deletions internal/configs/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,11 @@ func decodeResourceBlock(block *hcl.Block, override bool, allowExperiments bool)
r.Postconditions = append(r.Postconditions, cr)
}

// decoded, but not yet used!
case "action_trigger":
if allowExperiments {
at, atDiags := decodeActionTriggerBlock(block)
diags = append(diags, atDiags...)
if at != nil {
r.Managed.ActionTriggers = append(r.Managed.ActionTriggers, at)
}
at, atDiags := decodeActionTriggerBlock(block)
diags = append(diags, atDiags...)
if at != nil {
r.Managed.ActionTriggers = append(r.Managed.ActionTriggers, at)
}

default:
Expand Down
2 changes: 1 addition & 1 deletion internal/configs/testdata/valid-files/actions.tf.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"test_object.a[count.index].test_string"
],
"action_trigger": {
"events": ["before_destroy"],
"events": ["before_create"],
"actions": ["action.test_action.a"]
}
}
Expand Down