mirror of
https://github.com/hashicorp/terraform.git
synced 2026-05-28 04:03:27 -04:00
Support for deferred action invocations in plan
We encovered that deferred action invocations don't get provider addresses, which prevents us from loading the schema. That being said, I think it shouldn't be an issue, but will come back to revisit this as we build the support end to end. Add a test for deferred actions support
This commit is contained in:
parent
5b2f19abad
commit
ffeff0914d
4 changed files with 50 additions and 4 deletions
|
|
@ -207,6 +207,32 @@ func FromPlan(ctx context.Context, config *configs.Config, plan *plans.Plan, ref
|
|||
})
|
||||
}
|
||||
|
||||
// Handle deferred action invocations from the plan
|
||||
for _, deferredAction := range plan.DeferredActionInvocations {
|
||||
invocation := deferredAction.ActionInvocationInstanceSrc
|
||||
|
||||
if invocation == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// For deferred actions, the provider address is typically empty because
|
||||
// actions are deferred before being fully evaluated. We create the planned
|
||||
// change without schema since we can't fetch it without a provider address.
|
||||
plannedActionInvocation := PlannedChangeActionInvocationInstancePlanned{
|
||||
ActionInvocationAddr: stackaddrs.AbsActionInvocationInstance{
|
||||
Component: producer.Addr(),
|
||||
Item: invocation.Addr,
|
||||
},
|
||||
Invocation: invocation,
|
||||
Schema: providers.ActionSchema{}, // Empty schema for deferred actions
|
||||
ProviderConfigAddr: invocation.ProviderAddr, // Will be empty, that's expected
|
||||
}
|
||||
changes = append(changes, &PlannedChangeDeferredActionInvocation{
|
||||
DeferredReason: deferredAction.DeferredReason,
|
||||
ActionInvocationPlanned: plannedActionInvocation,
|
||||
})
|
||||
}
|
||||
|
||||
// We also need to catch any objects that exist in the "prior state"
|
||||
// but don't have any actions planned, since we still need to capture
|
||||
// the prior state part in case it was updated by refreshing during
|
||||
|
|
|
|||
|
|
@ -443,6 +443,8 @@ func plannedChangeSortKey(change stackplan.PlannedChange) string {
|
|||
return "function-results"
|
||||
case *stackplan.PlannedChangeActionInvocationInstancePlanned:
|
||||
return change.ActionInvocationAddr.String()
|
||||
case *stackplan.PlannedChangeDeferredActionInvocation:
|
||||
return "deferred:" + change.ActionInvocationPlanned.ActionInvocationAddr.String()
|
||||
default:
|
||||
// This is only going to happen during tests, so we can panic here.
|
||||
panic(fmt.Errorf("unrecognized planned change type: %T", change))
|
||||
|
|
|
|||
|
|
@ -6573,15 +6573,33 @@ func TestPlanWithDeferredActionInvocation(t *testing.T) {
|
|||
return plannedChangeSortKey(gotChanges[i]) < plannedChangeSortKey(gotChanges[j])
|
||||
})
|
||||
|
||||
// Find the deferred action invocation in the changes
|
||||
// First, let's verify the resource was actually deferred
|
||||
var foundDeferredResource bool
|
||||
var foundNormalActionInvocation bool
|
||||
var foundDeferredAction bool
|
||||
|
||||
for _, change := range gotChanges {
|
||||
if _, ok := change.(*stackplan.PlannedChangeDeferredActionInvocation); ok {
|
||||
switch c := change.(type) {
|
||||
case *stackplan.PlannedChangeDeferredResourceInstancePlanned:
|
||||
foundDeferredResource = true
|
||||
t.Logf("Found deferred resource: %s", c.ResourceInstancePlanned.ResourceInstanceObjectAddr)
|
||||
case *stackplan.PlannedChangeActionInvocationInstancePlanned:
|
||||
foundNormalActionInvocation = true
|
||||
t.Logf("Found normal action invocation: %s", c.ActionInvocationAddr)
|
||||
case *stackplan.PlannedChangeDeferredActionInvocation:
|
||||
foundDeferredAction = true
|
||||
break
|
||||
t.Logf("Found deferred action invocation: %s", c.ActionInvocationPlanned.ActionInvocationAddr)
|
||||
}
|
||||
}
|
||||
|
||||
if !foundDeferredResource {
|
||||
t.Error("Expected to find a deferred resource, but none was found")
|
||||
}
|
||||
|
||||
if foundNormalActionInvocation {
|
||||
t.Error("Action invocation should be deferred, not appearing as a normal invocation")
|
||||
}
|
||||
|
||||
if !foundDeferredAction {
|
||||
t.Error("Expected to find a deferred action invocation in the plan changes, but none was found")
|
||||
t.Logf("Got %d changes:", len(gotChanges))
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ variable "defer" {
|
|||
type = bool
|
||||
}
|
||||
|
||||
# Action that should be invoked when resource is created
|
||||
# Simple action
|
||||
action "testing_action" "notify" {
|
||||
config {
|
||||
message = "resource created with id ${var.id}"
|
||||
|
|
|
|||
Loading…
Reference in a new issue