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

lang/funcs: Allow some more expression types in templatestring #35285

Merged
merged 1 commit into from
Jun 3, 2024

Conversation

apparentlymart
Copy link
Contributor

@apparentlymart apparentlymart commented Jun 3, 2024

The templatestring function has some special constraints on its first argument that are included to add some intentional friction for those who are new to Terraform, want to do some simple template rendering, but have only found the templatestring function so far.

We know from previous experience with the hashicorp/template provider that this sort of functionality tends to attract those who haven't yet learned that the Terraform language has built-in support for string templates (without calling any function), who would then get confused by the need for an extra level of escaping to render a template string only indirectly through this function and waste time trying to get that to work, rather than looking for the better alternatives.

However, this rule is not intended to be onerous and require writing the rest of the containing module in an unnatural way to work around it, so here we loosen the rule to allow some additional forms:

  • An index expression whose collection operand meets these rules.
  • A relative traversal whose source operand meets these rules.

In particular this makes it possible to write an expression like:

data.example.example[each.key].result

...which is a relative traversal from an index from a scope traversal, and is a very reasonable thing to write if you've retrieved multiple templates using a data resource that uses for_each, as described in #35274. Although it's possible to write a working example today, it requires some non-trivial contortion of the code surrounding the templatestring call, which is too onerous for this reasonable common case.

This also treats splat expressions in the same way as index expressions at the static check stage, but that's only to allow us to reach the dynamic type check that will ultimately report that a string is required, because the result of a splat expression is a tuple. The type-related error message is (subjectively) more helpful/relevant than the syntax-related one for this case.

Finally, this includes some revisions to the documentation for this function to correct some editing errors from the first pass and to slightly loosen the language about what's allowed. It's still a little vague about what exactly is allowed, but I'm doubtful that a precise definition in terms of HCL's expression types would be very enlightening for a typical reader anyway. We can tweak the specificity of the language here if we start to see repeated questions about what is and is not valid.

This closes #35274.

The templatestring function has some special constraints on its first
argument that are included to add some intentional friction for those who
are new to Terraform, want to do some simple template rendering, but have
only found the templatestring function so far.

We know from previous experience with the hashicorp/template provider that
this sort of functionality tends to attract those who haven't yet learned
that the Terraform language has built-in support for string templates
(without calling any function), who would then get confused by the need
for an extra level of escaping to render a template string only indirectly
through this function.

However, this rule is not intended to be onerous and require writing the
rest of the containing module in an unnatural way to work around it, so
here we loosen the rule to allow some additional forms:
 - An index expression whose collection operand meets these rules.
 - A relative traversal whose source operand meets these rules.

In particular this makes it possible to write an expression like:
    data.example.example[each.key].result
...which is a relative traversal from an index from a scope traversal,
and is a very reasonable thing to write if you've retrieved multiple
templates using a data resource that uses for_each.

This also treats splat expressions in the same way as index expressions
at the static check stage, but that's only to allow us to reach the
dynamic type check that will ultimately report that a string is required,
because the result of a splat expression is a tuple. The type-related
error message is (subjectively) more helpful/relevant than the
syntax-related one for this case.

Finally, this includes some revisions to the documentation for this
function to correct some editing errors from the first pass and to slightly
loosen the language about what's allowed. It's still a little vague about
what exactly is allowed, but I'm doubtful that a precise definition in
terms of HCL's expression types would be very enlightening for a typical
reader anyway. We can tweak the specificity of the language here if we
start to see repeated questions about what is and is not valid.
@apparentlymart apparentlymart added enhancement config functions 1.9-backport If you add this label to a PR before merging, backport-assistant will open a new PR once merged labels Jun 3, 2024
@apparentlymart apparentlymart requested a review from a team June 3, 2024 16:33
@apparentlymart apparentlymart self-assigned this Jun 3, 2024
@apparentlymart apparentlymart merged commit e23e6b8 into main Jun 3, 2024
11 checks passed
Copy link

github-actions bot commented Jun 3, 2024

Reminder for the merging maintainer: if this is a user-visible change, please update the changelog on the appropriate release branch.

Copy link

github-actions bot commented Jul 5, 2024

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
1.9-backport If you add this label to a PR before merging, backport-assistant will open a new PR once merged config enhancement functions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

templatestring function allow for_each
2 participants