I am trying to create Cloudwatch alarm but only if engine_mode variable equals to provisioned. length and lookup can’t work together. By default following statement create alarm regardless: count = local.instance_count < 1 ? 1 : local.instance_count
while this wants to destroy it if it is set to provisioned: count = local.instance_count < 1 || (local.instance_count >= 1 && local.engine_mode == "provisioned") ? 1 : 0
It sounds like you have this code split across two modules, with one element from environment_vars being passed into the child module to become var.configuration.
If you haven’t already, I’d suggest writing an explicit object type constraint for that input variable so that Terraform has more information about what you’re intending to do, and so can hopefully give you some more direct feedback if something is missing:
Using optional attributes with defaults as I’ve shown here will also remove the need to define local values to deal with the attributes not being set, because Terraform will automatically set them to the default values as the object enters the module.
I’m suggesting this because I think the problem is in some of the intermediate code you haven’t shared. Perhaps the variable declaration has an incomplete type constraint and so your objects never have instance_count attributes, for example. I’m hoping that what I’ve suggested here will either make it work as you expected immediately or will cause Terraform to return an error message that will give a better clue as to what’s missing from your configuration.
You are using this data structure as if it is an object with specific attribute names and each attribute having its own type, so you should declare the variable as being of an object type, not as map(string).
Here is the a declaration based on the attribute names I can see in your other snippets:
If you don’t properly describe the data types that you are working with then Terraform can make incorrect assumptions about what you intended, leading to confusing error messages or unexpected behavior.
Once you have your variable’s type constraint declared correctly, I think you’ll be able to incorporate the extra rule about engine_mode (that you described in your original post) like this:
var.configuration_engine_mode == "provisioned" ? ... : 0 forces the result to be zero if the engine_mode is anything other than "provisioned".
max(var.configuration.instance_count, 1) chooses the largest value of the two arguments. That means that if var.configuration.instance_count is less than 1 then the result will be 1, because that will be the larger of the two values.
Notice that with the variable declared properly as having an object type it’s not necessary to use lookup, because Terraform guarantees that all of the declared attributes will always be present and will insert the default values for optional attributes automatically where necessary.