Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package terraform for openSUSE:Factory checked in at 2022-01-27 23:16:52 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/terraform (Old) and /work/SRC/openSUSE:Factory/.terraform.new.1898 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "terraform" Thu Jan 27 23:16:52 2022 rev:30 rq:949386 version:1.1.4 Changes: -------- --- /work/SRC/openSUSE:Factory/terraform/terraform.changes 2022-01-11 21:24:15.317169233 +0100 +++ /work/SRC/openSUSE:Factory/.terraform.new.1898/terraform.changes 2022-01-27 23:18:29.078349023 +0100 @@ -1,0 +2,8 @@ +Fri Jan 21 09:11:46 UTC 2022 - Marcus Hann <mar...@hhra.uk> + +- Update to 1.1.4 + BUG FIXES: + * config: Non-nullable variables with null inputs were not given default values when checking validation statements (#30330) + * config: Terraform will no longer incorrectly report "Cross-package move statement" when an external package has changed a resource from no count to using count, or vice-versa. (#30333) + +------------------------------------------------------------------- Old: ---- terraform-1.1.3.obscpio terraform-1.1.3.tar.gz New: ---- terraform-1.1.4.obscpio terraform-1.1.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ terraform.spec ++++++ --- /var/tmp/diff_new_pack.riZrBd/_old 2022-01-27 23:18:32.490325451 +0100 +++ /var/tmp/diff_new_pack.riZrBd/_new 2022-01-27 23:18:32.498325395 +0100 @@ -17,7 +17,7 @@ Name: terraform -Version: 1.1.3 +Version: 1.1.4 Release: 0 Summary: Tool for building infrastructure safely and efficiently License: MPL-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.riZrBd/_old 2022-01-27 23:18:32.538325119 +0100 +++ /var/tmp/diff_new_pack.riZrBd/_new 2022-01-27 23:18:32.542325091 +0100 @@ -3,8 +3,8 @@ <param name="url">https://github.com/hashicorp/terraform</param> <param name="scm">git</param> <param name="filename">terraform</param> - <param name="versionformat">1.1.3</param> - <param name="revision">v1.1.3</param> + <param name="versionformat">1.1.4</param> + <param name="revision">v1.1.4</param> <param name="exclude">.git</param> </service> <service name="tar" mode="disabled"/> @@ -16,7 +16,7 @@ <param name="basename">terraform</param> </service> <service name="go_modules" mode="disabled"> - <param name="archive">terraform-1.1.3.tar.gz</param> + <param name="archive">terraform-1.1.4.tar.gz</param> </service> </services> ++++++ terraform-1.1.3.obscpio -> terraform-1.1.4.obscpio ++++++ /work/SRC/openSUSE:Factory/terraform/terraform-1.1.3.obscpio /work/SRC/openSUSE:Factory/.terraform.new.1898/terraform-1.1.4.obscpio differ: char 49, line 1 ++++++ terraform-1.1.3.tar.gz -> terraform-1.1.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/.github/workflows/build.yml new/terraform-1.1.4/.github/workflows/build.yml --- old/terraform-1.1.3/.github/workflows/build.yml 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/.github/workflows/build.yml 2022-01-19 19:27:01.000000000 +0100 @@ -147,8 +147,17 @@ env: GOOS: ${{ matrix.goos }} GOARCH: ${{ matrix.goarch }} + ACTIONSOS: ${{ matrix.runson }} run: | mkdir dist out + if [ "$ACTIONSOS" == "macos-latest" ] && [ "$GOOS" == "darwin" ]; then + # When building for macOS _on_ macOS we must force CGo to get + # correct hostname resolution behavior. (This must be conditional + # because other cross-compiles won't have suitable headers + # available to use CGo; darwin_amd64 has suitable headers to + # cross-build for darwin_arm64.) + export CGO_ENABLED=1 + fi go build -ldflags "-w -s" -o dist/ . zip -r -j out/${{ env.PKG_NAME }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip dist/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/CHANGELOG.md new/terraform-1.1.4/CHANGELOG.md --- old/terraform-1.1.3/CHANGELOG.md 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/CHANGELOG.md 2022-01-19 19:27:01.000000000 +0100 @@ -1,3 +1,10 @@ +## 1.1.4 (January 19, 2022) + +BUG FIXES: + +* config: Non-nullable variables with null inputs were not given default values when checking validation statements ([#30330](https://github.com/hashicorp/terraform/issues/30330)) +* config: Terraform will no longer incorrectly report "Cross-package move statement" when an external package has changed a resource from no `count` to using `count`, or vice-versa. ([#30333](https://github.com/hashicorp/terraform/issues/30333)) + ## 1.1.3 (January 06, 2022) BUG FIXES: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/internal/lang/funcs/filesystem.go new/terraform-1.1.4/internal/lang/funcs/filesystem.go --- old/terraform-1.1.3/internal/lang/funcs/filesystem.go 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/internal/lang/funcs/filesystem.go 2022-01-19 19:27:01.000000000 +0100 @@ -226,8 +226,30 @@ return cty.True.WithMarks(pathMarks), nil } - return cty.False, fmt.Errorf("%s is not a regular file, but %q", - redactIfSensitive(path, pathMarks), fi.Mode().String()) + // The Go stat API only provides convenient access to whether it's + // a directory or not, so we need to do some bit fiddling to + // recognize other irregular file types. + filename := redactIfSensitive(path, pathMarks) + fileType := fi.Mode().Type() + switch { + case (fileType & os.ModeDir) != 0: + err = function.NewArgErrorf(1, "%s is a directory, not a file", filename) + case (fileType & os.ModeDevice) != 0: + err = function.NewArgErrorf(1, "%s is a device node, not a regular file", filename) + case (fileType & os.ModeNamedPipe) != 0: + err = function.NewArgErrorf(1, "%s is a named pipe, not a regular file", filename) + case (fileType & os.ModeSocket) != 0: + err = function.NewArgErrorf(1, "%s is a unix domain socket, not a regular file", filename) + default: + // If it's not a type we recognize then we'll just return a + // generic error message. This should be very rare. + err = function.NewArgErrorf(1, "%s is not a regular file", filename) + + // Note: os.ModeSymlink should be impossible because we used + // os.Stat above, not os.Lstat. + } + + return cty.False, err }, }) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/internal/lang/funcs/filesystem_test.go new/terraform-1.1.4/internal/lang/funcs/filesystem_test.go --- old/terraform-1.1.3/internal/lang/funcs/filesystem_test.go 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/internal/lang/funcs/filesystem_test.go 2022-01-19 19:27:01.000000000 +0100 @@ -228,12 +228,12 @@ { cty.StringVal(""), cty.BoolVal(false), - `"." is not a regular file, but "drwxr-xr-x"`, + `"." is a directory, not a file`, }, { cty.StringVal("testdata").Mark(marks.Sensitive), cty.BoolVal(false), - `(sensitive value) is not a regular file, but "drwxr-xr-x"`, + `(sensitive value) is a directory, not a file`, }, { cty.StringVal("testdata/missing"), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/internal/refactoring/move_validate.go new/terraform-1.1.4/internal/refactoring/move_validate.go --- old/terraform-1.1.3/internal/refactoring/move_validate.go 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/internal/refactoring/move_validate.go 2022-01-19 19:27:01.000000000 +0100 @@ -55,27 +55,34 @@ _, toCallSteps := stmt.To.ModuleCallTraversals() modCfg := rootCfg.Descendent(stmtMod) - if pkgAddr := callsThroughModulePackage(modCfg, fromCallSteps); pkgAddr != nil { - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Cross-package move statement", - Detail: fmt.Sprintf( - "This statement declares a move from an object declared in external module package %q. Move statements can be only within a single module package.", - pkgAddr, - ), - Subject: stmt.DeclRange.ToHCL().Ptr(), - }) - } - if pkgAddr := callsThroughModulePackage(modCfg, toCallSteps); pkgAddr != nil { - diags = diags.Append(&hcl.Diagnostic{ - Severity: hcl.DiagError, - Summary: "Cross-package move statement", - Detail: fmt.Sprintf( - "This statement declares a move to an object declared in external module package %q. Move statements can be only within a single module package.", - pkgAddr, - ), - Subject: stmt.DeclRange.ToHCL().Ptr(), - }) + if !stmt.Implied { + // Implied statements can cross module boundaries because we + // generate them only for changing instance keys on a single + // resource. They happen to be generated _as if_ they were written + // in the root module, but the source and destination are always + // in the same module anyway. + if pkgAddr := callsThroughModulePackage(modCfg, fromCallSteps); pkgAddr != nil { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Cross-package move statement", + Detail: fmt.Sprintf( + "This statement declares a move from an object declared in external module package %q. Move statements can be only within a single module package.", + pkgAddr, + ), + Subject: stmt.DeclRange.ToHCL().Ptr(), + }) + } + if pkgAddr := callsThroughModulePackage(modCfg, toCallSteps); pkgAddr != nil { + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Cross-package move statement", + Detail: fmt.Sprintf( + "This statement declares a move to an object declared in external module package %q. Move statements can be only within a single module package.", + pkgAddr, + ), + Subject: stmt.DeclRange.ToHCL().Ptr(), + }) + } } for _, modInst := range declaredInsts.InstancesForModule(stmtMod) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/internal/refactoring/move_validate_test.go new/terraform-1.1.4/internal/refactoring/move_validate_test.go --- old/terraform-1.1.3/internal/refactoring/move_validate_test.go 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/internal/refactoring/move_validate_test.go 2022-01-19 19:27:01.000000000 +0100 @@ -366,6 +366,50 @@ }, WantError: `Cross-package move statement: This statement declares a move to an object declared in external module package "fake-external:///". Move statements can be only within a single module package.`, }, + "implied move from resource in another module package": { + Statements: []MoveStatement{ + makeTestImpliedMoveStmt(t, + ``, + `module.fake_external.test.thing`, + `test.thing`, + ), + }, + // Implied move statements are not subject to the cross-package restriction + WantError: ``, + }, + "implied move to resource in another module package": { + Statements: []MoveStatement{ + makeTestImpliedMoveStmt(t, + ``, + `test.thing`, + `module.fake_external.test.thing`, + ), + }, + // Implied move statements are not subject to the cross-package restriction + WantError: ``, + }, + "implied move from module call in another module package": { + Statements: []MoveStatement{ + makeTestImpliedMoveStmt(t, + ``, + `module.fake_external.module.a`, + `module.b`, + ), + }, + // Implied move statements are not subject to the cross-package restriction + WantError: ``, + }, + "implied move to module call in another module package": { + Statements: []MoveStatement{ + makeTestImpliedMoveStmt(t, + ``, + `module.a`, + `module.fake_external.module.b`, + ), + }, + // Implied move statements are not subject to the cross-package restriction + WantError: ``, + }, "move to a call that refers to another module package": { Statements: []MoveStatement{ makeTestMoveStmt(t, @@ -650,6 +694,13 @@ } } +func makeTestImpliedMoveStmt(t *testing.T, moduleStr, fromStr, toStr string) MoveStatement { + t.Helper() + ret := makeTestMoveStmt(t, moduleStr, fromStr, toStr) + ret.Implied = true + return ret +} + var fakeExternalModuleSource = addrs.ModuleSourceRemote{ PackageAddr: addrs.ModulePackage("fake-external:///"), } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/internal/states/instance_object.go new/terraform-1.1.4/internal/states/instance_object.go --- old/terraform-1.1.3/internal/states/instance_object.go 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/internal/states/instance_object.go 2022-01-19 19:27:01.000000000 +0100 @@ -1,6 +1,8 @@ package states import ( + "sort" + "github.com/zclconf/go-cty/cty" ctyjson "github.com/zclconf/go-cty/cty/json" @@ -108,6 +110,13 @@ return nil, err } + // Dependencies are collected and merged in an unordered format (using map + // keys as a set), then later changed to a slice (in random ordering) to be + // stored in state as an array. To avoid pointless thrashing of state in + // refresh-only runs, we can either override comparison of dependency lists + // (more desirable, but tricky for Reasons) or just sort when encoding. + sort.Slice(o.Dependencies, func(i, j int) bool { return o.Dependencies[i].String() < o.Dependencies[j].String() }) + return &ResourceInstanceObjectSrc{ SchemaVersion: schemaVersion, AttrsJSON: src, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/internal/states/instance_object_test.go new/terraform-1.1.4/internal/states/instance_object_test.go --- old/terraform-1.1.3/internal/states/instance_object_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/terraform-1.1.4/internal/states/instance_object_test.go 2022-01-19 19:27:01.000000000 +0100 @@ -0,0 +1,50 @@ +package states + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform/internal/addrs" + "github.com/zclconf/go-cty/cty" +) + +func TestResourceInstanceObject_encode(t *testing.T) { + value := cty.ObjectVal(map[string]cty.Value{ + "foo": cty.True, + }) + // The in-memory order of resource dependencies is random, since they're an + // unordered set. + depsOne := []addrs.ConfigResource{ + addrs.RootModule.Resource(addrs.ManagedResourceMode, "test", "honk"), + addrs.RootModule.Child("child").Resource(addrs.ManagedResourceMode, "test", "flub"), + addrs.RootModule.Resource(addrs.ManagedResourceMode, "test", "boop"), + } + depsTwo := []addrs.ConfigResource{ + addrs.RootModule.Child("child").Resource(addrs.ManagedResourceMode, "test", "flub"), + addrs.RootModule.Resource(addrs.ManagedResourceMode, "test", "boop"), + addrs.RootModule.Resource(addrs.ManagedResourceMode, "test", "honk"), + } + rioOne := &ResourceInstanceObject{ + Value: value, + Status: ObjectPlanned, + Dependencies: depsOne, + } + rioTwo := &ResourceInstanceObject{ + Value: value, + Status: ObjectPlanned, + Dependencies: depsTwo, + } + riosOne, err := rioOne.Encode(value.Type(), 0) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + riosTwo, err := rioTwo.Encode(value.Type(), 0) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + // However, identical sets of dependencies should always be written to state + // in an identical order, so we don't do meaningless state updates on refresh. + if diff := cmp.Diff(riosOne.Dependencies, riosTwo.Dependencies); diff != "" { + t.Errorf("identical dependencies got encoded in different orders:\n%s", diff) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/internal/terraform/context_validate_test.go new/terraform-1.1.4/internal/terraform/context_validate_test.go --- old/terraform-1.1.3/internal/terraform/context_validate_test.go 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/internal/terraform/context_validate_test.go 2022-01-19 19:27:01.000000000 +0100 @@ -2088,3 +2088,36 @@ t.Fatal(diags.ErrWithWarnings()) } } + +func TestContext2Validate_nonNullableVariableDefaultValidation(t *testing.T) { + m := testModuleInline(t, map[string]string{ + "main.tf": ` + module "first" { + source = "./mod" + input = null + } + `, + + "mod/main.tf": ` + variable "input" { + type = string + default = "default" + nullable = false + + // Validation expressions should receive the default with nullable=false and + // a null input. + validation { + condition = var.input != null + error_message = "Input cannot be null!" + } + } + `, + }) + + ctx := testContext2(t, &ContextOpts{}) + + diags := ctx.Validate(m) + if diags.HasErrors() { + t.Fatal(diags.ErrWithWarnings()) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/internal/terraform/node_module_variable.go new/terraform-1.1.4/internal/terraform/node_module_variable.go --- old/terraform-1.1.3/internal/terraform/node_module_variable.go 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/internal/terraform/node_module_variable.go 2022-01-19 19:27:01.000000000 +0100 @@ -233,6 +233,29 @@ scope := ctx.EvaluationScope(nil, moduleInstanceRepetitionData) val, diags := scope.EvalExpr(expr, cty.DynamicPseudoType) + // FIXME: This check is only necessary for v1.1, and is will never be + // present in the v1.2 branch. + // + // Default values are currently being handled in two places, the graph + // transformation where a synthetic default expression is created if there + // was no input expression, and in the evaluator when a reference to the + // variable is evaluated. Unfortunately neither of these covers the case + // where a non-nullable variable default needs to be checked within a + // validation statement + // + // Rather than try and fix the overall variable handling here, which runs + // the risk of encountering more unexpected behavior, we are going to fixup + // this one case to ensure a null value doesn't continue to slip into + // validation. A more extensive refactoring of variable handling has been + // completed in v1.2, and this code will only be relevant for the v1.1 + // branch. + if !diags.HasErrors() && val.IsNull() && + !n.Config.Nullable && + n.Config.Default != cty.NilVal && !n.Config.Default.IsNull() { + // replace the evaluated value with the actual default + val = n.Config.Default + } + // We intentionally passed DynamicPseudoType to EvalExpr above because // now we can do our own local type conversion and produce an error message // with better context if it fails. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/version/version.go new/terraform-1.1.4/version/version.go --- old/terraform-1.1.3/version/version.go 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/version/version.go 2022-01-19 19:27:01.000000000 +0100 @@ -11,7 +11,7 @@ ) // The main version number that is being run at the moment. -var Version = "1.1.3" +var Version = "1.1.4" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/website/docs/cli/state/index.mdx new/terraform-1.1.4/website/docs/cli/state/index.mdx --- old/terraform-1.1.3/website/docs/cli/state/index.mdx 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/website/docs/cli/state/index.mdx 2022-01-19 19:27:01.000000000 +0100 @@ -22,7 +22,7 @@ Terraform CLI supports several workflows for interacting with state: - [Inspecting State](/cli/state/inspect) -- [Forcing Re-creation (Tainting)](/cli/state/taint) +- [Forcing Re-creation](/cli/state/taint) - [Moving Resources](/cli/state/move) - Importing Pre-existing Resources (documented in the [Importing Infrastructure](/cli/import) section) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/website/docs/cli/state/move.mdx new/terraform-1.1.4/website/docs/cli/state/move.mdx --- old/terraform-1.1.3/website/docs/cli/state/move.mdx 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/website/docs/cli/state/move.mdx 2022-01-19 19:27:01.000000000 +0100 @@ -21,13 +21,22 @@ can explicitly tell Terraform to associate it with a different configured resource. +For most cases we recommend using +[the Terraform language's refactoring features](/language/modules/develop/refactoring) +to document in your module exactly how the resource names have changed over +time. Terraform will react to this information automatically during planning, +and thus users of your module will not need to take any unusual extra steps. + +> **Hands On:** Try the [Use Configuration to Move Resources](https://learn.hashicorp.com/tutorials/terraform/move-config) on HashiCorp Learn. + +There are some other situations which require explicit state modifications, +though. For those, consider the following Terraform commands: + - [The `terraform state mv` command](/cli/commands/state/mv) changes which resource address in your configuration is associated with a particular real-world object. Use this to preserve an object when renaming a resource, or when moving a resource into or out of a child module. - > **Hands On:** Try the [Use Configuration to Move Resources](https://learn.hashicorp.com/tutorials/terraform/move-config) on HashiCorp Learn. - - [The `terraform state rm` command](/cli/commands/state/rm) tells Terraform to stop managing a resource as part of the current working directory and workspace, _without_ destroying the corresponding real-world object. (You diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/website/docs/cli/state/taint.mdx new/terraform-1.1.4/website/docs/cli/state/taint.mdx --- old/terraform-1.1.3/website/docs/cli/state/taint.mdx 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/website/docs/cli/state/taint.mdx 2022-01-19 19:27:01.000000000 +0100 @@ -1,25 +1,63 @@ --- -page_title: Forcing Re-creation of Resources (Tainting) - Terraform CLI +page_title: Forcing Re-creation of Resources - Terraform CLI description: Commands that allow you to destroy and re-create resources manually. --- -# Forcing Re-creation of Resources (Tainting) +# Forcing Re-creation of Resources -When a resource declaration is modified, Terraform usually attempts to update -the existing resource in place (although some changes can require destruction -and re-creation, usually due to upstream API limitations). - -In some cases, you might want a resource to be destroyed and re-created even -when Terraform doesn't think it's necessary. This is usually for objects that -aren't fully described by their resource arguments due to side-effects that -happen during creation; for example, a virtual machine that configures itself -with `cloud-init` on startup might no longer meet your needs if the cloud-init -configuration changes. - -- [The `terraform taint` command](/cli/commands/taint) tells Terraform to - destroy and re-create a particular resource during the next apply, regardless - of whether its resource arguments would normally require that. - -- [The `terraform untaint` command](/cli/commands/untaint) undoes a - previous taint, or can preserve a resource that was automatically tainted due - to failed [provisioners](/language/resources/provisioners/syntax). +During planning, by default Terraform retrieves the latest state of each +existing object and compares it with the current configuration, planning +actions only against objects whose current state does not match the +configuration. + +However, in some cases a remote object may become damaged or degraded in a +way that Terraform cannot automatically detect. For example, if software +running inside a virtual machine crashes but the virtual machine itself is +still running then Terraform will typically have no way to detect and respond +to the problem, because Terraform only directly manages the machine as a whole. + +If you know that an object is damaged, or if you want to force Terraform to +replace it for any other reason, you can override Terraform's default behavior +using [the `-replace=...` planning option](/cli/commands/plan#replace-address) +when you run either `terraform plan` or `terraform apply`: + +```shellsession +$ terraform apply -replace=aws_instance.example +# ... + + # aws_instance.example will be replaced, as requested +-/+ resource "aws_instance" "example" { + # ... + } +``` + +## The "tainted" status + +Sometimes Terraform is able to infer automatically that an object is in an +incomplete or degraded state. For example, if creation of a complex object +fails in such a way that parts of it already exist in the remote system, or +if object creation succeeded but a provisioner step subsequently failed, +Terraform must remember that the object exists but may not be fully-functional. + +Terraform represents this situation by marking an object in the state as +"tainted". When an object is marked with this status, the next plan will force +replacing that object in a similar way to if you had specified that object's +address using `-replace=...` as described above. + +``` + # aws_instance.example is tainted, so must be replaced +-/+ resource "aws_instance" "example" { + # ... + } +``` + +If Terraform has marked an object as tainted but you consider it to be working +correctly and do not want to replace it, you can override Terraform's +determination using [the `terraform untaint` command](/cli/commands/untaint), +after which Terraform will consider the object to be ready for use by any +downstream resource declarations. + +You can also _force_ Terraform to mark a particular object as tainted using +[the `terraform taint` command](/cli/commands/taint), but that approach is +deprecated in favor of the `-replace=...` option, which avoids the need to +create an interim state snapshot with a tainted object. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/terraform-1.1.3/website/docs/language/resources/provisioners/salt-masterless.mdx new/terraform-1.1.4/website/docs/language/resources/provisioners/salt-masterless.mdx --- old/terraform-1.1.3/website/docs/language/resources/provisioners/salt-masterless.mdx 2022-01-06 22:20:50.000000000 +0100 +++ new/terraform-1.1.4/website/docs/language/resources/provisioners/salt-masterless.mdx 2022-01-19 19:27:01.000000000 +0100 @@ -47,28 +47,26 @@ Docker builder, you will likely want to pass `true` since `sudo` is often not pre-installed. - `remote_pillar_roots` (string) - The path to your remote [pillar - roots](http://docs.saltstack.com/ref/configuration/master.html#pillar-configuration). + roots](https://docs.saltproject.io/en/latest/ref/configuration/master.html#pillar-configuration). default: `/srv/pillar`. This option cannot be used with `minion_config`. - `remote_state_tree` (string) - The path to your remote [state - tree](http://docs.saltstack.com/ref/states/highstate.html#the-salt-state-tree). + tree](https://docs.saltproject.io/en/latest/ref/states/highstate.html#the-salt-state-tree). default: `/srv/salt`. This option cannot be used with `minion_config`. - `local_pillar_roots` (string) - The path to your local [pillar - roots](http://docs.saltstack.com/ref/configuration/master.html#pillar-configuration). + roots](https://docs.saltproject.io/en/latest/ref/configuration/master.html#pillar-configuration). This will be uploaded to the `remote_pillar_roots` on the remote. - `local_state_tree` (string) - The path to your local [state - tree](http://docs.saltstack.com/ref/states/highstate.html#the-salt-state-tree). + tree](https://docs.saltproject.io/en/latest/ref/states/highstate.html#the-salt-state-tree). This will be uploaded to the `remote_state_tree` on the remote. - `custom_state` (string) - A state to be run instead of `state.highstate`. Defaults to `state.highstate` if unspecified. - `minion_config_file` (string) - The path to your local [minion config - file](http://docs.saltstack.com/ref/configuration/minion.html). This will be - uploaded to the `/etc/salt` on the remote. This option overrides the - `remote_state_tree` or `remote_pillar_roots` options. + file](https://docs.saltproject.io/en/latest/ref/configuration/minion.html). This will be uploaded to the `/etc/salt` on the remote. This option overrides the `remote_state_tree` or `remote_pillar_roots` options. - `skip_bootstrap` (boolean) - By default the salt provisioner runs [salt bootstrap](https://github.com/saltstack/salt-bootstrap) to install salt. Set @@ -83,7 +81,7 @@ - `log_level` (string) - Set the logging level for the `salt-call` run. - `salt_call_args` (string) - Additional arguments to pass directly to `salt-call`. See - [salt-call](https://docs.saltstack.com/ref/cli/salt-call.html) documentation for more + [salt-call](https://docs.saltproject.io/en/latest/ref/cli/salt-call.html) documentation for more information. By default no additional arguments (besides the ones Terraform generates) are passed to `salt-call`. ++++++ terraform.obsinfo ++++++ --- /var/tmp/diff_new_pack.riZrBd/_old 2022-01-27 23:18:33.550318127 +0100 +++ /var/tmp/diff_new_pack.riZrBd/_new 2022-01-27 23:18:33.550318127 +0100 @@ -1,6 +1,6 @@ name: terraform -version: 1.1.3 -mtime: 1641504050 -commit: 65a995c7c94be748c91e703a9b02ebba8f295043 +version: 1.1.4 +mtime: 1642616821 +commit: 516295951ee07a4f47f1449a22a36a007accd380 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/terraform/vendor.tar.gz /work/SRC/openSUSE:Factory/.terraform.new.1898/vendor.tar.gz differ: char 5, line 1