hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.42k stars 9.51k forks source link

Local expressions evaluated too early #20749

Closed salikov1809 closed 4 years ago

salikov1809 commented 5 years ago

Terraform Version

Terraform v0.11.13
+ provider.null v2.1.0

Shell script to reproduce the issue

cat <<"EOF" >./main.tf
data "null_data_source" "test" {
  inputs = {
    a = "1"
  }
}

locals {
  foo = "${data.null_data_source.test.outputs["a"]}"
}

output "result" {
  value = "${local.foo}"
}
EOF

terraform init
# The following apply will output "result = 1" as expected
terraform apply

# Add extra "b" key to the null_data_source.test outputs
cat <<"EOF" >./main.tf
data "null_data_source" "test" {
  inputs = {
    a = "1"
    b = "2"
  }
}

locals {
  foo = "${data.null_data_source.test.outputs["b"]}"
}

output "result" {
  value = "${local.foo}"
}
EOF

# The following apply will return an error
terraform apply

Expected Behavior

Terraform should output result = 2

Actual Behavior

An error is thrown:

Error: Error asking for user input: 1 error(s) occurred:

* local.foo: local.foo: key "b" does not exist in map data.null_data_source.test.outputs in:

${data.null_data_source.test.outputs["b"]}

Additional Context

output "result" { value = "${data.null_data_source.test.outputs["b"]}" }


- This issue does not occur with Terraform 0.12-beta1
Emptyless commented 5 years ago

I'm running the 0.11.14-dev version where the issue still remains. I've attached the debug log. I'll try to see if I can be of any help resolving it.

