'variable "..." is nil, but no error was reported' when using data.external in nested modules

76 views
Skip to first unread message

Marques Johansson

unread,
Jan 22, 2019, 10:26:42 AM1/22/19
to Terraform
I refactored a flat k8s module to have an master and node submodule which rely on a generic instance module. The branch that introduces this refactor is https://github.com/linode/terraform-linode-k8s/pull/23#issuecomment-455943205 .

While provisioning works after this refactor, I'm now getting a warning on which acts as an error during `terraform destroy` (`TF_WARN_OUTPUT_ERRORS=0`can silence this, but there must be a better approach).

module.masters.output.kubeadm_join_command: variable "kubeadm_join" is nil, but no error was reported


The output block emits the Kubernetes join command which is dependent on an external data block which is dependent  on the instance module (master_instance) to have provisioned.

//  module.masters includes a module.instance called "master_instance"
output "kubeadm_join_command" {
 depends_on = ["module.master_instance", "data.external.kubeadm_join"]
 value      = "${data.external.kubeadm_join.result["command"]}"
}

I attempted tricks to make the value not "nil" in the block above: coalesce, concat, ternary, values,  lookup.  None of those helped.

There appear to be several Terraform issues open with similar concerns, but I don't see any direct or indirect workarounds offered.


I also attempted to modify the `program` referenced in the external data to emit an empty json block instead of erroring when the master instance is not available for the input variable: `{ "command": "" }` .. that didn't help either.

Any pointers?

Marques Johansson

unread,
Jan 23, 2019, 9:02:01 PM1/23/19
to Terraform
Well, after a bunch of refactoring and experimentation, I found a workaround.  Repeated applies and destroys finish without error.


locals {
  result
= {
    command
= ""
 
}
  kubeadm_join_results
= "${concat(data.external.kubeadm_join.*.result, list(local.result))}"
  kubeadm_join_command
= "${lookup(local.kubeadm_join_results["0"], "command", "")}"
}

 output
"kubeadm_join_command" {
  depends_on
= ["null_resource.masters_provisioner"]
  value
= "${local.kubeadm_join_command}"
 
}

I bumped into some other issues that hinted towards this approach:
Reply all
Reply to author
Forward
0 new messages