Hi 馃憢 !
Description
Since upgrading the Tailscale provider from 0.28.0 to 0.29.2, any semantic change to a tailscale_acl resource causes Terraform/OpenTofu to display almost the entire policy file as changed.
Most displayed changes are formatting differences between:
- the canonical HuJSON returned by the Tailscale API, using tabs and canonical line wrapping; and
- the original HuJSON supplied through
templatefile, using spaces.
Whitespace-only changes are correctly suppressed. However, once there is a genuine policy change, the plan compares the API-formatted state against the raw configured string, making the plan practically impossible to review.
This worked correctly with provider 0.28.0.
Provider and OpenTofu versions
- tailscale/tailscale: 0.29.2
- previous working provider: 0.28.0
- OpenTofu: 1.11.2
- Platform: darwin_arm64
Configuration
We are using it similar to the documented example but use the result of templatefile.
resource "tailscale_acl" "main" {
acl = templatefile("${path.module}/tailscale_acl.hujson", {
installation_names = local.installation_names
})
}
Simplified policy:
{
"hosts": {
"vector": "100.64.0.1",
},
"ipsets": {
"ipset:monitoring-endpoints": ["add host:vector"],
},
}
Making this small semantic change:
"hosts": {
"vector": "100.64.0.1",
+ "vector-stage": "100.64.0.2",
},
-"ipset:monitoring-endpoints": ["add host:vector"],
+"ipset:monitoring-endpoints": ["add host:vector", "add host:vector-stage"],
causes the plan to show the complete policy as removed and re-added, primarily changing tabs, spaces, wrapping, alignment, and trailing commas. Excerpt from the plan output:
- "ipsets": {
- "ipset:monitoring-endpoints": ["add host:vector"],
- },
+ "ipsets": {
+ "ipset:monitoring-endpoints": ["add host:vector", "add host:vector-stage"],
+ },
Expected behavior
The plan should show only the semantic HuJSON changes, as it did with provider 0.28.0.
Regression analysis
Not done personally, the LLMs knew the version it worked with before and came up with this:
This appears to be a regression from the plugin-framework migration in: #721
Provider 0.28.0 used StateFunc with hujson.Format and DiffSuppressOnRefresh: https://github.com/tailscale/terraform-provider-tailscale/blob/v0.28.0/tailscale/resource_acl.go#L64-L89
In 0.29.2, Read stores the raw API HuJSON in state: https://github.com/tailscale/terraform-provider-tailscale/blob/v0.29.2/tailscale/resource_acl.go#L86-L100
The new plan modifier suppresses the diff when canonical state and configuration are identical. If they differ semantically, however, it leaves the raw configured value in the plan: https://github.com/tailscale/terraform-provider-tailscale/blob/v0.29.2/tailscale/plan_modifiers.go#L64-L82
This means that any real change causes Terraform to compare the server-formatted state with the differently formatted configuration.
Hi 馃憢 !
Description
Since upgrading the Tailscale provider from 0.28.0 to 0.29.2, any semantic change to a
tailscale_aclresource causes Terraform/OpenTofu to display almost the entire policy file as changed.Most displayed changes are formatting differences between:
templatefile, using spaces.Whitespace-only changes are correctly suppressed. However, once there is a genuine policy change, the plan compares the API-formatted state against the raw configured string, making the plan practically impossible to review.
This worked correctly with provider 0.28.0.
Provider and OpenTofu versions
Configuration
We are using it similar to the documented example but use the result of templatefile.
Simplified policy:
Making this small semantic change:
"hosts": { "vector": "100.64.0.1", + "vector-stage": "100.64.0.2", }, -"ipset:monitoring-endpoints": ["add host:vector"], +"ipset:monitoring-endpoints": ["add host:vector", "add host:vector-stage"],causes the plan to show the complete policy as removed and re-added, primarily changing tabs, spaces, wrapping, alignment, and trailing commas. Excerpt from the plan output:
Expected behavior
The plan should show only the semantic HuJSON changes, as it did with provider 0.28.0.
Regression analysis
Not done personally, the LLMs knew the version it worked with before and came up with this:
This appears to be a regression from the plugin-framework migration in: #721
Provider 0.28.0 used
StateFuncwithhujson.FormatandDiffSuppressOnRefresh: https://github.com/tailscale/terraform-provider-tailscale/blob/v0.28.0/tailscale/resource_acl.go#L64-L89In 0.29.2,
Readstores the raw API HuJSON in state: https://github.com/tailscale/terraform-provider-tailscale/blob/v0.29.2/tailscale/resource_acl.go#L86-L100The new plan modifier suppresses the diff when canonical state and configuration are identical. If they differ semantically, however, it leaves the raw configured value in the plan: https://github.com/tailscale/terraform-provider-tailscale/blob/v0.29.2/tailscale/plan_modifiers.go#L64-L82
This means that any real change causes Terraform to compare the server-formatted state with the differently formatted configuration.