GOROOT=/usr/local/Cellar/go/1.11.5/libexec #gosetup
GOPATH=/Users/[redacted]/go #gosetup
/usr/local/Cellar/go/1.11.5/libexec/bin/go build -o terraform /Users/[redacted]/go/src/github.com/hashicorp/terraform/checkpoint.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/commands.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/config_unix.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/version.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/synchronized_writers.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/signal_unix.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/plugins.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/panic.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/main.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/help.go /Users/[redacted]/go/src/github.com/hashicorp/terraform/config.go #gosetup
/Users/[redacted]/go/src/github.com/hashicorp/terraform/pkg/terraform apply #gosetup
2019/03/28 17:13:30 [INFO] Terraform version: 0.11.14 dev 
2019/03/28 17:13:30 [INFO] Go runtime version: go1.11.5
2019/03/28 17:13:30 [INFO] CLI args: []string{"/Users/[redacted]/go/src/github.com/hashicorp/terraform/pkg/terraform", "apply"}
2019/03/28 17:13:30 [DEBUG] Attempting to open CLI config file: /Users/[redacted]/.terraformrc
2019/03/28 17:13:30 [DEBUG] File doesn't exist, but doesn't need to. Ignoring.
2019/03/28 17:13:30 [INFO] CLI command args: []string{"apply"}
2019/03/28 17:13:30 [INFO] command: empty terraform config, returning nil
2019/03/28 17:13:30 [DEBUG] command: no data state file found for backend config
2019/03/28 17:13:30 [DEBUG] New state was assigned lineage "913b0d29-1a59-0376-bad1-55ddbd76dd5e"
2019/03/28 17:13:30 [INFO] command: backend initialized: <nil>
2019/03/28 17:13:30 [DEBUG] checking for provider in "."
2019/03/28 17:13:30 [DEBUG] checking for provider in "/Users/[redacted]/go/src/github.com/hashicorp/terraform/pkg"
2019/03/28 17:13:30 [DEBUG] checking for provider in ".terraform/plugins/darwin_amd64"
2019/03/28 17:13:30 [DEBUG] found provider "terraform-provider-null_v2.1.0_x4"
2019/03/28 17:13:30 [DEBUG] found valid plugin: "null", "2.1.0", "/Users/[redacted]/go/src/github.com/hashicorp/terraform/pkg/.terraform/plugins/darwin_amd64/terraform-provider-null_v2.1.0_x4"
2019/03/28 17:13:30 [DEBUG] checking for provisioner in "."
2019/03/28 17:13:30 [DEBUG] checking for provisioner in "/Users/[redacted]/go/src/github.com/hashicorp/terraform/pkg"
2019/03/28 17:13:30 [DEBUG] checking for provisioner in ".terraform/plugins/darwin_amd64"
2019/03/28 17:13:30 [INFO] command: backend <nil> is not enhanced, wrapping in local
2019/03/28 17:13:30 [INFO] backend/local: starting Apply operation
2019/03/28 17:13:30 [TRACE] Preserving existing state lineage "18de2fd3-7625-be26-6ed6-f5126a97dc00"
2019/03/28 17:13:30 [TRACE] Preserving existing state lineage "18de2fd3-7625-be26-6ed6-f5126a97dc00"
2019/03/28 17:13:30 [INFO] terraform: building graph: GraphTypeInput
2019/03/28 17:13:30 [TRACE] ConfigTransformer: Starting for path: []
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.ConfigTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.LocalTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
local.foo - *terraform.NodeLocal
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.OutputTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.OrphanResourceTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.OrphanOutputTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
2019/03/28 17:13:30 [TRACE] AttachResourceConfigTransformer: Beginning...
2019/03/28 17:13:30 [TRACE] AttachResourceConfigTransformer: Attach resource config request: data.null_data_source.test
2019/03/28 17:13:30 [TRACE] Attaching resource config: &config.Resource{Mode:1, Name:"test", Type:"null_data_source", RawCount:(*config.RawConfig)(0xc0003be700), RawConfig:(*config.RawConfig)(0xc0003be690), Provisioners:[]*config.Provisioner{}, Provider:"", DependsOn:[]string(nil), Lifecycle:config.ResourceLifecycle{CreateBeforeDestroy:false, PreventDestroy:false, IgnoreChanges:[]string(nil)}}
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.AttachResourceConfigTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
2019/03/28 17:13:30 [DEBUG] Attaching resource state to "data.null_data_source.test": &terraform.ResourceState{Type:"null_data_source", Dependencies:[]string{}, Primary:(*terraform.InstanceState)(0xc0000db590), Deposed:[]*terraform.InstanceState{}, Provider:"provider.null", mu:sync.Mutex{state:0, sema:0x0}}
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.AttachStateTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.RootVariableTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
2019/03/28 17:13:30 [TRACE] ProviderConfigTransformer: Starting for path: []
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.ProviderConfigTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
2019/03/28 17:13:30 [DEBUG] adding missing provider: null
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.MissingProviderTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [DEBUG] resource data.null_data_source.test using provider provider.null
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.ProviderTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.PruneProviderTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.ParentProviderTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.graphTransformerMulti:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.ModuleVariableTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.RemovedModuleTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
output.result - *terraform.NodeApplyableOutput
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [DEBUG] ReferenceTransformer: "data.null_data_source.test" references: []
2019/03/28 17:13:30 [DEBUG] ReferenceTransformer: "local.foo" references: [data.null_data_source.test]
2019/03/28 17:13:30 [DEBUG] ReferenceTransformer: "output.result" references: [local.foo]
2019/03/28 17:13:30 [DEBUG] ReferenceTransformer: "provider.null" references: []
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.ReferenceTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
  data.null_data_source.test - *terraform.NodeAbstractResource
output.result - *terraform.NodeApplyableOutput
  local.foo - *terraform.NodeLocal
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.CountBoundaryTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
  data.null_data_source.test - *terraform.NodeAbstractResource
meta.count-boundary (count boundary fixup) - *terraform.NodeCountBoundary
  data.null_data_source.test - *terraform.NodeAbstractResource
  local.foo - *terraform.NodeLocal
  output.result - *terraform.NodeApplyableOutput
  provider.null - *terraform.NodeApplyableProvider
output.result - *terraform.NodeApplyableOutput
  local.foo - *terraform.NodeLocal
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.TargetsTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
  data.null_data_source.test - *terraform.NodeAbstractResource
meta.count-boundary (count boundary fixup) - *terraform.NodeCountBoundary
  data.null_data_source.test - *terraform.NodeAbstractResource
  local.foo - *terraform.NodeLocal
  output.result - *terraform.NodeApplyableOutput
  provider.null - *terraform.NodeApplyableProvider
output.result - *terraform.NodeApplyableOutput
  local.foo - *terraform.NodeLocal
provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.CloseProviderTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
  data.null_data_source.test - *terraform.NodeAbstractResource
