Congratulations on the release of Terraform v0.12-alpha1 🎉
I have found some issues, so I will share it.
Terraform v0.12.0-alpha1
resource "aws_instance" "web" {
ami = "ami-12345678"
instance_type = "c3.2xlarge"
root_block_device = {
volume_size = "100"
}
ebs_block_device = {
device_name = "/dev/sdb"
volume_size = "24"
}
ebs_block_device = {
device_name = "/dev/sdk"
volume_size = "10"
}
}
There is no error when run terraform plan.
The following error will be reported:
$ terraform plan
Error: Attribute redefined
on instance.tf line 14:
14: ebs_block_device = {
The argument "ebs_block_device" was already set at instance.tf:9,3-19. Each
argument may be set only once.
Run terraform plan
Hi @wata727! Thanks for reporting this.
This is an interesting situation where there are two input problems here and HCL is, unfortunately, returning the less helpful one because it is the one it encountered first.
During _parsing_, the parser requires that each attribute definition in a body have a unique name. An attribute definition is a name, an equals sign, and an expression.
During _decoding_ -- extracting data from the parsed tree using schema -- the decoder would check to see that the given names are being used correctly.
The name ebs_block_device is defined as a nested block rather than an attribute, and so it must be defined _without_ the equals sign:
ebs_block_device {
device_name = "/dev/sdb"
volume_size = "24"
}
ebs_block_device {
device_name = "/dev/sdk"
volume_size = "10"
}
If you'd defined only one of these I believe Terraform would've produced a better error message explaining that ebs_block_device is a block rather than an attribute, but because parsing failed we did not reach that check.
This requirement to consistently use blocks vs. attributes is stricter than in prior versions because the parser needs this clue to determine whether to parse the following as a map expression or as a nested block. This is one of the consequences of expressions being first-class in HCL2, rather than always being given inside string interpolations with HIL.
In the final Terraform v0.12 release we will include a tool which will be able to fix this particular problem (amongst others) by rewriting the configuration to remove the equals signs.
For the moment I'm going to consider this issue to represent seeing if we can find a way to generate a better error message in this scenario. Unfortunately that is likely to be difficult to do without a significant change to handle duplicate attribute definitions at decode time rather than at parse time, but we'll investigate it and see what can be done.
Thanks again for trying out the alpha and reporting this!
Hi again, @wata727!
Unfortunately after some investigation I've concluded that we can't really improve on this error message without some serious code reorganization, and it would be too risky to do that when we're getting close to final release, so we're going to need to rely on the configuration upgrade tool to handle this situation.
The good news is that since I last commented an initial version of the upgrade tool is implemented. It's not totally finished yet, but it's able to fix up this particular situation. After running it on the configuration in the original comment here using v0.12.0-alpha4, it made these changes:
--- bad-equals-error.tf.orig 2018-12-17 13:17:11.701169326 -0800
+++ bad-equals-error.tf 2018-12-17 13:17:34.121973765 -0800
@@ -2,17 +2,18 @@
ami = "ami-12345678"
instance_type = "c3.2xlarge"
- root_block_device = {
+ root_block_device {
volume_size = "100"
}
- ebs_block_device = {
+ ebs_block_device {
device_name = "/dev/sdb"
volume_size = "24"
}
- ebs_block_device = {
+ ebs_block_device {
device_name = "/dev/sdk"
volume_size = "10"
}
}
After that, I was able to complete a terraform plan for this configuration successfully.
Although ideally we would've been able to improve the error message here, I think pragmatism requires us to rely on the upgrade tool for this particular situation, since it is at least a problem that is likely to only affect pre-existing configurations once our documentation and examples are updated to reflect the new requirements. I'm going to close this out now having verified that the upgrade tool is able to fix it.
Thanks again for reporting this!
Hey
I support one way for set block, but maybe need fixed this in https://github.com/hashicorp/hcl.
Because this print today in old style format
+1
same issue, not getting custom named device.
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Most helpful comment
Hi @wata727! Thanks for reporting this.
This is an interesting situation where there are two input problems here and HCL is, unfortunately, returning the less helpful one because it is the one it encountered first.
During _parsing_, the parser requires that each attribute definition in a body have a unique name. An attribute definition is a name, an equals sign, and an expression.
During _decoding_ -- extracting data from the parsed tree using schema -- the decoder would check to see that the given names are being used correctly.
The name
ebs_block_deviceis defined as a nested block rather than an attribute, and so it must be defined _without_ the equals sign:If you'd defined only one of these I believe Terraform would've produced a better error message explaining that
ebs_block_deviceis a block rather than an attribute, but because parsing failed we did not reach that check.This requirement to consistently use blocks vs. attributes is stricter than in prior versions because the parser needs this clue to determine whether to parse the following as a map expression or as a nested block. This is one of the consequences of expressions being first-class in HCL2, rather than always being given inside string interpolations with HIL.
In the final Terraform v0.12 release we will include a tool which will be able to fix this particular problem (amongst others) by rewriting the configuration to remove the equals signs.
For the moment I'm going to consider this issue to represent seeing if we can find a way to generate a better error message in this scenario. Unfortunately that is likely to be difficult to do without a significant change to handle duplicate attribute definitions at decode time rather than at parse time, but we'll investigate it and see what can be done.
Thanks again for trying out the alpha and reporting this!