Terraform: Enable substr to handle shorter strings

Created on 7 Aug 2017  ·  15Comments  ·  Source: hashicorp/terraform

Related to issue #1431, having a way to truncate a string to a given length is very useful, especially for names that cannot be more than x characters long (such as AWS Application Load Balancers) when the name will be assembled from multiple other variables (such as "alb-${var.app_name}-${var.app_env}"). However, the substr function currently chokes on strings that are already within the given constraint.

Terraform Version

0.9.11

Expected Behavior

A call to substr with a string shorter than the index+length specified should simply return the given string. Example substr("abc", 0, 5).

Actual Behavior

Error message:

'offset + length' cannot be larger than the length of the string

Steps to Reproduce

  1. Run terraform console.
  2. Run substr("abcdef", 0, 5) and see expected result of abcde.
  3. Run substr("abc", 0, 5) and see error message (rather than expected result of abc).

References

Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here?

  • GH-1431
config enhancement

Most helpful comment

forgive me, @forevermatt! It looks like I was a bit overzealous in mentioning that comment elsewhere. There was a duplicate ticket asking for a substr function, so I referenced the solution on that ticket. It would appear I didn't read this one closely enough! 😆

Ironically, I too would like the functionality you're asking for! My workaround:

substr("${local.prefix}", 0, min(19, length(local.prefix)))

All 15 comments

I'm currently using essentially the following to limit the length of our AWS ALB Target Group names, through it seems a touch more complicated (= less readable) than substr would be:

"${replace("tg-${var.idp_name}-${var.app_name}-${var.app_env}", "/(.{0,32})(.*)/", "$1")}"

Thanks for this request, @forevermatt.

This seems reasonable to me. Generating an error when offset is greater than the length is desirable, I think, since it is likely indicative of a mistake. But requesting more characters than remain in the string is a perfectly reasonable thing to do for the reason you gave here.

+1

@nathanielks Thanks for your interest in this issue. Would you mind clarifying why you referenced that comment? It looks like that is merely pointing at the existence of the substr() function, whereas this issue is requesting that substr() be enhanced to better handle short input strings.

forgive me, @forevermatt! It looks like I was a bit overzealous in mentioning that comment elsewhere. There was a duplicate ticket asking for a substr function, so I referenced the solution on that ticket. It would appear I didn't read this one closely enough! 😆

Ironically, I too would like the functionality you're asking for! My workaround:

substr("${local.prefix}", 0, min(19, length(local.prefix)))

No problem 🙂

+1 on this, i can understand the intention but in many practical use cases this should not break the build because there's not enough characters. Sometimes this is just to enforce the api restriction when dealing with dynamic variables that get passed through. I just ran into this same issue with the elastic cache cluster limit of only 20 characters and now have a unique variable to define the cluster, which follows no convention.

thanks, hope to see this improved.

edit: improved words

I ran into this as well today, would love to see this addition to terraform

I also ran into this today. Keen to learn some Go (Terraform is implemented in Go right?) so may try and work out how to contribute. Don't know what I am up against yet but will see if I can work it out.

@dnk8n I didn't know any Go before contributing to Terraform, but it's (Terraform) designed well that it's semi easy to pick it up/interact with Terraform. Give it a... Go :trollface:

Hi all!

While this sort of change would normally be a pretty nice introduction to Terraform development, unfortunately right now we're working in a feature branch that refactors how the interpolation functions are implemented, and so the implementations in the master branch will be deleted once that branch is merged.

Fortunately, from a quick check I think that this issue has been addressed already (when we wrote the new implementation of substr we wrote it without the length check mentioned here), so this should be addressed in the next major release. Since the development for that has not landed on master yet, I'll leave this open for now as a reminder to verify the behavior as part of the preparation for the release once the branch has been merged.

Good to hear, thanks @apparentlymart!

Hi all!

I've just verified this in the v0.12.0-alpha4 prerelease build, using the following configuration:

locals {
  str = "abc"
}

output "shorter" {
  value = substr(local.str, 0, 2)
}

output "equal" {
  value = substr(local.str, 0, 3)
}

output "longer" {
  value = substr(local.str, 0, 4)
}

This successfully produced the following output values, as expected:

equal = abc
longer = abc
shorter = ab

This functionality is now in the master branch ready to be included in the forthcoming v0.12.0 release, so I'm going to close this out. Thanks for requesting this, and sorry for the delay in getting it implemented!

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings