Skip to content

Commit

Permalink
Merge pull request #35895 from hashicorp/jbardin/eval-self-postcondition
Browse files Browse the repository at this point in the history
don't error on eval of missing instances
  • Loading branch information
jbardin authored Oct 24, 2024
2 parents 39bd9b3 + 7a508a6 commit 0b1dfe2
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 9 deletions.
57 changes: 57 additions & 0 deletions internal/terraform/context_plan2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6011,3 +6011,60 @@ output "staying" {
t.Fatalf("unexpected changes: %s", diff)
}
}

func TestContext2Plan_multiInstanceSelfRef(t *testing.T) {
// The postcondition here references self, but because instances are
// processed concurrently some instances may not be registered yet during
// evaluation. This should still evaluate without error, because we know our
// self value exists.
m := testModuleInline(t, map[string]string{
"main.tf": `
resource "test_resource" "test" {
}
data "test_data_source" "foo" {
count = 100
lifecycle {
postcondition {
condition = self.attr == null
error_message = "error"
}
}
depends_on = [test_resource.test]
}
`,
})

p := new(testing_provider.MockProvider)
p.GetProviderSchemaResponse = getProviderSchemaResponseFromProviderSchema(&providerSchema{
DataSources: map[string]*configschema.Block{
"test_data_source": {
Attributes: map[string]*configschema.Attribute{
"attr": {
Type: cty.String,
Computed: true,
},
},
},
},
ResourceTypes: map[string]*configschema.Block{
"test_resource": {
Attributes: map[string]*configschema.Attribute{
"attr": {
Type: cty.String,
Computed: true,
},
},
},
},
})

ctx := testContext2(t, &ContextOpts{
Providers: map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
},
})

_, diags := ctx.Plan(m, states.NewState(), SimplePlanOpts(plans.NormalMode, testInputValuesUnset(m.Module.Variables)))
assertNoErrors(t, diags)
}
17 changes: 8 additions & 9 deletions internal/terraform/evaluate.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,15 +681,14 @@ func (d *evaluationStateData) GetResource(addr addrs.Resource, rng tfdiags.Sourc
// and need to be replaced by the planned value here.
if is.Current.Status == states.ObjectPlanned {
if change == nil {
// If the object is in planned status then we should not get
// here, since we should have found a pending value in the plan
// above instead.
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Missing pending object in plan",
Detail: fmt.Sprintf("Instance %s is marked as having a change pending but that change is not recorded in the plan. This is a bug in Terraform; please report it.", instAddr),
Subject: &config.DeclRange,
})
// FIXME: This is usually an unfortunate case where we need to
// lookup an individual instance referenced via "self" for
// postconditions which we know exists, but because evaluation
// must always get the resource in aggregate some instance
// changes may not yet be registered.
instances[key] = cty.DynamicVal
// log the problem for debugging, since it may be a legitimate error we can't catch
log.Printf("[WARN] instance %s is marked as having a change pending but that change is not recorded in the plan", instAddr)
continue
}
instances[key] = change.After
Expand Down

0 comments on commit 0b1dfe2

Please sign in to comment.