hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io
Other
42.76k stars 9.56k forks source link

terraform fmt produces incorrect indents for resource properties after heredoc with templating #35645

Open VladRassokhin opened 2 months ago

VladRassokhin commented 2 months ago

Terraform Version

Terraform v1.9.5
on darwin_arm64

Terraform Configuration Files

resource "aws_instance" "test" {
  user_data = <<EOF
#!/bin/bash
${templatefile("${path.module}/userdata.sh", {
  var = local.var
})}
EOF

  root_block_device {
    volume_size           = var.disk_size
    delete_on_termination = true
  }
}

Debug Output

https://gist.github.com/VladRassokhin/baa20d094a8de5b8a09610e1bb930cf2

Expected Behavior

Indentation of root_block_device kept as is.

Actual Behavior

Indentation changes to:

resource "aws_instance" "test" {
  user_data = <<EOF
#!/bin/bash
${templatefile("${path.module}/userdata.sh", {
  var = local.var
})}
EOF

root_block_device {
  volume_size           = var.disk_size
  delete_on_termination = true
}
}

Steps to Reproduce

terraform fmt -write=true test.tf

Additional Context

Removing templating from the heredoc or removing {} from templatefile helps.

References

No response

crw commented 2 months ago

Thanks for this report!

bschaatsbergen commented 1 month ago

Hi @VladRassokhin,

Thank you for reporting this issue. The formatter implemented in Terraform wraps around formatting logic found in hclwrite, specifically, hclwrite.ParseConfig to offload most of its work to. Most HashiCorp products—if not all—differ slightly from native HCL and build their own DSL on top of it. As a result, they also implement their own formatters, such as terraform fmt, to adjust the given HCL to meet Terraform’s canonical style.

Apart from the formatting done through hclwrite.ParseConfig, Terraform's formatter extends the formatting logic to some Terraform native formatting rules. Think of normalizing tokens by reformatting attribute expressions, formatting type expressions and formatting labels for consistency.

From what I'm observing, this is an issue in the upstream hclwrite package. An example of how to reproduce the issue: https://gist.github.com/bschaatsbergen/ae4eca083250b4dd71aa426e089ab71c. This serves as mainly a note for myself and the team, but feel free to take a look if you’re interested.

Since I'm still getting familiar with the formatting changes made by hclwrite, I’ll need some time to investigate further and understand the underlying reasons. Thank you for your patience!

Also, I’m tagging this issue with the ‘hcl’ label since it appears to be an issue in hclwrite. Given that this is still a valid issue in Terraform, as we rely on hclwrite for the initial pass of surgical changes, I would be more than happy to address it here, but I defer to @crw and the team on this.