-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
fix(terraform): hcl object expressions to return references #8271
base: main
Are you sure you want to change the base?
fix(terraform): hcl object expressions to return references #8271
Conversation
References included in hcl objects should be returned from 'Attribute.AllReferences()'. Traverse the object fields recursively to locate references.
@@ -971,6 +971,10 @@ func (a *Attribute) AllReferences(blocks ...*Block) []*Reference { | |||
func (a *Attribute) referencesFromExpression(expression hcl.Expression) []*Reference { | |||
var refs []*Reference | |||
switch t := expression.(type) { | |||
case *hclsyntax.ObjectConsExpr: | |||
for _, item := range t.Items { | |||
refs = append(refs, a.referencesFromExpression(item.ValueExpr)...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to use createDotReferenceFromTraversal
, not referencesFromExpression
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I modified a unit test.
This is an object that sets foo
to a conditional expression. That conditional expression has 2 references in it.
{foo = 1 == 1 ? var.bar : data.aws_ami.ubuntu.most_recent}
Maybe I am misunderstanding, but if I do
if ref, err := createDotReferenceFromTraversal(a.module, item.KeyExpr.Variables()...); err == nil {
refs = append(refs, ref)
}
// And do the same for the ValueExpression
I get variable.bar.data.aws_ami.ubuntu.most_recent
. Since Variables()
call just appends all traversal types:
https://github.com/hashicorp/hcl/blob/main/hclsyntax/variables.go#L18-L20
It is not intelligent to know the conditional expression has 2 different references, and just returns them as a single list. Rather than 2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikpivkin let me know I am misusing createDotReferenceFromTraversal
Hi @Emyrk! Thanks for contributing! Left a couple of comments. Also can you fix the linting issues? |
case *hclsyntax.ParenthesesExpr: | ||
refs = append(refs, a.referencesFromExpression(t.Expression)...) | ||
case *hclsyntax.ObjectConsKeyExpr: | ||
refs = append(refs, a.referencesFromExpression(t.Wrapped)...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using your example (local.foo): local.foo
, I also had to add these @nikpivkin
@nikpivkin unrelated, but is there a reason the underlying I was wondering if a getter like |
What's your use case for this? |
I am doing work on https://github.com/coder/coder. Terraform is the configuration language we use for the underlying developer workspaces. To give even more functionality/flexibility in the experience, we have a feature called "Build Parameters". See example image. In order to speed up some of the inner loop and provide more immediate feedback on these parameters, I am seeking to use static anaylsis of the terraform (using your package, which is awesome by the way ❤️). Now this is not perfect, if the parameters include a reference to an external data source ( I intend to use the existing terraform state to populate these unknown references in some second "pass/step". I do not see this package injesting a tfstate, so was going to build something to mutate the eval context. My usage of the specific functionality is data "coder_workspace_tags" "custom_workspace_tags" {
tags = {
// AllReferences() = [docker_image.ubuntu.repo_digest, docker_image.centos]
"foo" = docker_image.ubuntu.repo_digest
"bar" = docker_image.centos.repo_digest
"qux" = "quux"
}
} I am using So I can tell the reference To do this, I would either need to have the underlying I see additional value in exposing the |
Thanks for the explanation. I don't see anything inherently wrong with exposing it. WDYT @nikpivkin? |
Description
References included in hcl objects should be returned from
'Attribute.AllReferences()'
. Traverse the object fields recursively to locate references.Expressions such as:
Should return
variable.cache
in theAllReferences()
Checklist