<p>Each module has its own set of input variables.</p>

<p>The input variables for the root module are set when you run Terraform, e.g. on the command like with the <code>-var</code> option.</p>

<p>The input variables for any child module, like your <code>module "logs"</code> here, are set inside the <code>module</code> block.</p>

<p>Each variable declaration is valid only for the module it appears in. You happen to have given both of these variables the same name, which is fine and sensible as it helps a human reader understand that they represent the same concept, but Terraform considers these two variables entirely separate and requires you to declare and set both of them.</p>

<p>As an analogy, consider a module as being somewhat equivalent to a function in a programming language. Each function defines its own arguments, and two functions might have an argument of the same name but they are still distinct by virtue of belonging to different functions:</p>

<pre><code>function main(env: string) {
  logs(env)
}

function logs(env: string) {
  // "env" in here is "test" because it was passed through
  // the arguments of both of these functions, not because
  // the arguments happened to have the same name in both
  // functions.
}

// Calling main here is, for the purposes of this analogy,
// corresponding to running: terraform apply -var="env=test"
main("test")
</code></pre>

CC BY-SA 4.0
2019-12-20T01:46:28.410Z
2019-12-20T01:46:28.410Z
Martin Atkins
<p>My folder hierarchy looks like this:</p>

<pre><code>/
  -&gt; live/
    : main.tf
    : variables.tf
  -&gt; modules/
    -&gt; logs/
      : logs.tf
      : variables.tf
</code></pre>

<p>In my <code>main.tf</code> I have:</p>

<pre><code>module "logs" {
  source = "../modules/logs"

  env = var.env
  ...
}
</code></pre>

<p>In my <code>logs.tf</code> I have:</p>

<pre><code>resource "datadog_monitor" "logs-fatal" {
  env = var.env
  ...
}
</code></pre>

<p>In both <code>variables.tf</code> files I have: </p>

<pre><code>variable "env" {default = "test"} 
</code></pre>

<p>If I remove this from either of them, I'm given an <code>Unsupported argument</code> error - why? It's unclear to me in this scenario which variable will be taking precedence and why both sets are needed.</p>

<terraform><terraform-module>
Why does my Terraform config require variables in multiple places?
MrDuk
# Why does my Terraform config require variables in multiple places?

(Asked by: username_0 on 2019-12-19)

My folder hierarchy looks like this:
/
  -> live/
    : main.tf
    : variables.tf
  -> modules/
    -> logs/
      : logs.tf
      : variables.tf

In my main.tf I have:
module "logs" {
  source = "../modules/logs"

  env = var.env
  ...
}

In my logs.tf I have:
resource "datadog_monitor" "logs-fatal" {
  env = var.env
  ...
}

In both variables.tf files I have: 
variable "env" {default = "test"} 

If I remove this from either of them, I'm given an Unsupported argument error - why? It's unclear to me in this scenario which variable will be taking precedence and why both sets are needed.

**Tags:** terraform, terraform-module


---

## 1 answers

### Answer by username_1 on 2019-12-20. Score: 1 | Accepted answer

Each module has its own set of input variables.
The input variables for the root module are set when you run Terraform, e.g. on the command like with the -var option.
The input variables for any child module, like your module "logs" here, are set inside the module block.
Each variable declaration is valid only for the module it appears in. You happen to have given both of these variables the same name, which is fine and sensible as it helps a human reader understand that they represent the same concept, but Terraform considers these two variables entirely separate and requires you to declare and set both of them.
As an analogy, consider a module as being somewhat equivalent to a function in a programming language. Each function defines its own arguments, and two functions might have an argument of the same name but they are still distinct by virtue of belonging to different functions:
function main(env: string) {
  logs(env)
}

function logs(env: string) {
  // "env" in here is "test" because it was passed through
  // the arguments of both of these functions, not because
  // the arguments happened to have the same name in both
  // functions.
}

// Calling main here is, for the purposes of this analogy,
// corresponding to running: terraform apply -var="env=test"
main("test")


---

