diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index 8e0a069df5..6f2c78b197 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -11860,8 +11860,17 @@ resource "test_resource" "foo" { } resource "test_resource" "bar" { - value = test_resource.foo.sensitive_value + value = test_resource.foo.sensitive_value random = test_resource.foo.id # not sensitive + + nesting_single { + value = "abc" + sensitive_value = "xyz" + } +} + +resource "test_resource" "baz" { + value = test_resource.bar.nesting_single.sensitive_value } `, }) @@ -11906,6 +11915,12 @@ resource "test_resource" "bar" { t.Fatalf("there should only be 1 marked path for bar, there are %v", len(barChangeSrc.AfterValMarks)) } + bazAddr := mustResourceInstanceAddr("test_resource.baz") + bazChangeSrc := plan.Changes.ResourceInstance(bazAddr) + if len(bazChangeSrc.AfterValMarks) != 1 { + t.Fatalf("there should only be 1 marked path for baz, there are %v", len(bazChangeSrc.AfterValMarks)) + } + state, diags := ctx.Apply() if diags.HasErrors() { t.Fatalf("apply errors: %s", diags.Err()) diff --git a/terraform/context_test.go b/terraform/context_test.go index b223c2a1e0..dde3ec5e99 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -445,6 +445,15 @@ func testProviderSchema(name string) *ProviderSchema { }, Nesting: configschema.NestingSet, }, + "nesting_single": { + Block: configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "value": {Type: cty.String, Optional: true}, + "sensitive_value": {Type: cty.String, Optional: true, Sensitive: true}, + }, + }, + Nesting: configschema.NestingSingle, + }, }, }, name + "_ami_list": { diff --git a/terraform/evaluate.go b/terraform/evaluate.go index 950ee9fbcc..adfacc3f79 100644 --- a/terraform/evaluate.go +++ b/terraform/evaluate.go @@ -754,7 +754,7 @@ func (d *evaluationStateData) GetResource(addr addrs.Resource, rng tfdiags.Sourc // If our schema contains sensitive values, mark those as sensitive if schema.ContainsSensitive() { - val = markProviderSensitiveAttributes(schema, val, nil) + val = markProviderSensitiveAttributes(schema, val) } instances[key] = val continue @@ -776,7 +776,7 @@ func (d *evaluationStateData) GetResource(addr addrs.Resource, rng tfdiags.Sourc val := ios.Value // If our schema contains sensitive values, mark those as sensitive if schema.ContainsSensitive() { - val = markProviderSensitiveAttributes(schema, val, nil) + val = markProviderSensitiveAttributes(schema, val) } instances[key] = val } @@ -948,16 +948,43 @@ func moduleDisplayAddr(addr addrs.ModuleInstance) string { // markProviderSensitiveAttributes returns an updated value // where attributes that are Sensitive are marked -func markProviderSensitiveAttributes(schema *configschema.Block, val cty.Value, path cty.Path) cty.Value { +func markProviderSensitiveAttributes(schema *configschema.Block, val cty.Value) cty.Value { + return val.MarkWithPaths(getValMarks(schema, val, nil)) +} + +func getValMarks(schema *configschema.Block, val cty.Value, path cty.Path) []cty.PathValueMarks { var pvm []cty.PathValueMarks + for name, blockS := range schema.BlockTypes { + blockV := val.GetAttr(name) + blockPath := append(path, cty.GetAttrStep{Name: name}) + switch blockS.Nesting { + case configschema.NestingSingle, configschema.NestingGroup: + pvm = append(pvm, getValMarks(&blockS.Block, blockV, blockPath)...) + case configschema.NestingList: + for it := blockV.ElementIterator(); it.Next(); { + idx, blockEV := it.Element() + morePaths := getValMarks(&blockS.Block, blockEV, append(blockPath, cty.IndexStep{Key: idx})) + pvm = append(pvm, morePaths...) + } + case configschema.NestingMap: + // TODO + continue + case configschema.NestingSet: + // TODO + continue + default: + panic(fmt.Sprintf("unsupported nesting mode %s", blockS.Nesting)) + } + } + for name, attrS := range schema.Attributes { if attrS.Sensitive { - path := append(path, cty.GetAttrStep{Name: name}) + attrPath := append(path, cty.GetAttrStep{Name: name}) pvm = append(pvm, cty.PathValueMarks{ - Path: path, + Path: attrPath, Marks: cty.NewValueMarks("sensitive"), }) } } - return val.MarkWithPaths(pvm) + return pvm }