Terraform.tmLanguage
Terraform.tmLanguage copied to clipboard
Aliased Terraform providers highlighted as if they are typos
Hi,
Since the 2.0.0 update, it seems like aliased provider inputs are being highlighted red, as if it is a typo:
providers = {
aws = aws.test
aws.secrets-manager = aws.secrets-manager
}
I assume this isn't intended.
More generally it occurs with any key name containing a period:
locals {
foo = {
bar.fizz = "buzz"
}
}
As far as I know this is valid Terraform: https://developer.hashicorp.com/terraform/language/modules/develop/providers#passing-providers-explicitly
Thank you 😄
Interesting, I have not seen this syntax before.
Trying to find the explanation of that in the syntax spec also does not reveal this to be valid.
- Attribute names must be an
Identifier(https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md#structural-elements) Identifierdoes not allow.(https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md#identifiers)
Is this perhaps a Terraform-specific expansion? Otherwise it might also be an undocumented feature.
Ah, I see now. This is not an attribute assignment inside a block but inside an object. Objects allow = and : as separators and the left-hand side can be an identifier or an expression, which is … terrible?
According to the docs, I would interpret an object written in the form { bar.fizz = "buzz" } to assign the value "buzz" to a key whose name is contained in bar.fizz.
The relevant syntax rules are as follows:
CollectionValue = tuple | object;
objectelem = (Identifier | Expression) ("=" | ":") Expression;
Identifier = ID_Start (ID_Continue | '-')*;
Expression = (
ExprTerm |
Operation |
Conditional
);
ExprTerm = (
LiteralValue |
CollectionValue |
TemplateExpr |
VariableExpr |
FunctionCall |
ForExpr |
ExprTerm Index |
ExprTerm GetAttr |
ExprTerm Splat |
"(" Expression ")"
);
VariableExpr = Identifier;
GetAttr = "." Identifier;
Is this how it behaves?
I guess so. I wouldn't have called an aliased provider config an expression but maybe my layman's definition of them doesn't match the hcl spec.
terraform apply
╷
│ Error: Reference to undeclared resource
│
│ on main.tf line 3, in locals:
│ 3: bar.fizz = "buzz"
│
│ A managed resource "bar" "fizz" has not been declared in the root module.
╵
If I define a resource and name it to match the left hand side it tells me to wrap it in parentheses or quotes:
terraform apply
╷
│ Error: Ambiguous attribute key
│
│ on main.tf line 3, in locals:
│ 3: aws_vpc.name = "buzz"
│
│ If this expression is intended to be a reference, wrap it in parentheses. If it's instead
│ intended as a literal name containing periods, wrap it in quotes to create a string
│ literal.
╵
So as a local it forces me to clarify, but the providers block is handled specially I suppose. The aliased provider config is quite unlike anything else I've seen in Terraform - I don't know of anywhere else where the left hand side can have a period like this.
FWIW, it looks like Terraform does allow me to replace the = with a : like any other object:
module "subdomain" {
source = "../../../modules/subdomain_delegation"
parent_zone_id = "dummy"
subdomain_prefix = "foobar"
providers = {
aws.parent : aws.test_1
aws.child : aws.test_2
}
}
Thanks for checking. I'll see if I can play around with this a bit myself before I implement it, but I'll be a bit short on time over the next weeks.