Could we use if-conditional to apply argument ?
Example
main.tf
resource "google_compute_backend_service" "bs" {
...
if var.iaps == "true" then
iap {
oauth2_client_id = var.iapsid
oauth2_client_secret = var.iapssecret
oauth2_client_secret_sha256 = var.iaps256
}
fi
}
variables.tf
variable "iaps" { default = false }
terraform.tfvars
iaps = true
iapsid = "AAXX"
iapssecret = "1234AA"
iaps256 = "d3eb1a"
Result is the terraform will process the iap block argument, but if other developer set iaps to false then terraform will not apply iap block argument
Is there a way to do like above ?
I want to make terraform script customizable. So, i don’t need to create 2 different main.tf
Yes you can do that via the use of dynamic blocks.
In this case try something like:
dynamic "iap" {
for_each = var.iaps ? [""] : []
content {
oauth2_client_id = var.iapsid
oauth2_client_secret = var.iapssecret
oauth2_client_secret_sha256 = var.iaps256
}
}
1 Like
The way I’d write this is to make a single variable that can be null
to disable the feature altogether, like this:
variable "iap" {
type = object({
client_id = string
client_secret = string
client_secret_sha256 = string
})
default = null
}
resource "google_compute_backend_service" "bs" {
# ...
dynamic "iap" {
for_each = var.iap[*]
content {
oauth2_client_id = iap.value.client_id
oauth2_client_secret = iap.value.client_secret
oauth2_client_secret_sha256 = iap.value.client_secret_sha256
}
}
}
With the above configuration, if you leave iap
unset or explicitly set it to null
in your terraform.tfvars
file then Terraform will generate no iap
blocks at all, or you can write a valid iap
object in the terraform.tfvars
file to enable it:
iap = {
client_id = "AAXX"
client_secret = "1234AA"
client_secret_256 = "d3eb1a"
}
The example above relies on a special behavior of the [*]
operator: if it is applied to something that isn’t a list, it will either return a zero-element list or a one-element list depending on whether the operand is null
. That therefore makes it a concise way to convert from a value that could conditionally be null into the collection of zero or one elements which Terraform language repetition features expect.
1 Like
Thank you @stuart-c and @apparentlymart for enlightening me 
I tried both answers and it works.
Will bookmark this since i don’t find this way in tech article 
@stuart-c @apparentlymart would you like to share docs about [""]
or [*]
usage ?
Sorry, i am not familiar with terraform. Have been looking on docs and badluck for me 
Really appreciate for your time to help me for this.
Hi @merceskoba,
The [*]
operator is called the “splat” operator, and you can find documentation about it in the section Splat Expressions. In particular, the special behavior of turning a null value into an empty list is covered at the end of that section:
Splat expressions are for lists only (and thus cannot be used to reference resources created with for_each
, which are represented as maps in Terraform). However, if a splat expression is applied to a value that is not a list or tuple then the value is automatically wrapped in a single-element list before processing.
For example, var.single_object[*].id
is equivalent to [var.single_object][*].id
, or effectively [var.single_object.id]
. This behavior is not interesting in most cases, but it is particularly useful when referring to resources that may or may not have count
set, and thus may or may not produce a tuple value:
aws_instance.example[*].id
The above will produce a list of ids whether aws_instance.example
has count
set or not, avoiding the need to revise various other expressions in the configuration when a particular resource switches to and from having count
set.
The documentation talks about count
resources as its main example. It doesn’t talk about a variable that might be null
or not, but it’s a different application of the same behavior.
1 Like