meta.count-boundary (count boundary fixup) - *terraform.NodeCountBoundary
  data.null_data_source.test - *terraform.NodeAbstractResource
  local.foo - *terraform.NodeLocal
  output.result - *terraform.NodeApplyableOutput
  provider.null - *terraform.NodeApplyableProvider
output.result - *terraform.NodeApplyableOutput
  local.foo - *terraform.NodeLocal
provider.null - *terraform.NodeApplyableProvider
provider.null (close) - *terraform.graphNodeCloseProvider
  data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.CloseProvisionerTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
  data.null_data_source.test - *terraform.NodeAbstractResource
meta.count-boundary (count boundary fixup) - *terraform.NodeCountBoundary
  data.null_data_source.test - *terraform.NodeAbstractResource
  local.foo - *terraform.NodeLocal
  output.result - *terraform.NodeApplyableOutput
  provider.null - *terraform.NodeApplyableProvider
output.result - *terraform.NodeApplyableOutput
  local.foo - *terraform.NodeLocal
provider.null - *terraform.NodeApplyableProvider
provider.null (close) - *terraform.graphNodeCloseProvider
  data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.RootTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
  data.null_data_source.test - *terraform.NodeAbstractResource
meta.count-boundary (count boundary fixup) - *terraform.NodeCountBoundary
  data.null_data_source.test - *terraform.NodeAbstractResource
  local.foo - *terraform.NodeLocal
  output.result - *terraform.NodeApplyableOutput
  provider.null - *terraform.NodeApplyableProvider
output.result - *terraform.NodeApplyableOutput
  local.foo - *terraform.NodeLocal
provider.null - *terraform.NodeApplyableProvider
provider.null (close) - *terraform.graphNodeCloseProvider
  data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
root - terraform.graphNodeRoot
  meta.count-boundary (count boundary fixup) - *terraform.NodeCountBoundary
  provider.null (close) - *terraform.graphNodeCloseProvider
2019/03/28 17:13:30 [TRACE] Graph after step *terraform.TransitiveReductionTransformer:

data.null_data_source.test - *terraform.NodeAbstractResource
  provider.null - *terraform.NodeApplyableProvider
local.foo - *terraform.NodeLocal
  data.null_data_source.test - *terraform.NodeAbstractResource
meta.count-boundary (count boundary fixup) - *terraform.NodeCountBoundary
  output.result - *terraform.NodeApplyableOutput
output.result - *terraform.NodeApplyableOutput
  local.foo - *terraform.NodeLocal
provider.null - *terraform.NodeApplyableProvider
provider.null (close) - *terraform.graphNodeCloseProvider
  data.null_data_source.test - *terraform.NodeAbstractResource
root - terraform.graphNodeRoot
  meta.count-boundary (count boundary fixup) - *terraform.NodeCountBoundary
  provider.null (close) - *terraform.graphNodeCloseProvider
