How can I pass the tfvars from another module? - terraform

So here's my setup:
main.tf:
module "foo" {
source = "../../../foo-module"
name = "bar"
foo_nets = "${var.foo_nets}"
}
foo-module/terraform.tfvars:
foo_nets = ["1", "2", "3"]
➜ terraform plan -var-file=../../foo-module/terraform.tfvars -target=module.foo
Error: module 'foo': unknown variable referenced: 'foo_nets'; define it with a 'variable' block

Your foo-module/terraform.tfvars doesn't define a variable named foo_nets, it only defines a default value for a variable named foo_nets if that variable happens to exist. You still have to define the variable somewhere in the terraform files in the foo-module folder like this:
variable "foo_nets" {
}

Related

Terraform interactive input doesn't work with the root module

Terraform Version
Terraform v1.1.2
on windows_amd64
Terraform Configuration Files
child_module1.tf(C1):
# Create Resource Group
resource "aws_resourcegroups_group" "resourcegroups_group" {
name = "test"
resource_query {
query = <<JSON
{
"ResourceTypeFilters": [
"AWS::EC2::Instance"
],
"TagFilters": [
{
"Key": "project",
"Values": ["${var.ProjectName}"]
}
]
}
JSON
}
}
child_module1_variables.tf:
########
variable "ProjectName" {
type = string
description = "This name would be prefixed with the cluster names."
}
Now call this child module in another child module**(C2)**:
child_module2.tf:
module "prepare_aws_cloud" {
source = "./modules/aws/prepare_cloud_copy"
ProjectName = "${var.test.ProjectName}"
}
child_module2_variables.tf:
variable "test" {
type = object({
ProjectName = string
})
}
Now I create a root module(R1)** which calls the child_module2.tf:**
terraform {
backend "local" {
}
}
module "test_deploy" {
source = "D:\\REPO\\installer_v2.2.22.1\\installer\\aws"
test = {
#ProjectName = ""
}
}
So the dependency is as follows:
R1 calls >> C2 calls >> C1
ERROR
PS D:\tkgTest> terraform apply -input=true
╷
│ Error: Invalid value for module argument
│
│ on testing.tf line 21, in module "test_deploy":
│ 21: test= {
│ 22: #ProjectName = ""
│ 23: }
│
│ The given value is not suitable for child module variable "test" defined at .terraform\modules\test_deploy\variables.tf:108,1-15: attribute "ProjectName" is required.
Expected Behavior
I would have expected that the user input would be taken interactively by the console as I am passing the -input=true flag but it doesn't seem to work.
The interactive prompts for input variables are intended only to help with getting started with Terraform (e.g. following a simple tutorial) and so they are limited in the scope of what they support. The typical way to set root module input variables for routine use is to either create a .tfvars file and pass it to Terraform with -var-file or to set a variable directly using -var.
Note also that only root module input variables can be set directly as part of the planning options. Any child module variables are defined exclusively by the expressions written in the module block, and so if you want to be able to set a child module's input variable on a per-run basis you'll need to also declare it as a root module variable and then pass it through to the child module.
For example, in the root module:
variable "test" {
type = object({
ProjectName = string
})
}
module "test_deploy" {
source = "./installer/aws"
test = var.test
}
You can then create an example.tfvars file with the following to set a value for the variable:
test = {
ProjectName = "example"
}
Specify that file when you run Terraform:
terraform apply -var-file=example.tfvars
If you will always set the same values then you can avoid the need for the extra option by naming your file example.auto.tfvars and placing it in the same directory where you will run Terraform. Terraform will load .auto.tfvars files automatically without any explicit -var-file option.

Import variables from module terraform

please help to understand how I can import variables files from a different location?
I have tried to do this from the module system, but it's not working for me.
My structure :
/
/variables.tf
/my_ec2/main.tf
/my_ec2/variables.tf
How I can import variables from root folder? Need to specify it somehow on main.tf
My /my_ec2/main.tf
module "global_vars" {
source = "../../../"
}
provider "aws" {
region = "module.global_vars.region_aws"
}
my /variables.tf
variable "region_aws" {
default = "eu-central-1"
}
How can I do this?
P.S. Did the same with "${var.region_aws}", but same result
Error: Reference to undeclared input variable
on ../my_ec2/main.tf line 10, in resource "aws_instance" "server":
10: region = "${var.region_aws}"
An input variable with the name "aws_instance" has not been declared. This
variable can be declared with a variable "environment" {} block.
Maybe use :
"${module.global_vars.region_aws}"
Instead of
"module.global_vars.region_aws"

When are variables defined in terraform?

