terraform: shadow errors with UUID() must be ignored
People with `uuid()` usage in their configurations would receive shadow errors every time on plan because the UUID would change. This is hacky fix but I also believe correct: if a shadow error contains uuid() then we ignore the shadow error completely. This feels wrong but I'll explain why it is likely right: The "right" feeling solution is to create deterministic random output across graph runs. This would require using math/rand and seeding it with the same value each run. However, this alone probably won't work due to Terraform's parallelism and potential to call uuid() in different orders. In addition to this, you can't seed crypto/rand and its unlikely that we'll NEVER use crypto/rand in the future even if we switched uuid() to use math/rand. Therefore, the solution is simple: if there is no shadow error, no problem. If there is a shadow error and it contains uuid(), then ignore it.
This commit is contained in:
parent
9205d25d38
commit
aa5d16be79
|
@ -2010,6 +2010,25 @@ func TestContext2Plan_orphan(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This tests that configurations with UUIDs don't produce errors.
|
||||||
|
// For shadows, this would produce errors since a UUID changes every time.
|
||||||
|
func TestContext2Plan_shadowUuid(t *testing.T) {
|
||||||
|
m := testModule(t, "plan-shadow-uuid")
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext2(t, &ContextOpts{
|
||||||
|
Module: m,
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := ctx.Plan()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestContext2Plan_state(t *testing.T) {
|
func TestContext2Plan_state(t *testing.T) {
|
||||||
m := testModule(t, "plan-good")
|
m := testModule(t, "plan-good")
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
|
|
|
@ -2,6 +2,7 @@ package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/mitchellh/copystructure"
|
"github.com/mitchellh/copystructure"
|
||||||
|
@ -138,5 +139,17 @@ func (c *shadowContextCloser) CloseShadow() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *shadowContextCloser) ShadowError() error {
|
func (c *shadowContextCloser) ShadowError() error {
|
||||||
return c.Components.ShadowError()
|
err := c.Components.ShadowError()
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a sad edge case: if the configuration contains uuid() at
|
||||||
|
// any point, we cannot reason aboyt the shadow execution. Tested
|
||||||
|
// with Context2Plan_shadowUuid.
|
||||||
|
if strings.Contains(err.Error(), "uuid()") {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
resource "aws_instance" "test" {
|
||||||
|
value = "${uuid()}"
|
||||||
|
}
|
Loading…
Reference in New Issue