Skip to content

Conversation

wata727
Copy link
Member

@wata727 wata727 commented Jul 6, 2025

Fixes #165

This PR adds the expr type as a schema type. The expr type differs from other types in that they do not immediately evaluate a value but instead return an expression structure. For example:

variable "instance_type" {
  default = "t2.micro"
}

resource "aws_instance" "main" {
  instance_type = var.instance_type
}

string type

terraform.resources("aws_instance", {"instance_type": "string"}, {})
[
  {
    "type": "aws_instance",
    "name": "main",
    "config": {
      "instance_type": {
        "value": "t2.micro",
        "unknown": false,
        "sensitive": false,
        "ephemeral": false,
        "range": {...}
      }
    },
    "decl_range": {...}
  }
]

expr type

terraform.resources("aws_instance", {"instance_type": "expr"}, {})
[
  {
    "type": "aws_instance",
    "name": "main",
    "config": {
      "instance_type": {
        "value": "var.instance_type",
        "range": {...}
      }
    },
    "decl_range": {...}
  }
]

From the above, you can see that the expression representation (var.instance_type) is returned, not the result of evaluating var.instance_type (t2.micro). Note that attributes such as unknown are undefined because the expression has not been evaluated.

This is useful for writing policies over expression structures. For example, the expr type is the only way to handle meta-arguments such as ignore_changes that cannot be evaluated in the normal way.

The expression obtained by the expr type can be passed to the introduced hcl.expr_list, hcl.expr_map, and hcl.expr_call functions in this PR to perform static analysis of the expression structure. These functions are wrappers around HCL static analysis functions. For example, you can use hcl.expr_list to check for references in ignore_changes:

resource "aws_instance" "main" {
  lifecycle {
    ignore_changes = [key_name, tags]
  }
}
resources := terraform.resources("*", {"lifecycle": {"ignore_changes": "expr"}}, {"expand_mode": "none"})
ignore_changes := resources[i].config.lifecycle[j].config.ignore_changes

# Does "ignore_changes" have "tags"?
some k
hcl.expr_list(ignore_changes)[k].value == "tags"

We have deliberately not introduced functions for static traversal. Perhaps you will need an API like lang.ReferencesInExpr, but it is not yet clear what kind of API you will need, so we will consider adding it upon request.

@wata727 wata727 force-pushed the add_expr_type branch 3 times, most recently from 20fc994 to 8dd2eaf Compare July 12, 2025 15:46
@wata727 wata727 marked this pull request as ready for review July 13, 2025 12:58
@wata727 wata727 merged commit bc9316d into main Jul 13, 2025
11 checks passed
@wata727 wata727 deleted the add_expr_type branch July 13, 2025 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Support for terraform meta arguments
1 participant