Skip to content

strip_string_quotes=True returns $${ and %%{ unresolved, so the value differs from Terraform's #336

Description

@livingstaccato

Summary

HCL's two template escapes, $${ and %%{, mean a literal ${ and %{.
strip_string_quotes=True asks for a string's value rather than its source,
and resolves \n, \r, \t, \", \\ and the unicode escapes -- but not
these two. The value therefore keeps a doubled sigil that Terraform does not.

Reproduction

import hcl2
from hcl2.utils import SerializationOptions

value = SerializationOptions(preserve_heredocs=False, strip_string_quotes=True)

hcl2.loads('a = <<EOT\n$${esc}\nEOT\n', serialization_options=value)["a"]  # '$${esc}'
hcl2.loads('a = <<EOT\n%%{d}\nEOT\n',  serialization_options=value)["a"]  # '%%{d}'
hcl2.loads('a = "$${esc}"\n',          serialization_options=value)["a"]  # '$${esc}'

OpenTofu evaluates the same three to "${esc}\n", "%{d}\n" and "${esc}".

Both string forms are affected, so the fix is not heredoc-specific: the quoted
form goes through StringRule.serialize (hcl2/rules/strings.py:115 at
v8.1.3, resolving escapes via _serialize_part_as_value at :133), the
heredoc form through HeredocTemplateRule.serialize (:164). Neither
consults the two template escapes; hcl2/utils.py:50 _SIMPLE_ESCAPES lists
the five backslash forms it does resolve.

Suggested shape of the fix

Resolve the two sequences wherever the value form is produced. $$ not
followed by { is literal in both implementations, and so is %% -- the rule
is exactly $${ and %%{, not the doubled sigil on its own.


This issue, and the investigation behind it, were produced by an AI assistant (Claude) working on behalf of the author. Please review with that provenance in mind.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions