Introduction
In Terraform language semantics, reference expressions are var.<NAME>, local.<NAME>, <RESOURCE TYPE>.<NAME>, etc., all consisting of multiple traversals including the attribute access operator.
However, some non-reference expressions may consist of root-only traversals. e.g.
resource "azurerm_linux_web_app_slot" "test" {
lifecycle {
ignore_changes = [
tags # root-only traversal
]
}
}
[for s in var.list : upper(s)] # "s" is root-only traversal
resource "aws_lambda_function" "example" {
lifecycle {
action_trigger {
events = [after_create, after_update] # root-only traversal
actions = [action.aws_lambda_invoke.example]
}
}
}
In particular, meta-arguments such as lifecycle are parsed as special attributes in Terraform, so they cannot be parsed as normal attributes. Specifically, an error may occur when retrieving them with the GetResourceContent API. See #2431
Proposal
Here are some options:
1. Allow root-only traversal expressions as reference expressions
Expressions like tags are inherently invalid in Terraform language semantics, but TFLint treats them as valid expressions. Their value always resolves to an unknown value.
This will likely reduce the chance of plugin developers encountering "surprising" behavior in many cases, but I'm not sure that always resolving to an unknown value is useful. For example, ignore_changes can be retrieved using the GetResourceContent API, but the "value" of these expressions is undefined. However, plugin developers can extract values that look reasonable.
Considering a valid situation, there are times when you just want to extract an hcl.Expression. In TFLint, blocks are expanded in advance and the expression is evaluated at that time, so there is an issue with evaluation errors even if you are not interested in the value of the meta-argument. Here is an example attempt by #2434.
This approach may solve terraform-linters/tflint-plugin-sdk#339 as a side effect.
2. Add APIs for handling meta-arguments
Add APIs like GetResourceLifecycle and prohibit getting meta-arguments in GetResourceContent.
This approach is most aligned with Terraform language semantics and may give you more flexibility in handling meta-arguments. However, the meta-argument schema varies between Terraform versions, so some effort is required to make it robust.
3. Ignore root-only traversal expressions during expression expansion
This is based on the approach in #2434, only ignoring it when expanding blocks, since most issues are likely to occur when expanding blocks.
However, this approach is a workaround compared to options 1 and 2, so I believe it would be better to consider options 1 and 2.
References
Introduction
In Terraform language semantics, reference expressions are
var.<NAME>,local.<NAME>,<RESOURCE TYPE>.<NAME>, etc., all consisting of multiple traversals including the attribute access operator.However, some non-reference expressions may consist of root-only traversals. e.g.
In particular, meta-arguments such as
lifecycleare parsed as special attributes in Terraform, so they cannot be parsed as normal attributes. Specifically, an error may occur when retrieving them with theGetResourceContentAPI. See #2431Proposal
Here are some options:
1. Allow root-only traversal expressions as reference expressions
Expressions like
tagsare inherently invalid in Terraform language semantics, but TFLint treats them as valid expressions. Their value always resolves to an unknown value.This will likely reduce the chance of plugin developers encountering "surprising" behavior in many cases, but I'm not sure that always resolving to an unknown value is useful. For example,
ignore_changescan be retrieved using theGetResourceContentAPI, but the "value" of these expressions is undefined. However, plugin developers can extract values that look reasonable.Considering a valid situation, there are times when you just want to extract an
hcl.Expression. In TFLint, blocks are expanded in advance and the expression is evaluated at that time, so there is an issue with evaluation errors even if you are not interested in the value of the meta-argument. Here is an example attempt by #2434.This approach may solve terraform-linters/tflint-plugin-sdk#339 as a side effect.
2. Add APIs for handling meta-arguments
Add APIs like
GetResourceLifecycleand prohibit getting meta-arguments inGetResourceContent.This approach is most aligned with Terraform language semantics and may give you more flexibility in handling meta-arguments. However, the meta-argument schema varies between Terraform versions, so some effort is required to make it robust.
3. Ignore root-only traversal expressions during expression expansion
This is based on the approach in #2434, only ignoring it when expanding blocks, since most issues are likely to occur when expanding blocks.
However, this approach is a workaround compared to options 1 and 2, so I believe it would be better to consider options 1 and 2.
References