Help fix replace

hello, sorry but I’m noob about terraform
I’m using

source  = "hashicorp/aws"
version = "~> 5.0"

I have this code:

family       = contains(var.engine, "-cdb-") ? replace(var.engine, "-cdb-", "") : lookup([for sg in var.database_parameters : sg if sg.fullname == var.engine][0], "family", "")

the idea is if var.engine contains word “-cdb-” then use whatever is in var.engine but remove word “-cdb-” from it, if does not contains word “-cdb-” then use this:

lookup([for sg in var.database_parameters : sg if sg.fullname == var.engine][0],"family","")

example: var.cluster=postgres16 then family=postgresql16
another one, var.cluster=oracle-ee-cdb-19 then family=oracle-ee-19

but I’m getting this error:

│ Error: Error in function call
│
│   on paramgroup.tf line 46, in resource "aws_db_parameter_group" "rds_instance_parameter_group":
│   46:   family       = contains(var.engine, "-cdb-") ? replace(var.engine, "-cdb-", "") : lookup([for sg in var.database_parameters : sg if sg.fullname == var.engine][0], "family", "")
│     ├────────────────
│     │ while calling contains(list, value)
│     │ var.engine is "oracle-ee-cdb-19"
│
│ Call to function "contains" failed: argument must be list, tuple, or set.

and to be honest I tried a lot of ways but still not working, if anyone know I really appreciate… thanks!

Hi @csandovalh!

I think the problem is that you’ve used the contains function which is for checking if a particular element exists in a list, rather than whether a particular substring exists in another string.

However, Terraform has a separate strcontains function which I think matches what you were intending:

strcontains(var.engine, "-cdb-")

I think you would also need to remove one of the dashes from your replace call:

replace(var.engine, "-cdb", "")

…because otherwise you’d transform oracle-ee-cdb-19 into oracle-ee19, by removing both of the dashes.

yeah you are correct only one -
change to this

family       = strcontains(var.engine, "-cdb") ? replace(var.engine, "-cdb", "") : lookup([for sg in var.database_parameters : sg if sg.fullname == var.engine][0], "family", "")

but I think something is missing or I’m using it the wrong way

│ Error: Call to unknown function
│
│   on paramgroup.tf line 46, in resource "aws_db_parameter_group" "rds_instance_parameter_group":
│   46:   family       = strcontains(var.engine, "-cdb") ? replace(var.engine, "-cdb", "") : lookup([for sg in var.database_parameters : sg if sg.fullname == var.engine][0], "family", "")
│     ├────────────────
│     │ var.engine is a string
│
│ There is no function named "strcontains".

Hi @csandovalh,

I’m afraid I can’t explain why you recieved that error. I tried to reproduce your result using a simplified configuration that doesn’t include any resources:

variable "engine" {
  type = string
  default = "oracle-ee-cdb-19"
}

variable "database_parameters" {
  type = list(object({
    fullname = string
  }))
  default = []
}

output "family" {
  value = strcontains(var.engine, "-cdb") ? replace(var.engine, "-cdb", "") : lookup([for sg in var.database_parameters : sg if sg.fullname == var.engine][0], "family", "")
}

For my output "family" value I copied the expression from your error message exactly, so I would expect my system to evaluate this in the same way yours does.

But for me it succeeds:

$ terraform apply -auto-approve

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

family = "oracle-ee-19"

The only idea I have is that perhaps you are using an old version of Terraform. The strcontains function was added in Terraform v1.5, so you will need to use at least that version to use this function.

thank you very much, strcontains was the solution, and error was due old version :frowning:
thanks again for your help.