allow nil config attributes in ignore_changes
The validation for ignore_changes was too broad, and makes it difficult to ignore changes in an attribute that the user does not want to set. While the goal of ignore_changes is to prevent changes in the configuration alone, we don't intend to break the use-case of ignoring drift from the provider. Since we cannot easily narrow the validation to only detect computed attributes at the moment, we can drop this error altogether for now.
This commit is contained in:
parent
a413fa7425
commit
96b099cf35
|
@ -1752,50 +1752,6 @@ output "out" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext2Validate_invalidIgnoreChanges(t *testing.T) {
|
|
||||||
// validate module and output depends_on
|
|
||||||
m := testModuleInline(t, map[string]string{
|
|
||||||
"main.tf": `
|
|
||||||
resource "test_instance" "a" {
|
|
||||||
lifecycle {
|
|
||||||
ignore_changes = [foo]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
`,
|
|
||||||
})
|
|
||||||
|
|
||||||
p := testProvider("test")
|
|
||||||
p.GetSchemaReturn = &ProviderSchema{
|
|
||||||
ResourceTypes: map[string]*configschema.Block{
|
|
||||||
"test_instance": {
|
|
||||||
Attributes: map[string]*configschema.Attribute{
|
|
||||||
"id": {Type: cty.String, Computed: true},
|
|
||||||
"foo": {Type: cty.String, Computed: true, Optional: true},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := testContext2(t, &ContextOpts{
|
|
||||||
Config: m,
|
|
||||||
Providers: map[addrs.Provider]providers.Factory{
|
|
||||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
diags := ctx.Validate()
|
|
||||||
if !diags.HasErrors() {
|
|
||||||
t.Fatal("succeeded; want errors")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, d := range diags {
|
|
||||||
des := d.Description().Summary
|
|
||||||
if !strings.Contains(des, "Cannot ignore") {
|
|
||||||
t.Fatalf(`expected "Invalid depends_on reference", got %q`, des)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext2Validate_rpcDiagnostics(t *testing.T) {
|
func TestContext2Validate_rpcDiagnostics(t *testing.T) {
|
||||||
// validate module and output depends_on
|
// validate module and output depends_on
|
||||||
m := testModuleInline(t, map[string]string{
|
m := testModuleInline(t, map[string]string{
|
||||||
|
|
|
@ -127,6 +127,8 @@ func (n *EvalRefresh) Eval(ctx EvalContext) tfdiags.Diagnostics {
|
||||||
|
|
||||||
// We have no way to exempt provider using the legacy SDK from this check,
|
// We have no way to exempt provider using the legacy SDK from this check,
|
||||||
// so we can only log inconsistencies with the updated state values.
|
// so we can only log inconsistencies with the updated state values.
|
||||||
|
// In most cases these are not errors anyway, and represent "drift" from
|
||||||
|
// external changes which will be handled by the subsequent plan.
|
||||||
if errs := objchange.AssertObjectCompatible(schema, priorVal, resp.NewState); len(errs) > 0 {
|
if errs := objchange.AssertObjectCompatible(schema, priorVal, resp.NewState); len(errs) > 0 {
|
||||||
var buf strings.Builder
|
var buf strings.Builder
|
||||||
fmt.Fprintf(&buf, "[WARN] Provider %q produced an unexpected new value for %s during refresh.", n.ProviderAddr.Provider.String(), absAddr)
|
fmt.Fprintf(&buf, "[WARN] Provider %q produced an unexpected new value for %s during refresh.", n.ProviderAddr.Provider.String(), absAddr)
|
||||||
|
|
|
@ -362,39 +362,14 @@ func (n *EvalValidateResource) Validate(ctx EvalContext) error {
|
||||||
|
|
||||||
if cfg.Managed != nil { // can be nil only in tests with poorly-configured mocks
|
if cfg.Managed != nil { // can be nil only in tests with poorly-configured mocks
|
||||||
for _, traversal := range cfg.Managed.IgnoreChanges {
|
for _, traversal := range cfg.Managed.IgnoreChanges {
|
||||||
// This will error out if the traversal contains an invalid
|
// validate the ignore_changes traversals apply.
|
||||||
// index step. That is OK if we want users to be able to ignore
|
|
||||||
// a key that is no longer specified in the config.
|
|
||||||
moreDiags := schema.StaticValidateTraversal(traversal)
|
moreDiags := schema.StaticValidateTraversal(traversal)
|
||||||
diags = diags.Append(moreDiags)
|
diags = diags.Append(moreDiags)
|
||||||
if diags.HasErrors() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// first check to see if this assigned in the config
|
// TODO: we want to notify users that they can't use
|
||||||
v, _ := traversal.TraverseRel(configVal)
|
// ignore_changes for computed attributes, but we don't have an
|
||||||
if !v.IsNull() {
|
// easy way to correlate the config value, schema and
|
||||||
// it's assigned, so we can also assume it's not computed-only
|
// traversal together.
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can't ignore changes that don't exist in the configuration.
|
|
||||||
// We're not checking specifically if the traversal resolves to
|
|
||||||
// a computed-only value, but we can hint to the user that it
|
|
||||||
// might also be the case.
|
|
||||||
sourceRange := traversal.SourceRange()
|
|
||||||
diags = diags.Append(&hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Cannot ignore argument not set in the configuration",
|
|
||||||
Detail: fmt.Sprintf("The ignore_changes argument is not set in the configuration.\n" +
|
|
||||||
"The ignore_changes mechanism only applies to changes " +
|
|
||||||
"within the configuration, and must be used with " +
|
|
||||||
"arguments set in the configuration and not computed by " +
|
|
||||||
"the provider.",
|
|
||||||
),
|
|
||||||
Subject: &sourceRange,
|
|
||||||
})
|
|
||||||
return diags.Err()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue