Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform variable to assign using function

variable "cidr" {
  type = map(string)
  default = {
      development = "x.1.0.0/16"
      qa = "x.1.0.0/16"
      default = "x.1.0.0/16"
  }
} 
variable "network_address_space" {
  default = lookup(var.cidr, var.environment_name,"default")
}

Am getting error that "Error: Function calls not allowed"

variable "subnet_address_space": cidr_subnet2_address_space = cidrsubnet(var.network_address_space,8,1)
like image 322
Jithin Kumar S Avatar asked Jan 26 '23 07:01

Jithin Kumar S


1 Answers

A Terraform Input Variable is analogous to a function argument in a general-purpose programming language: its value comes from an expression in the calling module, not from the current module.

The default mechanism allows us to substitute a value for when the caller doesn't specify one, but because variables are intended for getting data into a module from the outside, it doesn't make sense to set the default to something from inside that module: that would cause the result to potentially be something the caller of the module could never actually specify, because they don't have access to the necessary data.

Terraform has another concept Local Values which are roughly analogous to a local variable within a function in a general-purpose programming language. These can draw from function results and other objects in the current module to produce their value, and so we can use input variables and local values together to provide fallback behaviors like you've illustrated in your question:

var "environment_name" {
  type = string
}

var "environment_default_cidr_blocks" {
  type = map(string)
  default = {
      development = "10.1.0.0/16"
      qa          = "10.2.0.0/16"
  }
}

var "override_network_range" {
  type    = string
  default = null   # If not set by caller, will be null
}

locals {
  subnet_cidr_block = (
    var.override_network_range != null ?
    var.override_network_range :
    var.environment_default_cidr_blocks[var.environment_name]
  )
}

Elsewhere in the module you can use local.subnet_cidr_block to refer to the final CIDR block selection, regardless of whether it was set explicitly by the caller or by lookup into the table of defaults.

When a module uses computation to make a decision like this, it is sometimes useful for the module to export its result as an Output Value so that the calling module can make use of it too, similar to how Terraform resources also export additional attributes recording decisions made by the provider or by the remote API:

output "subnet_cidr_block" {
  value = local.subnet_cidr_block
}
like image 57
Martin Atkins Avatar answered Jan 31 '23 15:01

Martin Atkins