2019/03/28 17:13:30 [DEBUG] Starting graph walk: walkInput
2019/03/28 17:13:30 [TRACE] dag/walk: added new vertex: "provider.null (close)"
2019/03/28 17:13:30 [TRACE] dag/walk: added new vertex: "root"
2019/03/28 17:13:30 [TRACE] dag/walk: added new vertex: "data.null_data_source.test"
2019/03/28 17:13:30 [TRACE] dag/walk: added new vertex: "local.foo"
2019/03/28 17:13:30 [TRACE] dag/walk: added new vertex: "output.result"
2019/03/28 17:13:30 [TRACE] dag/walk: added new vertex: "provider.null"
2019/03/28 17:13:30 [TRACE] dag/walk: added new vertex: "meta.count-boundary (count boundary fixup)"
2019/03/28 17:13:30 [TRACE] dag/walk: added edge: "local.foo" waiting on "data.null_data_source.test"
2019/03/28 17:13:30 [TRACE] dag/walk: added edge: "meta.count-boundary (count boundary fixup)" waiting on "output.result"
2019/03/28 17:13:30 [TRACE] dag/walk: added edge: "provider.null (close)" waiting on "data.null_data_source.test"
2019/03/28 17:13:30 [TRACE] dag/walk: added edge: "root" waiting on "meta.count-boundary (count boundary fixup)"
2019/03/28 17:13:30 [TRACE] dag/walk: added edge: "data.null_data_source.test" waiting on "provider.null"
2019/03/28 17:13:30 [TRACE] dag/walk: added edge: "root" waiting on "provider.null (close)"
2019/03/28 17:13:30 [TRACE] dag/walk: added edge: "output.result" waiting on "local.foo"
2019/03/28 17:13:30 [TRACE] dag/walk: dependencies changed for "meta.count-boundary (count boundary fixup)", sending new deps
2019/03/28 17:13:30 [TRACE] dag/walk: dependencies changed for "provider.null (close)", sending new deps
2019/03/28 17:13:30 [TRACE] dag/walk: dependencies changed for "root", sending new deps
2019/03/28 17:13:30 [TRACE] dag/walk: dependencies changed for "data.null_data_source.test", sending new deps
2019/03/28 17:13:30 [TRACE] dag/walk: dependencies changed for "output.result", sending new deps
2019/03/28 17:13:30 [TRACE] dag/walk: dependencies changed for "local.foo", sending new deps
2019/03/28 17:13:30 [TRACE] dag/walk: walking "provider.null"
2019/03/28 17:13:30 [TRACE] vertex 'root.provider.null': walking
2019/03/28 17:13:30 [TRACE] vertex 'root.provider.null': evaluating
2019/03/28 17:13:30 [TRACE] [walkInput] Entering eval tree: provider.null
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalSequence
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalInitProvider
2019-03-28T17:13:30.903+0100 [DEBUG] plugin: starting plugin: path=/Users/[redacted]/go/src/github.com/hashicorp/terraform/pkg/.terraform/plugins/darwin_amd64/terraform-provider-null_v2.1.0_x4 args=[/Users/[redacted]/go/src/github.com/hashicorp/terraform/pkg/.terraform/plugins/darwin_amd64/terraform-provider-null_v2.1.0_x4]
2019-03-28T17:13:30.905+0100 [DEBUG] plugin: waiting for RPC address: path=/Users/[redacted]/go/src/github.com/hashicorp/terraform/pkg/.terraform/plugins/darwin_amd64/terraform-provider-null_v2.1.0_x4
2019-03-28T17:13:30.916+0100 [DEBUG] plugin.terraform-provider-null_v2.1.0_x4: plugin address: timestamp=2019-03-28T17:13:30.915+0100 address=/var/folders/cb/wf5dfzqj0m39hf5npvv2t65h0000gn/T/plugin641732846 network=unix
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalOpFilter
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalSequence
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalGetProvider
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalInterpolateProvider
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalBuildProviderConfig
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalInputProvider
2019/03/28 17:13:30 [TRACE] root: eval: terraform.EvalNoop
2019/03/28 17:13:30 [TRACE] root: eval: terraform.EvalNoop
2019/03/28 17:13:30 [TRACE] root: eval: terraform.EvalNoop
2019/03/28 17:13:30 [TRACE] [walkInput] Exiting eval tree: provider.null
2019/03/28 17:13:30 [TRACE] dag/walk: walking "data.null_data_source.test"
2019/03/28 17:13:30 [TRACE] vertex 'root.data.null_data_source.test': walking
2019/03/28 17:13:30 [TRACE] dag/walk: walking "provider.null (close)"
2019/03/28 17:13:30 [TRACE] vertex 'root.provider.null (close)': walking
2019/03/28 17:13:30 [TRACE] vertex 'root.provider.null (close)': evaluating
2019/03/28 17:13:30 [TRACE] [walkInput] Entering eval tree: provider.null (close)
2019/03/28 17:13:30 [TRACE] dag/walk: walking "local.foo"
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalCloseProvider
2019/03/28 17:13:30 [TRACE] vertex 'root.local.foo': walking
2019/03/28 17:13:30 [TRACE] [walkInput] Exiting eval tree: provider.null (close)
2019/03/28 17:13:30 [TRACE] vertex 'root.local.foo': evaluating
2019/03/28 17:13:30 [TRACE] [walkInput] Entering eval tree: local.foo
2019/03/28 17:13:30 [TRACE] root: eval: *terraform.EvalLocal
2019/03/28 17:13:30 [DEBUG] Interpolating computed map element attribute outputs (1)
2019/03/28 17:13:30 [ERROR] root: eval: *terraform.EvalLocal, err: local.foo: key "b" does not exist in map data.null_data_source.test.outputs in:

