Summary
With enable_alias_ip = true (the default), every terraform plan wants to remove the private VIP from the control plane that currently holds it. The diff never goes away, and applying it briefly removes the address that every node resolves the internal API hostname to.
Why it happens
The module configures Talos to own the VIP — talos_patch_control_plane.tf:
vip = var.enable_alias_ip ? {
ip = local.control_plane_private_vip_ipv4
hcloud = { apiToken = var.hcloud_token }
} : null
So the node holding the VIP calls the hcloud API and assigns the alias IP to its own private interface, moving it on failover.
But server.tf also declares the same attribute as empty:
network {
network_id = local.network_id
ip = each.value.ipv4_private
alias_ips = [] # fix for https://github.com/hetznercloud/terraform-provider-hcloud/issues/650
}
alias_ips = [] tells the provider the list is empty, not that it is unmanaged. So Terraform sees drift as soon as Talos claims the VIP:
~ resource "hcloud_server" "control_planes" {
~ network {
~ alias_ips = ["10.0.10.100"] -> []
}
}
lifecycle.ignore_changes currently covers only user_data, image and iso, so nothing suppresses it.
Impact
The internal API hostname is mapped to the VIP on every node via extraHostEntries:
network:
extraHostEntries:
- ip: 10.0.10.100
aliases: [kube.cluster.local]
and cluster_endpoint is https://kube.cluster.local:6443. So applying the diff removes the address every kubelet in the cluster uses to reach the API server, until Talos re-announces the VIP. Running pods keep serving, but nothing can be scheduled or reported in that window.
The practical effect is worse than the window itself: the plan is never clean, so terraform apply stops being safe to run for any unrelated change.
Environment
- module
v3.4.12 (also verified unchanged in v3.4.14)
- hcloud provider
1.66.0, Terraform 1.15.7
- 3 control planes,
enable_alias_ip = true (default), kubeconfig_endpoint_mode = "public_ip"
- Present since the cluster's first apply; not triggered by any config change on our side
Suggested fix
Add the network block to ignore_changes:
lifecycle {
ignore_changes = [
user_data,
image,
iso,
network
]
}
Note network is a set block, so network[0].alias_ips is not addressable — terraform validate rejects it with "set elements do not have addressable keys". The whole block has to be ignored, which seems acceptable since its other attributes (network_id, ip) are fixed at creation.
Verified with terraform validate against v3.4.12. Branch with the change: https://github.com/betidaprod-org/terraform-hcloud-talos/tree/fix/ignore-alias-ips — happy to open it as a PR if the approach looks right, or to test an alternative you prefer.
Summary
With
enable_alias_ip = true(the default), everyterraform planwants to remove the private VIP from the control plane that currently holds it. The diff never goes away, and applying it briefly removes the address that every node resolves the internal API hostname to.Why it happens
The module configures Talos to own the VIP —
talos_patch_control_plane.tf:So the node holding the VIP calls the hcloud API and assigns the alias IP to its own private interface, moving it on failover.
But
server.tfalso declares the same attribute as empty:alias_ips = []tells the provider the list is empty, not that it is unmanaged. So Terraform sees drift as soon as Talos claims the VIP:lifecycle.ignore_changescurrently covers onlyuser_data,imageandiso, so nothing suppresses it.Impact
The internal API hostname is mapped to the VIP on every node via
extraHostEntries:and
cluster_endpointishttps://kube.cluster.local:6443. So applying the diff removes the address every kubelet in the cluster uses to reach the API server, until Talos re-announces the VIP. Running pods keep serving, but nothing can be scheduled or reported in that window.The practical effect is worse than the window itself: the plan is never clean, so
terraform applystops being safe to run for any unrelated change.Environment
v3.4.12(also verified unchanged inv3.4.14)1.66.0, Terraform1.15.7enable_alias_ip = true(default),kubeconfig_endpoint_mode = "public_ip"Suggested fix
Add the network block to
ignore_changes:Note
networkis a set block, sonetwork[0].alias_ipsis not addressable —terraform validaterejects it with "set elements do not have addressable keys". The whole block has to be ignored, which seems acceptable since its other attributes (network_id,ip) are fixed at creation.Verified with
terraform validateagainstv3.4.12. Branch with the change: https://github.com/betidaprod-org/terraform-hcloud-talos/tree/fix/ignore-alias-ips — happy to open it as a PR if the approach looks right, or to test an alternative you prefer.