mirror of
https://github.com/hashicorp/terraform.git
synced 2026-06-09 08:58:34 -04:00
apply: include sensitive metadata when comparing changed input values (#37582)
* apply: include sensitive metadata when comparing changed input values * correct changelog entry
This commit is contained in:
parent
003edcf5a1
commit
00d680d819
4 changed files with 98 additions and 3 deletions
5
.changes/v1.13/BUG FIXES-20250910-095424.yaml
Normal file
5
.changes/v1.13/BUG FIXES-20250910-095424.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
kind: BUG FIXES
|
||||
body: 'apply: hide sensitive inputs when values have changed between plan and apply'
|
||||
time: 2025-09-10T09:54:24.889605+02:00
|
||||
custom:
|
||||
Issue: "37582"
|
||||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/hashicorp/terraform/internal/backend/backendrun"
|
||||
"github.com/hashicorp/terraform/internal/command/views"
|
||||
"github.com/hashicorp/terraform/internal/configs"
|
||||
"github.com/hashicorp/terraform/internal/lang/marks"
|
||||
"github.com/hashicorp/terraform/internal/logging"
|
||||
"github.com/hashicorp/terraform/internal/plans"
|
||||
"github.com/hashicorp/terraform/internal/states"
|
||||
|
|
@ -345,6 +346,14 @@ func (b *Local) opApply(
|
|||
Subject: rng,
|
||||
})
|
||||
} else {
|
||||
markedPlannedVar := plannedVar
|
||||
markedParsedVar := parsedVar.Value
|
||||
|
||||
if decl.Sensitive {
|
||||
markedPlannedVar = markedPlannedVar.Mark(marks.Sensitive)
|
||||
markedParsedVar = markedParsedVar.Mark(marks.Sensitive)
|
||||
}
|
||||
|
||||
// The user can't override the planned variables, so we
|
||||
// error when possible to avoid confusion.
|
||||
if parsedVar.Value.Equals(plannedVar).False() {
|
||||
|
|
@ -361,7 +370,7 @@ func (b *Local) opApply(
|
|||
"because a saved plan includes the variable values that were set when it was created. "+
|
||||
"The saved plan specifies %s as the value whereas during apply the value %s was %s. "+
|
||||
"To declare an ephemeral variable which is not saved in the plan file, use ephemeral = true.",
|
||||
varName, tfdiags.CompactValueStr(plannedVar), tfdiags.CompactValueStr(parsedVar.Value),
|
||||
varName, tfdiags.CompactValueStr(markedPlannedVar), tfdiags.CompactValueStr(markedParsedVar),
|
||||
parsedVar.SourceType.DiagnosticLabel()),
|
||||
Subject: rng,
|
||||
})
|
||||
|
|
@ -374,7 +383,7 @@ func (b *Local) opApply(
|
|||
"set when it was created. The saved plan specifies %s as the value whereas during apply "+
|
||||
"the value %s was %s. To declare an ephemeral variable which is not saved in the plan "+
|
||||
"file, use ephemeral = true.",
|
||||
varName, tfdiags.CompactValueStr(plannedVar), tfdiags.CompactValueStr(parsedVar.Value),
|
||||
varName, tfdiags.CompactValueStr(markedPlannedVar), tfdiags.CompactValueStr(markedParsedVar),
|
||||
parsedVar.SourceType.DiagnosticLabel()),
|
||||
Subject: rng,
|
||||
})
|
||||
|
|
@ -386,7 +395,7 @@ func (b *Local) opApply(
|
|||
panic(fmt.Sprintf("Attempted to change variable %s when applying a saved plan. "+
|
||||
"The saved plan specifies %s as the value whereas during apply the value %s was %s. "+
|
||||
"This is a bug in Terraform, please report it.",
|
||||
varName, tfdiags.CompactValueStr(plannedVar), tfdiags.CompactValueStr(parsedVar.Value),
|
||||
varName, tfdiags.CompactValueStr(markedPlannedVar), tfdiags.CompactValueStr(markedParsedVar),
|
||||
parsedVar.SourceType.DiagnosticLabel()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1053,6 +1053,78 @@ func TestApply_planWithEnvVars(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestApply_planWithSensitiveEnvVars(t *testing.T) {
|
||||
_, snap := testModuleWithSnapshot(t, "apply-sensitive-variable")
|
||||
plan := testPlan(t)
|
||||
|
||||
addr, diags := addrs.ParseAbsOutputValueStr("output.shadow")
|
||||
if diags.HasErrors() {
|
||||
t.Fatal(diags.Err())
|
||||
}
|
||||
|
||||
shadowVal := mustNewDynamicValue("noot", cty.DynamicPseudoType)
|
||||
plan.VariableValues = map[string]plans.DynamicValue{
|
||||
"shadow": shadowVal,
|
||||
}
|
||||
plan.Changes.Outputs = append(plan.Changes.Outputs, &plans.OutputChangeSrc{
|
||||
Addr: addr,
|
||||
ChangeSrc: plans.ChangeSrc{
|
||||
Action: plans.Create,
|
||||
After: shadowVal,
|
||||
},
|
||||
})
|
||||
planPath := testPlanFileMatchState(
|
||||
t,
|
||||
snap,
|
||||
states.NewState(),
|
||||
plan,
|
||||
statemgr.SnapshotMeta{},
|
||||
)
|
||||
|
||||
statePath := testTempFile(t)
|
||||
|
||||
p := applyFixtureProvider()
|
||||
view, done := testView(t)
|
||||
c := &ApplyCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(p),
|
||||
View: view,
|
||||
},
|
||||
}
|
||||
|
||||
t.Setenv("TF_VAR_shadow", "unique")
|
||||
|
||||
args := []string{
|
||||
"-state", statePath,
|
||||
"-no-color",
|
||||
planPath,
|
||||
}
|
||||
code := c.Run(args)
|
||||
output := done(t)
|
||||
if code != 0 {
|
||||
t.Fatal("unexpected failure: ", output.All())
|
||||
}
|
||||
|
||||
out := output.Stdout()
|
||||
|
||||
expectedWarn := "Warning: Ignoring variable when applying a saved plan\n"
|
||||
if !strings.Contains(out, expectedWarn) {
|
||||
t.Fatalf("expected warning in output, given: %q", out)
|
||||
}
|
||||
|
||||
if !strings.Contains(out, "(sensitive value)") {
|
||||
t.Error("should have elided sensitive value")
|
||||
}
|
||||
|
||||
if strings.Contains(out, "noot") {
|
||||
t.Error("should have elided sensitive input, but contained value")
|
||||
}
|
||||
|
||||
if strings.Contains(out, "unique") {
|
||||
t.Error("should have elided sensitive input, but contained value")
|
||||
}
|
||||
}
|
||||
|
||||
// A saved plan includes a list of "apply-time variables", i.e. ephemeral
|
||||
// input variables that were set during the plan, and must therefore be set
|
||||
// during apply. No other variables may be set during apply.
|
||||
|
|
|
|||
9
internal/command/testdata/apply-sensitive-variable/main.tf
vendored
Normal file
9
internal/command/testdata/apply-sensitive-variable/main.tf
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
variable "shadow" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
output "foo" {
|
||||
value = var.shadow
|
||||
sensitive = true
|
||||
}
|
||||
Loading…
Reference in a new issue