${data.null_data_source.test.outputs["b"]}
2019/03/28 17:13:30 [TRACE] [walkInput] Exiting eval tree: local.foo
2019/03/28 17:13:30 [TRACE] dag/walk: upstream errored, not walking "output.result"
2019/03/28 17:13:30 [TRACE] dag/walk: upstream errored, not walking "meta.count-boundary (count boundary fixup)"
2019/03/28 17:13:30 [TRACE] dag/walk: upstream errored, not walking "root"
e:
2019/03/28 17:13:30 [DEBUG] plugin: waiting for all plugin processes to complete...
Error: Error asking for user input: 1 error occurred:
    * local.foo: local.foo: key "b" does not exist in map data.null_data_source.test.outputs in:

${data.null_data_source.test.outputs["b"]}

2019-03-28T17:13:30.919+0100 [DEBUG] plugin.terraform-provider-null_v2.1.0_x4: 2019/03/28 17:13:30 [ERR] plugin: plugin server: accept unix /var/folders/cb/wf5dfzqj0m39hf5npvv2t65h0000gn/T/plugin641732846: use of closed network connection
2019-03-28T17:13:30.920+0100 [DEBUG] plugin: plugin process exited: path=/Users/[redacted]/go/src/github.com/hashicorp/terraform/pkg/.terraform/plugins/darwin_amd64/terraform-provider-null_v2.1.0_x4

Process finished with exit code 1
apparentlymart commented 5 years ago

Hi all! Thanks for reporting this and sorry for the slow response.

Based on the debug log from @Emptyless it appears that is error is occurring during the phase where Terraform analyzes the provider configurations to see if any of them require input prompts. It's not totally clear to me why Terraform is trying to evaluate the local values in that phase but it makes sense that this would fail because data resources are not read until the refresh phase, which comes after the input phase.

You may be able to work around this for now by passing -input=false to the terraform apply command, which should disable this input phase altogether and allow Terraform to proceed to refresh and then plan.

This input phase no longer exists in the same way in the forthcoming Terraform v0.12.0 release, which is what we currently have in the master branch. Therefore it's likely that this issue will no longer be present in the same form in the forthcoming release: the codepath where this failed no longer exists. After v0.12.0 development has concluded we can check this to see if there are any remaining issues in this area to be fixed and then, hopefully, fix them in a subsequent patch release.

Emptyless commented 5 years ago

@apparentlymart what I found strange is that during the initial apply (where the input is only 'a' and the output is 'a' and there is no .tfstate), the [walkInput] also enters local.foo but does not generate errors:

2019/03/30 15:06:53 [TRACE] [walkInput] Entering eval tree: local.foo
2019/03/30 15:06:53 [TRACE] root: eval: *terraform.EvalLocal
2019/03/30 15:06:53 [TRACE] [walkInput] Entering eval tree: provider.null (close)
2019/03/30 15:06:53 [TRACE] root: eval: *terraform.EvalCloseProvider
2019/03/30 15:06:53 [TRACE] [walkInput] Exiting eval tree: provider.null (close)
2019/03/30 15:06:53 [TRACE] [walkInput] Exiting eval tree: local.foo

EDIT:

If the execution is traced, it traverses EvalRaw -> EvalLocal -> Interpolate(n.Value, nil) to "eval_context_builtin.go": func (ctx *BuiltinEvalContext) Interpolate) where it throws the error during the "do interpolation" step at: cfg.Interpolate(vs) (line 249)

EDIT 2:

@apparentlymart , If I update the conditional of valueResourceVar to be:

if i.Operation == walkValidate || i.Operation == walkInput {
    result[n] = unknownVariable()
    return nil
}

It behaves the same on initial apply and the second apply. What would be the side-effects of introducing such a conditional? Running the tests with make does not give failed tests. I can create a PR this evening :)

apparentlymart commented 4 years ago

Hi all. It's been a while!

The root cause of this issue -- that Terraform would use a graph traversal to analyze a configuration for input prompts before taking other action -- was addressed in Terraform 0.12 by switching to a new strategy for implementing the input prompts, which is now handled in a simpler way in the Terraform UI code.

There are no additional v0.11 releases planned, so I'm going to close this out to reflect that it has been fixed in the v0.12 series. Thanks for sharing the reproduction cases and trace logs: they were helpful in determining that this problem is arising in the (now removed) walkInput, which had been the root cause of a number of other strange problems of this sort and that is why we redesigned that subsystem in Terraform v0.12.

ghost commented 4 years ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.