Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Can not set variable to null in Terragrunt inputs #892

Closed
yorinasub17 opened this issue Oct 3, 2019 · 27 comments · Fixed by #2663
Closed

Can not set variable to null in Terragrunt inputs #892

yorinasub17 opened this issue Oct 3, 2019 · 27 comments · Fixed by #2663
Assignees
Labels
bug Something isn't working p:needs triage Needs to be processed by maintainer and issue type / priority added

Comments

@yorinasub17
Copy link
Contributor

This needs investigation, but we were seeing some behavior where if you try to use null as one of the variable values in inputs, terragrunt translates it as the string "null" by the time it gets to terraform.

@ashemedai
Copy link

Did a quick test, @yorinasub17. If the variable is defined as a number then it will fail with a Error: Invalid value for input variable and explicitly with The environment variable TF_VAR_vm_default_capacity does not contain a valid value for variable "vm_default_capacity": a number is required. if you use null in the inputs.

If the variable is defined as a string, then it will parse null as a literal string instead: resource_group_name = "bastion-development-rg" -> "null-development-rg"

@brikis98
Copy link
Member

brikis98 commented Nov 7, 2019

This may be a limitation of terraform. I think if you run terraform apply -var foo=null, it parses null as a string.

@yorinasub17 yorinasub17 added bug Something isn't working help wanted labels Jan 23, 2020
@kerr-bighealth
Copy link

I just ran into this same issue where I have some conditional code around null string variable handling to create a resource. Passing null from terragrunt.hcl negates the null handling, though when omitting the variable from inputs in terragrunt.hcl, null handling works as expected.

@ahmad-hamade
Copy link

I have faced this problem today as well.

@masterleros
Copy link

Hello all,
I'm facing same issue which is blocking my terraform modules executions when using Terragrunt:

inputs = {
  optional = try(dependency.foo.outputs.optional, null)
}

output:

Error: Invalid value for input variable

The environment variable TF_VAR_optional does not contain a valid value for
variable "optional": a number is required.

I've just submitted a fix in the pull request 1367 (with option for old behavior)

@faelnpaiva
Copy link

Same problem , trying to pass null to input for certain environments

@masterleros
Copy link

masterleros commented Oct 8, 2020

Same problem , trying to pass null to input for certain environments

You can use this approach to sort out the null approach avoiding to pass null values to the inputs (if you are using default values inputs in your modules, else it would fail)

inputs = {
  for key, val in {
    # ... your inputs ...
  } :
  key => val if val != null
}

Thanks @yorinasub17 for this tip!

@suppix
Copy link

suppix commented Dec 21, 2021

Looks like I faced the same issue:

include "envcommon" {
  path           = "${dirname(find_in_parent_folders())}/_envcommon/prod/rds/alpha/terragrunt.hcl"
  merge_strategy = "deep"
}

dependency "rds-alpha-master" {
  config_path = "${get_terragrunt_dir()}/../../../../eu-north-1/prod/rds/alpha"
}

inputs = {
  cross_region_replica = true
  replicate_source_db  = dependency.rds-alpha-master.outputs.db_instance_arn

  # Username and password should not be set for replicas
  username = null
  password = null

  multi_az = false

In rendered json I can see:

   + username                              = "null"

And then I get:

 Cannot change master user password on an RDS postgres Read Replica because it uses physical replication and therefore cannot differ from its parent.

@introquest
Copy link

The problem has been relevant for three years, it seems they are not going to solve it, have there been any crutches or workarounds?

  • In the comments I saw so far only sort out the null approach

@lorengordon
Copy link
Contributor

The problem has been relevant for three years, it seems they are not going to solve it, have there been any crutches or workarounds?

Try generating a tfvars file that sets the variable to null?

@anitakrueger
Copy link

I have just hit this problem with a few variables that my module has defaults for. But they all turn out to be set to the string "null" in the state. Is there no traction on this after 3 years? Or is there another workaround like a conditional to leave the variable out from the inputs?

@MaoChhaya
Copy link

MaoChhaya commented Jul 15, 2022

I noticed that it got "null" when a variable is only defined as type = string , number or bool and put its value in terragrunt inputs = {}.

I hope that it will be fixed asap so I don't need to make a validation or condition in very variable

@jonasthehobbit
Copy link

Just had this issue too, what are people using as a workaround?

@DanielViglione
Copy link

wow, got this issue today. A big limitation.

@ragumix
Copy link

ragumix commented Jan 20, 2023

Also faced this problem.

@mwarkentin
Copy link

mwarkentin commented Feb 1, 2023

We're running into this problem as well.

Edit: Creating a terraform.tfvars file and setting the value to null there worked for me.

@pedrohdz
Copy link

@denis256 @yorinasub17
Randomly pinging a maintainers in hopes that this gets attention... Sorry... This issue is problematic.

@AnhQKatalon
Copy link

Just faced this issue today

@ralucado
Copy link

ralucado commented Mar 8, 2023

This is indeed rather ugly and limiting. I would like to not have to have a specific check for "null" strings.

@sherifabdlnaby
Copy link

Faced this today, big limitation in Terragrunt IMO.

@rinerb
Copy link

rinerb commented Mar 27, 2023

I ran into this today.

This is implicit type coercion, and it would help to produce at least a warning message until passing nulls to inputs is supported.

@ellisonc
Copy link

ellisonc commented Apr 4, 2023

Hello everyone, quick update on this issue. This is indeed a limitation of terraform. The variable loader for environment variables and -var command line options intentionally does not evaluate expressions like the tfvars file loader does. We had previously prototyped a solution that uses tfvars files, but that opens up security risks that are unacceptable for some of our customers. I'll be keeping an eye on the relevant terraform issue and will do what I can to get a solution pushed through.

Until then, there are a few workarounds mentioned in this issue. Alternately, if you have control of the module you are trying to use the terraform team suggested the following workaround:

Set the type constraint for the variable to type = any, which tells Terraform to expect a value of any type, and then use a custom validation rule to restore the constraint that it must be something stringable:

variable "memory" {
  type = any

  validation {
    condition     = can(tostring(var.memory))
    error_message = "The \"memory\" value must be a string."
  }
}

You'd then be able to set the environment variable either to a literal string expression or to null:

TF_VAR_memory='"foo"' # single quotes to escape the literal double quotes
TF_VAR_memory='null'

Terragrunt directly translates your inputs into TF_VAR_ statements. The examples above would translate to:

inputs = {
  memory = "\"foo\""
}
inputs = {
  memory = null
}

@denis256 denis256 moved this to To do in Terragrunt Roadmap Aug 3, 2023
@denis256 denis256 moved this from To do to In progress in Terragrunt Roadmap Aug 11, 2023
@denis256 denis256 self-assigned this Aug 11, 2023
@denis256 denis256 moved this from In progress to Review in progress in Terragrunt Roadmap Aug 11, 2023
@github-project-automation github-project-automation bot moved this from Review in progress to Done in Terragrunt Roadmap Aug 14, 2023
@dmatkovic
Copy link

Hello @denis256, thank you for the update. Just fetched the latest version of Terragrunt for our project and saw that terragrunt init now always generates an empty .terragrunt-null-vars.auto.tfvars.json file in the repository even though we are only using hcl configs for our projects without empty inputs. Is there an option to deactivate the generation of the file with the help of a cli-flag or configuration similar to the skip_region_validation when generating the provider block?

@denis256
Copy link
Member

Hello,
which issues cause having empty .terragrunt-null-vars.auto.tfvars.json ?

@grimm26
Copy link
Contributor

grimm26 commented Aug 16, 2023

Hello, which issues cause having empty .terragrunt-null-vars.auto.tfvars.json ?

that's the question, right? I started having that file show up with just {} in it, too. I don't know why. I'm going to just add it to .gitignore

@dmatkovic
Copy link

Hello @denis256, no immediate issue for the execution of the code but it would be nice if the generation could be skipped as described in #2670 so that not every terragrunt project in the future has to generate or ignore this file in the repository when there is no need for it in case of being empty.

@celsocoutinho-tangany
Copy link

Hello everyone, quick update on this issue. This is indeed a limitation of terraform. The variable loader for environment variables and -var command line options intentionally does not evaluate expressions like the tfvars file loader does. We had previously prototyped a solution that uses tfvars files, but that opens up security risks that are unacceptable for some of our customers. I'll be keeping an eye on the relevant terraform issue and will do what I can to get a solution pushed through.

Until then, there are a few workarounds mentioned in this issue. Alternately, if you have control of the module you are trying to use the terraform team suggested the following workaround:

Set the type constraint for the variable to type = any, which tells Terraform to expect a value of any type, and then use a custom validation rule to restore the constraint that it must be something stringable:

variable "memory" {
  type = any

  validation {
    condition     = can(tostring(var.memory))
    error_message = "The \"memory\" value must be a string."
  }
}

You'd then be able to set the environment variable either to a literal string expression or to null:

TF_VAR_memory='"foo"' # single quotes to escape the literal double quotes
TF_VAR_memory='null'

Terragrunt directly translates your inputs into TF_VAR_ statements. The examples above would translate to:

inputs = {
  memory = "\"foo\""
}
inputs = {
  memory = null
}

I am confused with this workaround...

Isn't it the case that it is not possible to use single quotes in terragrunt to define strings?

Isn't it the case that environment variables set externally of terragrunt, are not picked up by terraform?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug Something isn't working p:needs triage Needs to be processed by maintainer and issue type / priority added
Projects
Development

Successfully merging a pull request may close this issue.