terraform
terraform copied to clipboard
Terraform fmt inconsistent on Linux and Windows (1.6.6)
Terraform Version
Locally
-------
Terraform v1.6.6
on windows_amd64
CI Agent (Azure DevOps)
----------------------------
Terraform v1.6.6
on linux_amd64
Terraform Configuration Files
resource "azurerm_linux_web_app" "lwa" {
name = var.name
location = var.location
resource_group_name = var.resource_group_name
service_plan_id = var.service_plan_id
https_only = true
client_certificate_enabled = var.client_certificate_enabled
client_certificate_mode = var.client_certificate_mode
app_settings = var.app_settings
identity {
type = "SystemAssigned"
}
dynamic "connection_string" {
iterator = entry
for_each = var.connection_string
content {
name = entry.value.name
type = entry.value.type
value = entry.value.value
}
}
site_config {
ftps_state = "Disabled"
app_command_line = var.app_command_line
health_check_path = var.health_check_path
use_32_bit_worker = false
always_on = true
vnet_route_all_enabled = var.vnet_route_all_enabled
http2_enabled = true
dynamic "application_stack" {
iterator = entry
for_each = var.application_stack
content {
dotnet_version = entry.value.dotnet_version
node_version = entry.value.node_version
}
}
dynamic "ip_restriction" {
iterator = entry
for_each = var.ip_restriction
content {
service_tag = entry.value.service_tag
name = entry.value.name
priority = entry.value.priority
action = entry.value.action
}
}
}
lifecycle {
ignore_changes = [
tags,
virtual_network_subnet_id
]
}
}
variable "name" {
type = string
}
variable "location" {
type = string
}
variable "resource_group_name" {
type = string
}
variable "service_plan_id" {
type = string
}
variable "client_certificate_enabled" {
type = string
default = true
}
variable "client_certificate_mode" {
type = string
default = "OptionalInteractiveUser"
}
variable "app_settings" {
type = map(string)
}
variable "connection_string" {
type = list(object({
name = string
type = string
value = string
}))
default = []
}
variable "application_stack" {
type = list(object({
dotnet_version = string
node_version = string
}))
default = []
}
variable "ip_restriction" {
type = list(object({
service_tag = string
name = string
priority = string
action = string
}))
default = []
}
variable "app_command_line" {
type = string
default = null
}
variable "vnet_route_all_enabled" {
type = bool
default = true
}
variable "health_check_path" {
type = string
default = null
}
Debug Output
https://gist.github.com/Devvox93/47fd9f8b44e5df51ce11b42b2e9e67bb
Expected Behavior
Both locally (on Windows) and on the agent (on Linux) with the same Terraform version (1.6.6) should provide a consistent result (no fmt errors).
Actual Behavior
Locally (on Windows) there are no errors with -check and running without check changes nothing, but on the agent (running Linux) the main.tf and variables.tf file are mentioned that they contain errors.
Steps to Reproduce
terraform fmt -check -recurse
Additional Context
Just running the command above as part of a CI run on an Azure DevOps agent on a Linux OS.
We updated from Terraform 1.5.7 to 1.6.6 and the first time running Terraform fmt with 1.6.6 on Windows did make (whitespace) changes to the main.tf and variables.tf. Those changes were committed and pushed. Either with those changes or when they are reverted, the Linux agent output keeps saying there are errors, while the Windows version says they're okay (with the changes). Both are using Terraform 1.6.6, as mentioned in the appropriate area above.
References
No response
Thanks for reporting this, @Devvox93.
Could you please run terraform fmt -recurse -write
to let terraform fmt
update the files, and then compare the result with the original input?
One way we've seen this happen in the past is when a version control system is misconfigured to quietly rewrite the line endings from Windows-style (\r\n
) to Unix style (just \n
) or vice-versa, making the input to terraform fmt
actually different between the two OSes even though in a text editor it might appear to be the same. I can't say whether that's what's happening here, but I'm hoping that showing the actual differences the command is finding on your system will help determine whether it's a line-endings-related problem like this, or something else.
Hi @apparentlymart! Thanks for the amazingly quick response. I did not expect that, so am pleasantly surprised 😃 Locally it doesn't output a thing, but tomorrow I'll try running this on the CI agent and output the git diffs.
I expected something like you describe as well, so I already checked that these files have the same line endings in my VS Code locally. That doesn't necessarily mean that still some quiet conversion is happening to those 2 files.
I am also seeing whitespace differences between my dev machine (Windows) and the CI (Linux). Running TF 1.7.3.
Primarily it is not happy with my maps. I have:
default_tags = merge(local.default_tags, {"Name" = "someName"})
which when running terraform fmt -recursive -write
on Windows makes no changes but my CI reckons this should be
default_tags = merge(local.default_tags, { "Name" = "someName" })
which is causing my fmt check pipeline to fail.
TL;DR: It's not an issue with Terraform.
I (finally) have an update concerning this issue.
In our pipeline, we use various templates and checkout multiple repositories.
The repository that showed this error is one of those template repositories and was being checked out with a wrong ref as part of our PR analysis. The terraform fmt
kept showing the same error, because the same old version was being checked (and not the PR version where the formatting was corrected).
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.