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.73k stars 9.55k forks source link

terraform fmt: align equals sign even when the expression is split over multiple lines #34760

Open Joren-Thijs opened 8 months ago

Joren-Thijs commented 8 months ago

Terraform Version

Terraform v1.7.4
on darwin_arm64

Terraform Configuration Files

resource "azurerm_key_vault_secret" "sa_connectionstring" {
  name         = "storage-account-connectionstring"
  value        = azurerm_storage_account.main.primary_connection_string
  key_vault_id = azurerm_key_vault.main.id
  depends_on        = [
    azurerm_key_vault_access_policy.current
  ]
}

Debug Output

jorenthijs@macbook Main % export TF_LOG=trace jorenthijs@macbook Main % terraform fmt ./storage.tf 2024-03-04T12:34:26.694+0100 [INFO] Terraform version: 1.7.4 2024-03-04T12:34:26.694+0100 [DEBUG] using github.com/hashicorp/go-tfe v1.41.0 2024-03-04T12:34:26.694+0100 [DEBUG] using github.com/hashicorp/hcl/v2 v2.19.1 2024-03-04T12:34:26.695+0100 [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.1 2024-03-04T12:34:26.695+0100 [DEBUG] using github.com/zclconf/go-cty v1.14.1 2024-03-04T12:34:26.695+0100 [INFO] Go runtime version: go1.21.5 2024-03-04T12:34:26.695+0100 [INFO] CLI args: []string{"terraform", "fmt", "./storage.tf"} 2024-03-04T12:34:26.695+0100 [TRACE] Stdout is a terminal of width 292 2024-03-04T12:34:26.695+0100 [TRACE] Stderr is a terminal of width 292 2024-03-04T12:34:26.695+0100 [TRACE] Stdin is a terminal 2024-03-04T12:34:26.695+0100 [DEBUG] Attempting to open CLI config file: /Users/jorenthijs/.terraformrc 2024-03-04T12:34:26.695+0100 [DEBUG] File doesn't exist, but doesn't need to. Ignoring. 2024-03-04T12:34:26.695+0100 [DEBUG] ignoring non-existing provider search directory terraform.d/plugins 2024-03-04T12:34:26.695+0100 [DEBUG] ignoring non-existing provider search directory /Users/jorenthijs/.terraform.d/plugins 2024-03-04T12:34:26.695+0100 [DEBUG] ignoring non-existing provider search directory /Users/jorenthijs/Library/Application Support/io.terraform/plugins 2024-03-04T12:34:26.695+0100 [DEBUG] ignoring non-existing provider search directory /Library/Application Support/io.terraform/plugins 2024-03-04T12:34:26.695+0100 [INFO] CLI command args: []string{"fmt", "./storage.tf"} 2024-03-04T12:34:26.696+0100 [TRACE] terraform fmt: Formatting storage.tf storage.tf

Expected Behavior

What i expect and want is for depends_on's '=' sign to be vertically aligned with the others

resource "azurerm_key_vault_secret" "sa_connectionstring" {
  name         = "storage-account-connectionstring"
  value        = azurerm_storage_account.main.primary_connection_string
  key_vault_id = azurerm_key_vault.main.id
  depends_on   = [
    azurerm_key_vault_access_policy.current
  ]
}

Actual Behavior

when i format this document (format on save is turned on, but manual formatting gives same result). Terraform collapses the whitespace but does not vertically align the = sign of the depends_on parameter

resource "azurerm_key_vault_secret" "sa_connectionstring" {
  name         = "storage-account-connectionstring"
  value        = azurerm_storage_account.main.primary_connection_string
  key_vault_id = azurerm_key_vault.main.id
  depends_on = [
    azurerm_key_vault_access_policy.current
  ]
}

If i write the array differently to make it single line. the issue does not reproduce. However this is not a solution because currently the extension is causing whitespace changes for my coworker who uses windows and doesn't have this problem.

resource "azurerm_key_vault_secret" "sa_connectionstring" {
  name         = "storage-account-connectionstring"
  value        = azurerm_storage_account.main.primary_connection_string
  key_vault_id = azurerm_key_vault.main.id
  depends_on   = [azurerm_key_vault_access_policy.current]
}

Steps to Reproduce

terraform fmt or terraform fmt specific-file.ts

Additional Context

I first thought it was an issue with the VS-code extension so I filed a bug there. They could reproduce it but redirected me here since they also use terraform fmt.

References

apparentlymart commented 8 months ago

Hi @Joren-Thijs,

What you've encountered here is the auto-formatter behaving as designed: a multi-line expression isn't considered to be grouped in with its neighbors for alignment purposes because it represents a break in the sequence of single-line assignments that potentially introduces new nested groups that would get aligned separately.

I'm going to relabel this as an enhancement request to represent that you are asking for a change to the intended design which therefore requires new technical design work, but I also want to be explicit that you've described a subjective preference that is not inherently better or worse than what Terraform currently does, and any systematic design rules are inevitably going to be considered differently by different people, so we tend to avoid making essentially-arbitrary changes to the established rules to avoid creating churn for people who already have their configurations formatted under the current set of rules. Therefore I'm not optimistic that this request will lead to terraform fmt being changed to behave as you described.

We also explicitly do not offer any customization options for terraform fmt because its purpose is to be a single fixed set of rules that represent idiomatic Terraform style.


FWIW I'd also note that the documented style conventions call for meta-arguments like depends_on to be visually separated from other arguments by one blank line and placed first anyway. terraform fmt does not currently enforce ordering and blank line rules to avoid significant churn to existing configurations, but if your example were following those conventions it would be written this way and so the depends_on would not be included in the same alignment group as the other arguments regardless of whether it were single-line or not:

resource "azurerm_key_vault_secret" "sa_connectionstring" {
  depends_on = [
    azurerm_key_vault_access_policy.current
  ]

  name         = "storage-account-connectionstring"
  value        = azurerm_storage_account.main.primary_connection_string
  key_vault_id = azurerm_key_vault.main.id
}

Of course there's no requirement that you follow those style rules, just as there's no requirement that you use terraform fmt. These style conventions and the tool that automates some of them are offered in the hope that they are useful for achieving consistency and familiarity for folks who have used Terraform in other organizations before, but some organizations prefer to decide and document their own local design rules that differ from the official ones.