2
votes

Versioning:

Terraform v0.15.0
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v3.37.0
+ provider registry.terraform.io/hashicorp/random v3.1.0

I have the following folder structure:

terraform/
├── main.tf
└── terraform.tfvars
├── core
│   ├── main.tf
│   └── variables.tf

The files of concern here are:

terraform/main.tf
terraform/terraform.tfvars
core/main.tf
core/variables.tf

The high-level overview is I'm trying to use TF to create a VPC in AWS, using the terraform-aws-vpc module, so my root module is calling the core module which calls the terraform-provided vpc module to build. The reason it's a child calling a child is that once I get this vpc step working, the "core" module is going to be responsible for building other infrastructure assets in the account. The idea is to have the root module call a child module for each important piece of the AWS Account assets.

The problem I'm running into here is one of variables.

In core/, I have the following variables defined in core/variables.tf:

variable "vpc_facts" {
    type = map
}

That variable is referenced for information for the vpc module in core/main.tf:

module "vpc" {
    source = "terraform-aws-modules/vpc/aws"

    name = var.vpc_facts.name
    cidr = var.vpc_facts.cidr
}

I define these values, which I hope will be passed into the module, in terraform/terraform.tfvars:

vpc_facts = {
    name = "demo-vpc"
    cidr = "192.168.0.0/16" 
}

I then call the core module from terraform/main.tf

module "core" {
    source = "./core/"
}

I am trying to call terraform plan from my root folder of terraform/ - I have included the core as a module within terraform/main.tf

My thought process here is terraform/main.tf -> gathers terraform/terraform.tfvars -> core module -> uses terraform/terraform.tfvars as input variables for vpc module

However, that doesn't seem to be happening. I keep getting this error when running terraform plan from the root module folder:

Releasing state lock. This may take a few moments...
╷
│ Warning: Value for undeclared variable
│ 
│ The root module does not declare a variable named "vpc_facts" but a value was found in file "terraform.tfvars". If you meant to use
│ this value, add a "variable" block to the configuration.
│ 
│ To silence these warnings, use TF_VAR_... environment variables to provide certain "global" settings to all configurations in your
│ organization. To reduce the verbosity of these warnings, use the -compact-warnings option.
╵
╷
│ Error: Missing required argument
│ 
│   on main.tf line 57, in module "core":
│   57: module "core" {
│ 
│ The argument "vpc_facts" is required, but no definition was found.

I would guess this should already be defined since I'm defining it in both tfvars and core/variables, but when I actually try to define it in the root main.tf:

module "core" {
    source = "./core/"
    
    vpc_facts = var.vpc_facts
}

I get a different error:

╷
│ Error: Reference to undeclared input variable
│ 
│   on main.tf line 60, in module "core":
│   60:     vpc_facts = var.vpc_facts
│ 
│ An input variable with the name "vpc_facts" has not been declared. This variable can be declared with a variable "vpc_facts" {}
│ block.

but it is declared, in core/variables.tf and valued in terraform/terraform.tfvars

What am I missing here? Does this mean I need to repeatedly define variables in both child modules and the root module? I would think that if a root module is calling a child module, it's a flat structure in terms of variables, and that child module can see child/variables.tf

1

1 Answers

1
votes

Does this mean I need to repeatedly define variables in both child modules and the root module?

Yes, exactly what it means. All modules are self-contained, and a child module does not inherit variables from the parent. You have to explicitly define the variables in the module, and then set them in the parent module when you create the module.