mirror of
https://github.com/hashicorp/terraform.git
synced 2026-06-09 00:42:48 -04:00
ephemeral: tests for setting unplanned vars during apply
This commit is contained in:
parent
fa44937977
commit
3207836729
2 changed files with 106 additions and 20 deletions
|
|
@ -328,35 +328,30 @@ func (b *Local) opApply(
|
|||
applyTimeValues[varName] = val
|
||||
} else {
|
||||
// If a non-ephemeral variable is set differently between plan and apply, we should emit a diagnostic.
|
||||
value, ok := plan.VariableValues[varName]
|
||||
plannedVariableValue, ok := plan.VariableValues[varName]
|
||||
if !ok {
|
||||
if v.Value.IsNull() {
|
||||
continue
|
||||
} else {
|
||||
// TODO: Add test for this case
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Can't set variable when applying a saved plan",
|
||||
Detail: fmt.Sprintf("The variable %s cannot be set using the -var and -var-file options when applying a saved plan file, because a saved plan includes the variable values that were set when it was created. To declare an ephemeral variable which is not saved in the plan file, use ephemeral = true.", varName),
|
||||
Subject: rng,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
val, err := value.Decode(cty.DynamicPseudoType)
|
||||
if err != nil {
|
||||
// TODO: Reword error message
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Variable was set with a different type when applying a saved plan",
|
||||
Detail: fmt.Sprintf("The variable %s was set to a different type of value during plan than during apply. Please either don't supply the value or supply the same value if the variable.", varName),
|
||||
Summary: "Can't set variable when applying a saved plan",
|
||||
Detail: fmt.Sprintf("The variable %s cannot be set using the -var and -var-file options when applying a saved plan file, because it is neither ephemeral nor has it been declared during the plan operation. To declare an ephemeral variable which is not saved in the plan file, use ephemeral = true.", varName),
|
||||
Subject: rng,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
val, err := plannedVariableValue.Decode(cty.DynamicPseudoType)
|
||||
if err != nil {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Could not decode variable value from plan",
|
||||
Detail: fmt.Sprintf("The variable %s could not be decoded from the plan. %s. This is a bug in Terraform, please report it.", varName, err),
|
||||
Subject: rng,
|
||||
})
|
||||
} else {
|
||||
if v.Value.Equals(val) == cty.False {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Can't set variable when applying a saved plan",
|
||||
Summary: "Can't change variable when applying a saved plan",
|
||||
Detail: fmt.Sprintf("The variable %s cannot be set using the -var and -var-file options when applying a saved plan file, 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, viewsjson.CompactValueStr(v.Value), viewsjson.CompactValueStr(val), v.SourceType.DiagnosticLabel()),
|
||||
Subject: rng,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -860,6 +860,7 @@ func TestApply_planWithVarFile(t *testing.T) {
|
|||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// The value of foo is the same as in the var file
|
||||
planPath := applyFixturePlanFileWithVariableValue(t, "bar")
|
||||
statePath := testTempFile(t)
|
||||
|
||||
|
|
@ -901,6 +902,96 @@ func TestApply_planWithVarFile(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestApply_planWithVarFilePreviouslyUnset(t *testing.T) {
|
||||
varFileDir := testTempDir(t)
|
||||
varFilePath := filepath.Join(varFileDir, "terraform.tfvars")
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(applyVarFile), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// The value of foo is not set
|
||||
planPath := applyFixturePlanFile(t)
|
||||
statePath := testTempFile(t)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(varFileDir); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
|
||||
p := applyFixtureProvider()
|
||||
view, done := testView(t)
|
||||
c := &ApplyCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(p),
|
||||
View: view,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-state-out", statePath,
|
||||
planPath,
|
||||
}
|
||||
code := c.Run(args)
|
||||
output := done(t)
|
||||
if code == 0 {
|
||||
t.Fatalf("expected to fail, but succeeded. \n\n%s", output.All())
|
||||
}
|
||||
|
||||
expectedTitle := "Can't set variable when applying a saved plan"
|
||||
if !strings.Contains(output.Stderr(), expectedTitle) {
|
||||
t.Fatalf("Expected stderr to contain %q, got %q", expectedTitle, output.Stderr())
|
||||
}
|
||||
}
|
||||
|
||||
func TestApply_planWithVarFileChangingVariableValue(t *testing.T) {
|
||||
varFileDir := testTempDir(t)
|
||||
varFilePath := filepath.Join(varFileDir, "terraform.tfvars")
|
||||
if err := ioutil.WriteFile(varFilePath, []byte(applyVarFile), 0644); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// The value of foo is differnet from the var file
|
||||
planPath := applyFixturePlanFileWithVariableValue(t, "lorem ipsum")
|
||||
statePath := testTempFile(t)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if err := os.Chdir(varFileDir); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
defer os.Chdir(cwd)
|
||||
|
||||
p := applyFixtureProvider()
|
||||
view, done := testView(t)
|
||||
c := &ApplyCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(p),
|
||||
View: view,
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-state-out", statePath,
|
||||
planPath,
|
||||
}
|
||||
code := c.Run(args)
|
||||
output := done(t)
|
||||
if code == 0 {
|
||||
t.Fatalf("expected to fail, but succeeded. \n\n%s", output.All())
|
||||
}
|
||||
|
||||
expectedTitle := "Can't change variable when applying a saved plan"
|
||||
if !strings.Contains(output.Stderr(), expectedTitle) {
|
||||
t.Fatalf("Expected stderr to contain %q, got %q", expectedTitle, output.Stderr())
|
||||
}
|
||||
}
|
||||
|
||||
func TestApply_planVars(t *testing.T) {
|
||||
// This test ensures that it isn't allowed to set non-ephemeral input
|
||||
// variables when applying from a saved plan file, since in that case the
|
||||
|
|
|
|||
Loading…
Reference in a new issue