Reputation: 1212
Terraform newbie would appreciate a push in the right direction.
Have created my first module, a child module to root called 'storage' in there I want to put all the templates for the storage accounts. I thought this would be simple.
I've added a folder named 'storage' and moved the existing 'storage.tf' file into that and added added modules block to my main.tf (in root) to tell it the module exists. I did a terraform init and it found and installed it - great!
But now when I try something like:
terraform plan -var-file='env/dev/dev.tfvars'
None of the variables which my storage.tf file references are found. I just get:
Error: Reference to undeclared input variable
│
│ on modules\storage\storage.tf line 11, in resource "google_storage_bucket" "new_bucket":
│ 11: name = "${var.env_name}-${var.name_of_bucket}-test"
│
│ An input variable with the name "env_name" has not been declared. This variable can be declared with a variable "env_name" {} block.
All my variables are defined in a variables.tf in root and when running terraform I pass in the path to the relevant variable values using the .tfvars method.
Why can't the module see those?
I tried creating a vars.tf in the module directory, next to the storage.tf file. I copied the variable definitions into that file and got errors that the value of the variable was missing (even though the values were in the .tfvars file used in the invocation).
I then tried adding the value to the variable definitions using the 'default' and this actually worked - but that means I can no longer use the .tfvars to control which environment I'm configuring.
I must be missing something really basic!
Question: How can I get my modules to accept the values contained in my .tfvars? I don't mind having the variables which each module needs in a seperate vars.tf for each module - thats fine and actually useful, but there has to be some way to pass in the values with a simple .tfvars? Please... what am I missing?
Update Below is the folder and file structure, sorry if I am not using the right syntax for the graph!
condo (folder)
|--.git (folder)
|--.github (folder)
|--creds (folder)
| |--dev_creds.json (file)
| |--prod_creds.json (file)
|
|--infracomm (folder) (root)
|
|--.terraform (file)
|--.terraform.hcl.lock (file)
|--env (folder)
| |--dev (folder)
| | |--dev.tfvar (file)
| |
| |--prod (folder)
| |--prod.tfvars (file)
|
|--modules (folder) (child module)
| |--storage (folder)
| |--storage.tf (file)
|
|--backend.tf (file)
|--main.tf (file)
|--variables.tf (file)
All I am trying to do is get the variables in the root variables.tf AND the values for those variables, which I am providing in the cli arg
-var-file='./env/dev/dev.tfvars'
To be usable inside the storage module.
UPDATE #2
Here is the code from main.tf in root where I am referencing the child module. Let me know if more needed:
provider "google" {
project = var.project_name
region = "europe-west4"
zone = "europe-west4"
credentials = var.credentials_path
}
// Define modules
module "storage" {
source = "./modules/storage"
}
Do I need to duplicate those variables in a vars.tf in the module? If so, how do I get values into them without using 'default' as that would break scalability.
I'm sure I'm missing something basic.
Thanks!
Upvotes: 2
Views: 5537
Reputation: 4408
Let's say you want to pass the variable variable_to_child_module in your module, from the root module.
The value of this variable was added through a .tfvars file in the root module, namely variable_from_root_module
When you call the storage module from the root module pass the variable
// Define modules
module "storage" {
source = "./modules/storage"
variable_to_child_module = var.variable_from_root_module
}
Also in ./modules/storage
directory you should add a variables.tf
where you will add the variable definition
E.g.
variable "variable_to_child_module" {
description = "my child module variable"
type = string
}
Upvotes: 3
Reputation: 762
Consider each module (root and storage) an independent module. You need to (re)define the variables which you use in the sub-module (storage) in the sub-module itself.
Assuming you have variables region
and size
which you pass into the main module and want to use in storage module, you can do this as follows:
module "storage" {
source = "./modules/storage"
region = var.region
size = var.size
}
Upvotes: 3