Terraform newbie here. I've a module with variables.tf which creates a resource 'folder' in Google Cloud. The variables are defined as:
variable "folder_name" {
type = "string"
description = "Name of the folder"
}
The calling function of this module is main.tf.
module "folder" {
source = "../<path>/"
}
When I run 'terraform init', it throws the following error-
$ terraform init
Initializing modules...
- module.folder
- module.project
Error: module "folder": missing required argument "folder_name"
I thought variables can be predetermined in a file or included in the command line options while running 'terraform apply'. I'd prefer CLI options, but then why am I seeing an argument error at the 'init' stage?
You provide the value of each module variable when calling the module itself:
module "folder" {
source = "../<path>/"
folder_name = "xyz" # add this line to define the folder_name variable
}
If you'd like to specify folder_name on the command line instead, you can create a variable in your main.tf file and provide that via command line instead:
variable "module_folder_name" {
default = "xyz"
}
module "folder" {
source = "../<path>/"
folder_name = "${var.module_folder_name}"
}
And then provide this variable's value via the command line:
terraform apply -var="module_folder_name=abc"

Values to variables mentioned in variables.tf in Terraform through environment variables file .tfvars

How do I pass the values of variables mentioned in variable.tf of type "list" or "map" . Are there any mistakes in the syntax in the input.tfvars file mentioned below?
The goal is not to hard code any values in the variables.tf or the main.tf file. In the Terraform.io docs I verified that the values can be provided in this format.
This is from the site:
Lists are defined either explicitly or implicitly:
# implicitly by using brackets [...]
variable "cidrs" { default = [] }
# explicitly
variable "cidrs" { type = "list" }
You can specify lists in a the terraform.tfvars file:
cidrs = [ "10.0.0.0/16", "10.1.0.0/16" ]
Now, when I try to do
terraform plan -var-file=input.tfvars
it is unable to read the variable values from the tfvars file and presents the following error:
Error: module root:
module vpc: required variable "vpccidr" not set
module vpc: required variable "vpcname" not set
The variables.tf file looks like:
variable "vpccidr" { type = "list"}
variable "vpcname" { type = "list" }
The input.tfvars file looks like:
vpccidr=[ "10.1.0.0/16", "10.2.0.0/16", "10.3.0.0/16" ]
vpcname=[ "vpc1", "vpc2", "vpc3" ]
The main.tf file looks like:
module "vpc"{
source = "modules/network/vpc"
}
The VPC module under modules/network has the following configuration file main.tf and the variable file mentioned above in variables.tf:
resource "aws_vpc" "customVpc" {
count = "${length(var.vpccidr)}"
cidr_block = "${element(var.vpccidr, count.index)}"
tags {
count = "${length(var.vpcname)}"
Name = "${element(var.vpcname, count.index)}"
}
}
You need to pass the variables to your module, i.e
module "vpc"{
source = "modules/network/vpc"
vpccidr = "${var.vpccidr}"
vpcname = "${var.vpcname}"
}

Terraform common variable usage in modules

I am writing terraform script to create ASG on AWS. I tried to create it with terraform module to have a more reusable code. The problem is when I want to use variable from common-variable.tfvars on the module tf files, it keeps saying it is undefined and need to be declared. This way, the module will be less reuseable .
Here is an example
root
|
|___project 1
| |_____ main.tf
| |_____ common-variable.tfvars
|
|___ modules
|
|_____ a-module
|______ main.tf
So inside project 1 common-variable.tfvars, basically it looks like this
variable "a" {
description = "a variable"
default = "a"
}
variable "b" {
description = "a variable"
default = "b"
}
Inside a-module / main.tf looks like this
variable "name" {}
resource "aws_autoscaling_group" "asg-1" {
name = "${var.a}"
...
}
When I do terraform init, it says
resource 'aws_autoscaling_group.asg-1' config: unknown variable
referenced: 'a'. define it with 'variable' blocks
Any idea how i can use this common variable from within the module main .tf?
Update
I managed to pass terraform init by redeclaring the variable in each module. However, when i run terraform plan, this kind of error appears invalid value "common-variable.tfvars" for flag -var-file: multiple map declarations not supported for variables
Wrong tfvars format, should be key / value only, such as:
a = "a"
b = "b"
Second, check how do you refer the module, should be something like this:
source = "../modules/a-module"
You need to declare the variables required by the module within the module, and then pass them in when instantiating the module from your project.
Example stolen from hashicorp documentation
In your project:
module "assets_bucket" {
source = "./publish_bucket"
name = "assets"
}
module "media_bucket" {
source = "./publish_bucket"
name = "media"
}
In your module:
# publish_bucket/bucket-and-cloudfront.tf
variable "name" {} # this is the input parameter of the module
resource "aws_s3_bucket" "the_bucket" {
# ...
}
resource "aws_iam_user" "deploy_user" {
# ...
}

Resources