terraform
terraform copied to clipboard
`yamldecode()` should support files with `%YAML 1.2` directive
Terraform Version
Terraform v1.7.3
on darwin_arm64
Terraform Configuration Files
locals {
doc = <<EOT
%YAML 1.2
---
root:
key: value
EOT
val = yamldecode(local.doc)["root"]["key"]
}
output "val" {
value = local.val
}
Debug Output
https://gist.github.com/asaba-hashi/bb070ec6caadf4c588209cbd2350344c
Expected Behavior
The "doc" contents should be correctly parsed as YAML.
Changes to Outputs:
+ val = "value"
Actual Behavior
terraform reported an error
╷
│ Error: Error in function call
│
│ on test.tf line 8, in locals:
│ 8: val = yamldecode(local.doc)["root"]["key"]
│ ├────────────────
│ │ while calling yamldecode(src)
│ │ local.doc is "%YAML 1.2\n---\nroot:\n key: value\n"
│
│ Call to function "yamldecode" failed: found incompatible YAML document.
Steps to Reproduce
-
terraform init
-
terraform plan
Additional Context
YAML 1.2 introduces the %YAML
directive to direct parsers to treat the document as version 1.1 or 1.2.
In particular, YAML 1.2 introduces a Failsafe Schema that does not include the additional "truthy" values like on
, no
etc. , so this may be the path towards fixes/workarounds for problems like #34611. The workaround would be for such documents to include a %YAML 1.2
directive.
References
No response
Thanks for this feature request! If you are viewing this issue and would like to indicate your interest, please use the 👍 reaction on the issue description to upvote this issue. We also welcome additional use case descriptions. Thanks again!
The YAML 1.2 spec says:
A version 1.2 YAML processor must accept documents with an explicit “%YAML 1.2” directive, as well as documents lacking a “YAML” directive. Such documents are assumed to conform to the 1.2 version specification.
While the docs for yamldecode
do say that only a "limited" portion of 1.2 is supported, the parser is behaving more like 1.1 parser, so I do still think this is a bug (whether in the docs or implementation), WDTY?
Here is a workaround for interoperating where you can work with strictly 1.1 docs, which will work with a more compliant parser/encoder like raumel.yaml
s roundtrip encoder:
locals {
doc = <<EOT
%YAML 1.1
---
root:
notaboolvalue: 'no'
'no': no
EOT
val1 = yamldecode(trimprefix(local.doc, "%YAML 1.1\n"))["root"]["no"]
val2 = yamldecode(trimprefix(local.doc, "%YAML 1.1\n"))["root"]["notaboolvalue"]
}
output "notaboolkey" {
value = local.val1
}
output "notaboolvalue" {
value = local.val2
}
The enhancement determination was made due to the "limited" disclaimer in the docs, so the thought in triage with @apparentlymart is that any increase in functionality is a new feature (otherwise it would just be documented as supported). Thanks for the work-around!