After I source the .env file and perform terraform init and apply, I am getting issues that terraform cannot detect the environment variables
Error: Missing required argument
│
│ on main.tf line 1, in module "aws-deploy":
│ 1: module "aws-deploy" {
│
│ The argument "region" is required, but no definition was found.
I am unsure what to do as I am new to TF_VARs and I want to source my vars apart of my code approach
It looks like you have a root module (main dir) plus a sub-module (modules/eks dir). Both of those have variable definitions (by convention in variables.tf as you have).
For the root module the variables are set from the command line, a tfvars file, environment variables (TF_VAR_<name>) or an interactive prompt.
For sub modules the variables are set from the module {} block.
Your error indicates that the sub-module is expecting a required variable called “region” which is missing. If your main.tf is literally just a module block that has the source line it would give that error. You also need to include lines for “region” and any other variables you want your module to use.
If you are wanting to pass the same value that the root module has, you would have something like:
I am still doing this wrong and wondering how best to modify this code, I guess my parent module “aws-deploy” is trying to provide TF_VAR_region to the child module “eks” but its not working for me
Error: Reference to undeclared input variable
│
│ on main.tf line 9, in module "aws-deploy":
│ 9: region = var.region
│
│ An input variable with the name "region" has not been declared. This variable can be declared with a
│ variable "region" {} block.
I know I am misunderstanding what you mentioned above, my ambition is for the “main.tf” in main dir to call “modules/eks” directory but I want to pass the TF_VARs somehow to child module “modules/eks”
I guess I am either writing my terraform code wrong or do something wrong
So you have your root module (the top level directory). It needs to have a variable block for the “region”. You then also have a module block that calls your eks module, passing in the value of the region.
Within the eks module you have a variable block for the “region”.
Then when you run Terraform the root level “region” variable will get its value from the environment variable. You then pass that (in the module block) to your eks module (region = var.region) which can then use it as needed.
@stuart-c : Just want to confirm I understand this (sorry for repetitive questions as first time I ever use TF VAR but trying to build this into my CI/CD pipeline for terraform builds)
For the root module (main), the main.tf looks like
→ main dir
main.tf
state.tf
versions.tf
main.tf
module "aws-deploy" {
source = "../../modules/eks"
# AWS
region = var.region
}
variable "region" {
type = string
}
and then for the eks module or eks.tf (child module) in eks folder
→ modules/eks dir
eks.tf
variables.tf
aws.tf
versions.tf
for variables.tf inside eks folder :
variable "region" {
type = string
}
and then the code for aws.tf inside the (eks folder):
provider "aws" {
region = var.region
}
does that look similar to the strategy to getting the region var from environment TF_VAR?
Yes, however you shouldn’t be putting provider blocks inside a sub-module. All providers should be being defined at the top level and then passed into modules (either explicitly or implicitly).
You are correct indeed.
but there are some providers like elasticsearch which do require provider declaration in the submodules as well, otherwise you might face errors like “required module is not present” when you try to DELETE a module block from the root module.
I have faced these type of issues and adding a provider block in the submodule solved my problem.
Provider blocks shouldn’t be added to submodules, and aren’t allowed if you are wanting to use count or for_each with a module. Within the submodule there should be a required_providers section in the terraform {} block, but no actual provider definitions.