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
17 changes: 15 additions & 2 deletions internal/terraform/context_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4536,15 +4536,28 @@ func TestContext2Plan_ignoreChanges(t *testing.T) {
func TestContext2Plan_ignoreChangesWildcard(t *testing.T) {
m := testModule(t, "plan-ignore-changes-wildcard")
p := testProvider("aws")
p.PlanResourceChangeFn = testDiffFn
p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) (resp providers.PlanResourceChangeResponse) {
// computed attributes should not be set in config
id := req.Config.GetAttr("id")
if !id.IsNull() {
t.Error("computed id set in plan config")
}

foo := req.Config.GetAttr("foo")
if foo.IsNull() {
t.Error(`missing "foo" during plan, was set to "bar" in state and config`)
}

return testDiffFn(req)
}

state := states.NewState()
root := state.EnsureModule(addrs.RootModuleInstance)
root.SetResourceInstanceCurrent(
mustResourceInstanceAddr("aws_instance.foo").Resource,
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
AttrsJSON: []byte(`{"id":"bar","ami":"ami-abcd1234","instance":"t2.micro","type":"aws_instance"}`),
AttrsJSON: []byte(`{"id":"bar","ami":"ami-abcd1234","instance":"t2.micro","type":"aws_instance","foo":"bar"}`),
},
mustProviderConfig(`provider["registry.terraform.io/hashicorp/aws"]`),
)
Expand Down
22 changes: 18 additions & 4 deletions internal/terraform/node_resource_abstract_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ func (n *NodeAbstractResourceInstance) plan(
// starting values.
// Here we operate on the marked values, so as to revert any changes to the
// marks as well as the value.
configValIgnored, ignoreChangeDiags := n.processIgnoreChanges(priorVal, origConfigVal)
configValIgnored, ignoreChangeDiags := n.processIgnoreChanges(priorVal, origConfigVal, schema)
diags = diags.Append(ignoreChangeDiags)
if ignoreChangeDiags.HasErrors() {
return plan, state, keyData, diags
Expand Down Expand Up @@ -881,7 +881,7 @@ func (n *NodeAbstractResourceInstance) plan(
// providers that we must accommodate the behavior for now, so for
// ignore_changes to work at all on these values, we will revert the
// ignored values once more.
plannedNewVal, ignoreChangeDiags = n.processIgnoreChanges(unmarkedPriorVal, plannedNewVal)
plannedNewVal, ignoreChangeDiags = n.processIgnoreChanges(unmarkedPriorVal, plannedNewVal, schema)
diags = diags.Append(ignoreChangeDiags)
if ignoreChangeDiags.HasErrors() {
return plan, state, keyData, diags
Expand Down Expand Up @@ -1145,7 +1145,7 @@ func (n *NodeAbstractResourceInstance) plan(
return plan, state, keyData, diags
}

func (n *NodeAbstractResource) processIgnoreChanges(prior, config cty.Value) (cty.Value, tfdiags.Diagnostics) {
func (n *NodeAbstractResource) processIgnoreChanges(prior, config cty.Value, schema *configschema.Block) (cty.Value, tfdiags.Diagnostics) {
// ignore_changes only applies when an object already exists, since we
// can't ignore changes to a thing we've not created yet.
if prior.IsNull() {
Expand All @@ -1158,9 +1158,23 @@ func (n *NodeAbstractResource) processIgnoreChanges(prior, config cty.Value) (ct
if len(ignoreChanges) == 0 && !ignoreAll {
return config, nil
}

if ignoreAll {
return prior, nil
// If we are trying to ignore all attribute changes, we must filter
// computed attributes out from the prior state to avoid sending them
// to the provider as if they were included in the configuration.
ret, _ := cty.Transform(prior, func(path cty.Path, v cty.Value) (cty.Value, error) {
attr := schema.AttributeByPath(path)
if attr != nil && attr.Computed && !attr.Optional {
return cty.NullVal(v.Type()), nil
}

return v, nil
})

return ret, nil
}

if prior.IsNull() || config.IsNull() {
// Ignore changes doesn't apply when we're creating for the first time.
// Proposed should never be null here, but if it is then we'll just let it be.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ variable "bar" {}
resource "aws_instance" "foo" {
ami = "${var.foo}"
instance = "${var.bar}"
foo = "bar"

lifecycle {
ignore_changes = all
Expand Down