5

I have following structure

main.tf
modules
--moduleA
----worker.tf
----variables.tf

Content of main.tf:

module "moduleA" {
  source = "./modules/moduleA"
}

Content of variables.tf:

variable "num_of_workers" {
  type        = number
  description = "This is number of workers"
  default     = 1

I want co call terraform apply var="num_of_workers=12" I am getting an error:

Error: Value for undeclared variable
│ A variable named "num_of_workers" was assigned on the command line, but the root module does not declare a variable of that name. To use this value, add a "variable" block to the configuration.

Is there any way to set variables in variables.tf in module and set them from commandline? What I am missing here?

2 Answers 2

7

You need to also declare the variable at the parent level. Then you would pass the parent level value to the module like this:

variable "num_of_workers" {
  type = number
}

module "moduleA" {
  source = "./modules/moduleA"
  num_of_workers = var.num_of_workers
}

Then you would set the parent-level value at the command line like this:

terraform apply -var num_of_workers=2

Documentation: https://developer.hashicorp.com/terraform/language/values/variables

Sign up to request clarification or add additional context in comments.

9 Comments

Yes, I got to this answer by trial and error myself. I hoped there could be a more elegant solution to this - I would like to keep everything in the moduleA itself. So basically now I have a dummy variable placeholder defined in module A: variable "num_of_workers" {type = number} and a whole variable with validation defined in root level - more code, and the glue num_of_workers = var.num_of_workers. It is not elegant, but works.
whats more, somehow it does not work with targeting. Any idea why? terraform apply -target=modules.moduleA="num_of_workers=4" does not use the variable value, and says no changes.
I find it very elegant that Terraform modules are entirely self contained and don't leak their variables into the parent module. The way you are saying it "should" work would actually break the ability to use a module multiple times in the parent module.
As for the targeting, please take a look at the syntax. terraform apply -target=modules.moduleA="num_of_workers=4" You are missing the -var argument, and have added unnecessary quotes. It should be something like this: terraform apply -target=modules.moduleA -var num_of_workers=2
@EugenKonkov there's an example in the official documentation: developer.hashicorp.com/terraform/language/values/variables terraform apply -var='image_id_list=["ami-abc123","ami-def456"]' -var="instance_type=t2.micro"
|
1

You can assign a variable from the command line as follows:

terraform apply -var num_of_workers=2

Or like this:

terraform apply -var 'num_of_workers=2'

Reference: Terraform docs

3 Comments

yes, that's actually how I am calling it. The issue is different though - terraform requires variable to be defined twice in order to work, and only allows to pass variable defined in the top level root directory which is a shame - see answer above.
@Wojtas.Zet Saying "Terraform requires variables to be defined twice in order to work" is not really correct. Terraform requires variables to be defined at the top level, if you want to override them at the command line. Overriding variables at the command line is not the only reason to use variables in Terraform, and they "work" just fine for other purposes without "defining them twice".
I suppose it is the way it is. For my use case it would be nicer to be able to pass them just to the module without another definition in the root module. I am trying to have several independent modules for different teams to use.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.