Terraform v0.11.7
+ provider.aws v1.52.0
โโโ README.md
โโโ modules
โย ย โโโ alb
โย ย โย ย โโโ main.tf
โย ย โย ย โโโ variables.tf
โโโ prod
โย ย โโโ alb
โย ย โย ย โโโ consumer_vars.tfvars
โย ย โย ย โโโ main.tf
โย ย โย ย โโโ seller_vars.tfvars
The 'alb' module in 'main.tf' contains all the required steps to create alb with variables defined in 'variables.tf'. My variables.tf is as below:
terraform {
backend "consul" {
address = "consul.prod.com"
path = "tf/state/alb"
}
}
variable "cluster_name" {
description = "ELB name, e.g cdn"
}
variable "vpc_id" {
description = "New production VPC id"
}
variable "subnet_ids" {
description = "Comma separated list of subnet IDs"
}
variable "environment" {
description = "Environment tag, e.g prod"
}
variable "client_listener_ports" {
type= "list"
description = "Client listener ports to be attached to ALB Security Group"
}
variable "log_bucket" {
description = "S3 bucket name to write ELB logs into"
}
variable "service_name" {
type = "list"
description = "List of services that are part of the cluster"
}
I have defined the 'alb' module in prod-> alb-> main.tf as below:
provider "aws" {
region = "ap-southeast-1"
}
module "alb" {
source = "../../modules/alb"
cluster_name= "${var.cluster_name}"
service_name= "${var.service_name}"
subnet_ids= "${var.subnet_ids}"
environment= "${var.environment}"
log_bucket="${var.log_bucket}"
vpc_id="${var.vpc_id}"
client_listener_ports="${var.client_listener_ports}"
}
Also, I have my cluster specific variables defined in prod-> alb-> consumer_vars.tfvars as below:
cluster_name= "consumer"
service_name=["service1","service2","service3"]
subnet_ids= "subnet-37c,subnet-a10"
environment= "prod"
log_bucket="log_bucket"
vpc_id="vpc-ad"
client_listener_ports=["9000"]
terraform plan -var-file="consumer_vars.tfvars"
The above command should have returned a list of resources that would be created upon 'terraform apply'.
Error: module 'alb': unknown variable referenced: 'environment'; define it with a 'variable' block
Error: module 'alb': unknown variable referenced: 'log_bucket'; define it with a 'variable' block
Error: module 'alb': unknown variable referenced: 'vpc_id'; define it with a 'variable' block
Error: module 'alb': unknown variable referenced: 'client_listener_ports'; define it with a 'variable' block
Error: module 'alb': unknown variable referenced: 'cluster_name'; define it with a 'variable' block
Error: module 'alb': unknown variable referenced: 'service_name'; define it with a 'variable' block
Error: module 'alb': unknown variable referenced: 'subnet_ids'; define it with a 'variable' block
First off, I am new to Terraform and still exploring the documentations, extensively trying out different configs and observing outputs.
I would want to re-use the module for different cluster specific resource creation without constantly editing 'main.tf' with defined variables.
Hi @adithyamenon ,
Frequently, module developers use the same variable name in the top-level configuration and in the modules. That means you need to declare a variable in both your top-level terraform configuration files (in your example, somewhere in prod/alb/, and in the module (again, in your example modules/alb/variables/tf.
I believe if you add the variables from the error messages to a .tf file in the module you'll be all set.
@mildwonkey I have encountered similar issue and your suggestion did work. This is a little counter - intuitive to declare the variable again at the module and resource config files.
Thanks @mildwonkey! This worked for me.
But yes, as @kbaddi mentioned, isn't it redundant to declare variables both at resource and module level? As we mention the 'source' in the resource main.tf, shouldn't terraform be able to load the variables.tf from the module?
I do understand that this can feel redundant! There are a few bits of information that may help you understand why you need to declare variables in your root module (the top-level terraform configuration files) and each individual modules.
The most obvious issue is that you can have multiple modules with the same variable name, but you need to pass a different value to each module.
Imagine a situation where your main.tf references three modules, and each module has a count. Your main.tf therefore might end up with three different variables to pass to the modules' count: module1_count or alb_count, etc.
This might be easier to see in some pseudo-code:
variable "app_count" { }
variable "db_count" { }
variable "alb_count" { }
module "app_servers" {
count = var.app_count
}
module "db_instances" {
count = var.db_count
}
module "alb" {
count = var.alb_count
}
The other thing to know is that terraform loads each module, including the root module, a discrete unit. It needs to parse the root module (your top-level configuration files) before it can start loading the child modules. It cannot get past the first step, loading the root module, if you are using variables that haven't been declared there.
I hope this is helpful information!
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.
Most helpful comment
I do understand that this can feel redundant! There are a few bits of information that may help you understand why you need to declare variables in your root module (the top-level terraform configuration files) and each individual modules.
The most obvious issue is that you can have multiple modules with the same variable name, but you need to pass a different value to each module.
Imagine a situation where your
main.tfreferences three modules, and each module has acount. Your main.tf therefore might end up with three different variables to pass to the modules' count:module1_countoralb_count, etc.This might be easier to see in some pseudo-code:
The other thing to know is that terraform loads each module, including the root module, a discrete unit. It needs to parse the root module (your top-level configuration files) before it can start loading the child modules. It cannot get past the first step, loading the root module, if you are using variables that haven't been declared there.
I hope this is helpful information!