Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native Terraform/OpenTofu function templatestring() does not work in Terragrunt as a builtin function. #3242

Open
Jpk518 opened this issue Jul 4, 2024 · 9 comments
Assignees
Labels
bug Something isn't working terragrunt

Comments

@Jpk518
Copy link

Jpk518 commented Jul 4, 2024

Describe the bug

A new function templatestring() was added in Terraform 1.9 and Opentofu 1.7. This New function does not work when attempting to use in terragrunt as a built-in function https://terragrunt.gruntwork.io/docs/reference/built-in-functions/#terraform-built-in-functions, both when using the Terraform binary and the OpenTofu binary.

Steps To Reproduce

Define locals block that uses function templatestring().

example/terragrunt.hcl:

locals {
  template = "$${stage}-test"
  name = templatestring(local.template, { stage = "staging" } )
}

inputs = {
  name = local.name
}

example/main.tf:

variable "name" {}

resource "aws_sqs_queue" "example" {
  name  = var.name
}

Expected behavior

Here is the expected behaviour

$ terragrunt init

OpenTofu has been successfully initialized!

Here is the actual behaviour

$ terragrunt init

ERRO[0000]   on /.../example/terragrunt.hcl line 7, in locals: 
ERRO[0000]    7:   name     = templatestring(local.template, { stage = "staging" }) 
ERRO[0000]                                              
ERRO[0000] with                                         
ERRO[0000] local.template as "${stage}-test"  

ERRO[0000] There is no function named "templatestring".

Versions

  • Terragrunt version: v0.59.6
  • OpenTofu Version: v1.7.2
  • Terraform version: v1.9.2

Additional context

Function works properly when defined directly in .tf file using opentofu/terraform

example/main.tf:

locals {
  template = "$${stage}-test"
  name = templatestring(local.template, { stage = "staging" } )
}

resource "aws_sqs_queue" "test" {
  name = local.name
}
$ terragrunt init

OpenTofu has been successfully initialized!
@Jpk518 Jpk518 added the bug Something isn't working label Jul 4, 2024
@ZachGoldberg ZachGoldberg added the terragrunt label Jul 9, 2024 — with Linear
@levkohimins levkohimins self-assigned this Jul 9, 2024
@begemotik
Copy link

@levkohimins would be wonderful to get it supported in Terragrunt. Do you have an estimation?

@yhakbar
Copy link
Collaborator

yhakbar commented Oct 17, 2024

Hey @begemotik , this is a good request, but not a priority right now.

Could you provide any reasons why this should be prioritized higher? I imagine most folks needing this functionality would simply use run_cmd right now.

@Jpk518
Copy link
Author

Jpk518 commented Oct 17, 2024

Hey @begemotik , this is a good request, but not a priority right now.

Could you provide any reasons why this should be prioritized higher? I imagine most folks needing this functionality would simply use run_cmd right now.

Is it possible to update the documentation if going forward Terragrunt doesn't plan to support all built in Opentofu/Terraform functions. Can lead to a little confusion https://terragrunt.gruntwork.io/docs/reference/built-in-functions/#opentofuterraform-built-in-functions

@yhakbar
Copy link
Collaborator

yhakbar commented Oct 17, 2024

Is it possible to update the documentation if going forward Terragrunt doesn't plan to support all built in Opentofu/Terraform functions.

Sure thing, I can update that.

To be clear, we're not refusing to support this, we're just trying to prioritize effectively. If there's a use-case that requires this behavior, we can look at prioritizing it.

@begemotik
Copy link

Could you provide any reasons why this should be prioritized higher? I imagine most folks needing this functionality would simply use run_cmd right now.

We manage multiple ASGs within one TF state and need to be able to re-use one config template for different cases.
There is another case I can imagine with "generate" block and dynamic providers rendering.

We haven't tried run_cmd, I might be mistaken but it occurs to be that run_cmd would be hard to re-use across many states as it references local file.

run_cmd(command, arg1, arg2…​) runs a shell command and returns the stdout as the result of the interpolation. The command is executed at the same folder as the terragrunt.hcl file

@ThisGuyCodes
Copy link

We're a current Gruntwork subscriber and we have a need for this now.

We have a template string defined in an _envcommon module, and the variables to flesh it out are defined in the downstream instances. Ideally we could use templatestring to make the downstream use look like this:

templatestring(include.envcommon.locals.template, {
  env   = local.env
  other = local.other
})

Without this we're using format, which requires some ugly and error prone repetition:

format(include.envcommon.locals.template,
  local.env,
  local.other,
  local.env,
  local.other,
  local.env,
  local.other,
)

templatestring would allow us to use the same values in the template multiple times, and allow for a keyword based input rather than positional.

@yhakbar
Copy link
Collaborator

yhakbar commented Jan 14, 2025

Hey @ThisGuyCodes ,

I see that you do have a very practical need for templatestring, and I'll share some thoughts regarding the challenge of supporting it.

There is a workaround

For basically any gap in HCL functionality that you might have, there is the escape hatch of run_cmd. It'll let you execute arbitrary commands in order to get some value that you need, so you can write-up a bash script, use something like envsubst or boilerplate to template out strings that you might need.

I know this is not always an optimal solution, but we are a little constrained otherwise.

We cannot use OpenTofu/Terraform built-in functions as a library

This might change in the future for OpenTofu, but right now, implementations for OpenTofu HCL functions are in internal, and thus not exported for re-use outside the project. As a result, the best we can do is implement something net-new on our own for now.

Building an alternative to templatestring in Terragrunt isn't high priority right now

The availability of a different function that is very explicitly not templatestring (e.g. template_to_string) in Terragrunt is something that users have workarounds for, as you mentioned with templatestring and run_cmd for more advanced cases.

If we were to introduce a net-new function with novel implementation for Terragrunt, it would be in collaboration with the community to work out the right API, figure out the best patterns for use in Terragrunt and drive implementation.

I would also point out that we wouldn't want to implement anything too close to templatestring, as:

  1. The templatestring function might change in the future, and we wouldn't want to try to preserve any kind of parity there.
  2. The OpenTofu team might decide to export their HCL functions as a library, which we would wholeheartedly integrate with high priority.

Hopefully this gives insight as to the complications inherent to this issue.

@ThisGuyCodes
Copy link

Thanks for that suggestion @yhakbar. I did actually go down this path a bit for a few things, but ran into a blocking bug (or maybe undesired behavior?), which breaks pipelines: #3850

@yhakbar
Copy link
Collaborator

yhakbar commented Feb 7, 2025

@ThisGuyCodes

Take a look at my response on the issue. Let me know if that helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working terragrunt
Projects
None yet
Development

No branches or pull requests

6 participants