Skip to content

feat(deps): update terraform unifi ( 0.55.0 → 0.58.0 ) - #2668

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/unifi-0.x
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate/unifi-0.x

Conversation

@renovate

@renovate renovate Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Type Update Change
unifi (source) required_provider minor 0.55.0 → 0.58.0

Release Notes

ubiquiti-community/terraform-provider-unifi (unifi)

v0.58.0

Compare Source

✨ Features
  • unifi_setting: manage Global Switch Settings via the new global_switch block (stp_version, dhcp_snoop, jumboframe_enabled, dot1x_portctrl_enabled). Current controllers only honor jumbo frames at the site level: setting unifi_device.jumboframe_enabled = true is accepted and then read back as false, failing apply with Provider produced inconsistent result after apply, so jumbo frames were previously unmanageable. The block is opt-in like the others on unifi_setting, all fields are Optional+Computed with UseStateForUnknown, and only the fields you set are sent to the controller, so Global Switch options the provider doesn't model (ACL isolation, switch exclusions, link debounce, PoE staging) are left untouched (#​513)
  • unifi_firewall_policy: expose match_mac on the source and destination blocks. The controller stores a match_mac flag on every policy endpoint that makes the listed client_macs match by MAC address rather than by the clients' current IP. The provider neither read nor wrote it, so a policy using MAC matching could not be expressed in Terraform and any update through the provider serialized match_mac: false, silently disabling it on the controller. The new attribute is Optional+Computed with a false default and is round-tripped on read, so existing configurations plan clean; policies with MAC matching enabled outside Terraform show a diff until the attribute is declared. The v0 to v1 endpoint state upgrader seeds it as false and the next refresh overwrites it with the live value (#​472)
  • unifi_setting: manage Wireless Meshing via the new connectivity block (enabled, mlo_mesh_enabled, uplink_type, uplink_host). Turning meshing off on a fully wired site frees the standby mesh radio and doubles the per-band SSID budget: with meshing on, APs reserve a hidden backhaul SSID and allow 4 SSIDs per band instead of 8, so a site rebuilt from code could fail to create its fifth WLAN with reached the limit of WiFi networks per AP before this toggle was manageable. The block is opt-in like the others on unifi_setting, every field is Optional+Computed with UseStateForUnknown, and only the fields you set are written - so the controller-generated mesh SSID and pre-shared key (x_mesh_essid, x_mesh_psk), and any option the provider does not model, are preserved across updates (#​518)
  • unifi_wan: manage PPPoE credentials via username, password and the write-only password_wo. unifi_wan accepted type = "pppoe" but had no way to set the ISP login, because wan_username and x_wan_password were absent from go-unifi's curated WAN payload and so never reached the controller. Both now travel, and only when set: an unset attribute keeps the key off the wire, so an imported PPPoE uplink can be managed for its other settings without clearing the login and dropping the connection. password_wo (Terraform 1.11+) is used at apply time and never written to state, so it can come from an ephemeral resource - with the trade-off that the provider then cannot detect a password changed outside Terraform, which produces no diff. Requires go-unifi ≥ v1.35.0 (ubiquiti-community/go-unifi#85) (#​515)
  • unifi_wireguard_peer: manage a peer's pre-shared key via preshared_key and the write-only preshared_key_wo. The UI offers it as a Pre-Shared Key toggle on every WireGuard client and the controller stores it, but the resource had no such attribute - and because the peer endpoints are full replaces, a key configured in the UI was silently destroyed by the next apply that touched the peer (verified on Network 10.6.106: a write omitting preshared_key removes the stored key). Both attributes are now written only when set, so leaving them unset keeps the key off the wire and preserves whatever the controller holds. preshared_key_wo (Terraform 1.11+) is used at apply time and never written to state, with the trade-off that the provider cannot then detect a key changed outside Terraform. Requires go-unifi ≥ v1.35.0 (ubiquiti-community/go-unifi#86) (#​490)
  • unifi_firewall_policy: match on region via the new regions attribute on source and destination. Zone-based policies that filter by country (matching_target = "REGION") could not be expressed: neither the schema nor go-unifi carried the field, so such a policy had to be left out of Terraform entirely. matching_target now accepts REGION, and regions takes a list of two-letter country codes, round-tripped from the controller in both directions. Two controller constraints are worth knowing: REGION is only valid on an external zone, and a write that leaves the list empty is rejected with api.err.EmptyFirewallSourceRegions - so an imported region policy was never silently losing its country list, contrary to the original report; an apply that dropped the list failed outright instead. Requires go-unifi ≥ v1.35.0 (ubiquiti-community/go-unifi#87) (#​492)
  • unifi_setting: manage Client Device Isolation via global_switch.acl_device_isolation. The "Device Isolation (ACL)" toggle under Settings > Networks is the acl_device_isolation list on the site's global_switch setting: the network IDs whose devices may not talk to each other. It is a switch ACL, so it covers same-network traffic across access points - which neither unifi_wlan.l2_isolation (one access point) nor unifi_network.network_isolation (between networks) reaches. Previously it could only be set in the UI, so a change there produced no plan diff and drift went unnoticed. The list round-trips, an explicitly empty list clears the setting, and an unmanaged one stays off the wire so isolation configured outside Terraform survives an unrelated change to the block. Note the controller only offers this for networks routed by a UniFi gateway or L3 switch, and rejects an unsupported network rather than ignoring it (#​509)
  • unifi_site_to_site_vpn: accept a hostname as peer_ip, and manage the IKE identifiers. peer_ip was typed as an IPv4 address, so a tunnel whose peer is configured by hostname (a peer behind dynamic DNS, which the controller stores verbatim) could not even be refreshed: terraform import failed with Invalid IPv4 Address String Value before any configuration was compared. It is now a string accepting either an address or a hostname. The new local_identifier, local_identifier_enabled, remote_identifier and remote_identifier_enabled attributes expose the IKE peer-authentication identifiers the UI offers; setting an identifier enables it, as the UI does, and an explicit *_enabled flag overrides that. Unmanaged identifiers stay off the wire. Requires go-unifi ≥ v1.35.0 (ubiquiti-community/go-unifi#88), which adds the four fields to the site-vpn payload - they were absent from it, so they were never written and never cleared (#​484)
⚠️ Deprecations
  • unifi_device: radio_table's assisted_roaming_enabled and assisted_roaming_rssi are deprecated and no longer applied. UniFi removed 802.11k assisted roaming from the device radio table: the fields are absent from the controller API and from the firmware's own field definitions as of Network 10.6 (verified against the 10.6.106 field set, where the sibling radio fields min_rssi, maxsta and sens_level are all still present), and a UCG-Fiber on 10.6.106 reports neither key on any radio. Both attributes keep their schema entry so existing configurations still parse, but they now read back as null, are no longer sent in the device update PUT, and are no longer range-validated. Remove them from your configuration; they will be dropped in a future release
  • unifi_wlan: bandsteering_mode is deprecated and no longer applied. UniFi moved band steering off the WLAN object: the field is absent from the controller's WLAN field definitions as of Network 10.6 while still present on the device, so the setting now lives on unifi_device's bandsteering_mode. The attribute keeps its schema entry so existing configurations still parse, but it is neither read nor written and always reads back null. Set it on unifi_device instead
🐛 Bug Fixes
  • unifi_port_profile: forward = "customize" on an untagged native network now fails at plan time instead of leaving the resource tainted. The controller accepts such a profile and then stores forward = "all", so the post-apply read disagreed with the plan: Create failed with Provider produced inconsistent result after apply, the resource was marked tainted, and every later apply destroyed, recreated and failed identically - the configuration could never converge. The provider now checks the native network's VLAN id while planning and rejects the combination with the reason and both ways out (set forward = "all", or point native_networkconf_id at a tagged network). A lookup failure does not block the plan, and an unresolved native network is left to the apply (#​496)
  • unifi_setting: managing part of the ips or usg block no longer disables everything else in it. Both blocks built their outgoing document from the Terraform model alone, and every boolean on go-unifi's settings.Ips and settings.Usg serializes without omitempty - so an attribute the configuration did not manage was written as false. Managing only ips_mode therefore switched off an existing honeypot, the content-filtering blocking page, memory optimisation and torrent restriction, and the usg block did the same across twenty flags (FTP/GRE/H.323 helpers, broadcast ping, LLDP, mDNS and the rest). Both write paths now read the live setting document first and overlay only the attributes present in configuration, so unmanaged options keep their controller values (#​493)
  • unifi_network: adopting a network by import no longer switches auto-scaling and LTE-LAN on. auto_scale and lte_lan were declared with a schema default of true, but the controller stores no default for either: a network created without the keys comes back without them, while a network written even once carries an explicit value (verified on Network 10.6.106 - a freshly created network has neither key, all eight pre-existing networks on the same site have both, set to false). So importing a network that had these off planned false -> true, and because both values were unconditionally serialized into the update PUT, apply turned the features on - with the diff attributed to a default the user never wrote. Both attributes are now Optional + Computed with no default and UseStateForUnknown: left unset they stay off the wire entirely and the controller's value is preserved; set explicitly, false included, they are sent as before. Requires go-unifi ≥ v1.35.0, where the two fields became tri-state pointers (ubiquiti-community/go-unifi#84). Importing an existing corporate network now reaches a strictly empty plan (#​524)
  • unifi_network: importing a vlan-only network no longer plans auto_scale, internet_access, lte_lan and setting_preference forever. Same root cause as #​414 (fixed in #​415 for gateway_type / ipv6_interface_type): the controller omits these fields for a vlan-only network, and the read path copied them from the prior model, which on import carries nothing but the ID. They stayed null while the schema defaults are true / "auto", so every ordinary plan proposed an in-place update and import-first adoption could never reach a strict no-op - lifecycle { ignore_changes } does not suppress it, because the default is applied to the null config value after the prior state is substituted. A null or unknown prior value now resolves to the documented default; an explicitly configured value, false included, is preserved. Read-side only, with no change to what is written to the controller. lte_lan has no schema Default, so it falls back to the true its documentation promises (#​517)
  • unifi_port_profile: a configured storm-control, rate-limit or priority-queue value no longer leaves the resource tainted. egress_rate_limit_kbps, egress_rate_limit_kbps_enabled, the four priority_queue*_level attributes and the ten stormctrl_* attributes were hardcoded to null/false on read, whatever the controller actually held, so any configured value failed the post-apply consistency check with Provider produced inconsistent result after apply. The profile was created on the controller and recorded in state, but Terraform marked it tainted and the next apply destroyed, recreated and failed identically - the configuration could never converge. All sixteen are now round-tripped from the controller, and an attribute the controller does not hold still reads back null rather than zero (#​496)
  • unifi_network: firewall_zone_id no longer shows -> (known after apply) on every plan. The attribute is Optional + Computed with no plan modifier, so the framework re-planned it as unknown on any update whose configuration left it unset. ModifyPlan already pinned it back, but only when the prior state was null - the case for controllers without zone-based firewalling. On a ZBF controller, where the controller assigns a zone on first apply, the state is always populated, so the unknown survived and made every follow-up plan non-empty. The plan is now pinned to the prior state value whenever the configuration declares none, which covers both cases. The dhcp_relay acceptance test no longer needs its zone-based-firewall precheck as a result. The code change shipped in #​526; this adds the changelog entry it was missing (#​519)
  • unifi_device: carry every configurable field into the update PUT. stp_version, stp_priority, outlet_overrides, outlet_enabled, the lcm_* display settings, poe_mode, locked, disabled, bandsteering_mode, flowctrl_enabled, jumboframe_enabled, outdoor_mode_override, volume and x_baresip_password were converted from the plan but never copied into the minimal body sent on update, so the controller kept its previous values and the post-apply read failed with Provider produced inconsistent result after apply (for example stp_priority staying at 32768 after planning 4096). All of them are now included. Every one of these fields is omitempty in go-unifi, so attributes that are not declared stay off the wire and existing configurations are unaffected (#​476, #​510)
  • CI: stop the nightly acceptance run failing on TestAccDeviceFramework_radioTable. The test declared an na (5 GHz) radio on 00:15:6d:00:00:01, which the compose controller simulates as a U2O - a single-band device whose radio_table holds only an ng entry. With no matching entry to echo the controller-required radio name from, the PUT was rejected with a bare api.err.Invalid (400) and the failure was attributed to whichever change had merged last. The simulated APs also populate radio_table asynchronously after adoption (and often not at all), which is why the same commit passed and failed on consecutive nightly runs. The test now checks the target device actually exposes the radios it configures and skips with the reason when it does not, so radio coverage is only claimed where the hardware provides it
  • unifi_device: apply per-device management IP and DNS changes from config_network. The Terraform configuration was converted into DeviceConfigNetwork but dropped when assembling the minimal update payload, so the controller kept its previous values and the post-apply read could fail with Provider produced inconsistent result after apply. The update payload now includes the configured management network settings, including dns1 and dns2; an unset block stays omitted (#​482)

v0.57.0

Compare Source

✨ Features
  • unifi_firewall_policy: expose the "Match Opposite" (invert) toggles. New match_opposite_ips, match_opposite_networks and match_opposite_ports attributes on the source and destination blocks, plus a top-level match_opposite_protocol, map 1:1 to the controller's match_opposite_* flags — the "Match Opposite" switches in the UI that make an endpoint match everything except the listed networks/IPs/ports (or protocol). Previously the provider neither read nor wrote these flags, so a policy inverted in the UI could not be expressed in Terraform and any update through the provider silently reset the inversion to false. All four are Optional+Computed with a false default and are round-tripped from the controller on read, so existing configurations plan clean; policies inverted outside Terraform now show a diff until the attribute is declared. The v0→v1 endpoint state upgrader seeds the new fields as false (refresh overwrites them with the live values)
🐛 Bug Fixes
  • unifi_network: collapse duplicate DHCP NTP servers returned by the controller. UniFi can store a single configured server in both DHCP NTP fields, causing dhcp_server.ntp_servers to read back with duplicate entries and produce inconsistent-result errors or persistent drift. Both the resource and data source now return unique servers in their original order; the resource continues to preserve the distinction between an unset list and an explicitly empty list (#​477)
  • Fix every plan failing under OpenTofu after upgrading from v0.55.0 with attribute "site" is required. v0.56.0 added site (and network_id on unifi_wireguard_peer) to the resource identity of 21 resources without bumping the identity schema version. Terraform decodes the old {"id"} identity with the new attributes null, but OpenTofu requires every attribute of the current identity schema to be present, so unifi_dns_record, unifi_firewall_group, unifi_network, unifi_port_forward and unifi_wan failed directly and their dependents were skipped. The identity schema of ap_group, client_qos_rate, dns_record, firewall_group, firewall_policy, firewall_rule, firewall_zone, network, port_forward, port_profile, power_supervisor, radius_profile, radius_user, site_to_site_vpn, static_route, traffic_route, vpn_client, vpn_server, wan, wireguard_peer and wlan is now at version 1, with a shared upgrader that carries stored values over and fills a missing site from the provider's configured site. No configuration or state changes are needed. A resource whose site differs from the provider's site gets the provider's site in its upgraded identity. A unifi_wireguard_peer identity written before v0.56.0 keeps a null network_id, since an identity upgrader cannot see state; plans are unaffected because Read takes network_id from state (#​506)
  • unifi_port_profile: an explicitly empty port_security_mac_address no longer fails apply with Provider produced inconsistent result after apply. The controller stores a profile whose Port State is Disabled as port_security_enabled = true with an empty MAC allowlist, so no device can pass. The read turned an empty allowlist from the controller into null, so a configured [] could not be kept in state and both create and update failed, although the controller had accepted the write. An explicitly empty set now reads back as [], an unset attribute still reads as null, and addresses the controller reports are adopted as before. To disable ports through a profile, set port_security_enabled = true with port_security_mac_address = []: forward = "disabled" alone leaves the port Active (#​470)
  • unifi_firewall_policy: fix Provider produced inconsistent result after apply when UniFi renumbers a policy's index. The controller can renumber remaining policies when siblings are deleted during the same apply. The computed, read-only index no longer uses UseStateForUnknown, allowing an updated policy's post-apply read to refresh the controller-assigned value instead of comparing it against a stale index pinned in the plan (#​348, #​473)

v0.56.1

Compare Source

🐛 Bug Fixes
  • unifi_device: fix terraform plan failing after upgrading from v0.55.0 with failed to decode identity: unsupported attribute "id". v0.56.0 changed the unifi_device resource identity key from the controller device id to the device mac without bumping the identity schema version, so every state holding a unifi_device written by v0.55.0 or earlier failed to plan. The identity schema is now at version 1 with an upgrader for version 0 identities, which exist in two shapes: a {"mac"} identity written by v0.56.0 is carried over, and an {"id"} identity written by earlier versions is rebuilt from the state's mac attribute on the next refresh. No configuration or state changes are needed, and states already written by v0.56.0 keep working. Other resources whose identity only gained an optional site (or network_id) attribute in v0.56.0 were not affected (#​502, #​504)

v0.56.0

Compare Source

✨ Features
  • unifi_wlan: per-SSID band steering via the new bandsteering_mode attribute (off | equal | prefer_5g). Modern controllers expose band steering on the wlanconf record, and on WiFi 6/7 access points this per-SSID control has replaced the legacy device-level one (still available as unifi_device.bandsteering_mode), so band steering was previously unmanageable on that hardware. Optional+Computed with value validation; the value is echoed from the controller on read, stays entirely off the wire when unset, and on controllers without per-SSID band steering (which accept and ignore the key) the declared value is kept in state instead of failing the apply with an inconsistent-result error. Requires go-unifi with WLAN.BandsteeringMode (go-unifi#72) (#​388)
🐛 Bug Fixes
  • unifi_network: dhcp_server.dns_servers, dhcp_server.ntp_servers, and dhcp_server.wins.addresses can now be set back to empty. Two halves made an explicit [] impossible. Read collapsed an empty controller response to null while the plan held [], failing apply with "provider produced inconsistent result after apply"; the readback now mirrors the previous value's null-ness, so [] round-trips as [] and never-configured stays null. And on the wire, go-unifi tagged dhcpd_dns_1..4 with omitempty and squashed a pointer-to-empty dhcpd_ntp_1..2 to nil, so the clearing PUT silently omitted the fields and the controller (whose networkconf PUT keeps omitted fields) retained the old servers — fixed upstream in go-unifi#73, picked up by the go.mod bump. Because corporate/guest updates now serialize those fields unconditionally, updates on networks whose configuration does not manage the dhcp_server block preserve the controller's current DHCP options (range, lease time, DNS/NTP/WINS, boot fields) by reading the network first, the same pattern #​439 introduced for dhcp_guarding (#​429)

  • unifi_wlan: creating a WLAN with "6g" in wlan_bands no longer fails with Provider produced inconsistent result after apply. The provider marshals the full declared band list — 6g included — on both create and update, but some controllers (observed on Network 10.4.x) silently drop 6g from the initial create response while accepting the identical payload on a subsequent update; the reporter's manual workaround (create without 6g, then add it) confirmed the asymmetry. Create now compares the controller's response against the requested band list and, when a band was dropped, immediately re-asserts the intended configuration with a single follow-up update — the created WLAN carries all declared bands in one terraform apply. If the controller refuses the band even then, the apply now fails with an actionable diagnostic (6GHz gating: WPA3/SAE with PMF, 6GHz-capable APs) instead of the cryptic consistency error, and the created WLAN is tracked in state as tainted rather than orphaned on the controller (#​406)

  • unifi_device: fix declared radio_table rejecting every update with api.err.InvalidPayload (400). A radio_table entry declared with only some sub-fields (e.g. radio/channel/ht/tx_power_mode) leaves the rest Unknown — not Null — in the plan, and ValueInt64Pointer() maps Unknown to a pointer at the Go zero value, so every undeclared numeric sub-field went out as a literal 0 ("antenna_gain":0,"min_rssi":0,"sens_level":0,…), which the controller rejects; and simply omitting them is not enough, because the controller requires each entry to carry the hardware-assigned radio name and fails with api.err.MissingValue (key radio) without it. Unknown sub-fields now stay off the wire like Null, hardware-derived fields the practitioner left unset (name, antenna_gain, antenna_id, channel/width/power when undeclared) are echoed from the device's current radio table so controller-required values are always present, and the post-apply state keeps the declared list's count/order/values, resolving only the undeclared sub-fields from the controller. As part of the same diff-hygiene class, an empty port_overrides now mirrors the device's existing representation (null vs []) instead of always sending [], which manufactured a spurious null→[] change that some controllers reject on devices without ports (#​427)

  • unifi_setting.ips: suppression_alerts / suppression_whitelist are now actually saved on current controllers instead of producing a perpetual diff. Newer controllers (observed on Network 10.4.x) no longer store IPS suppression nested inside the ips setting: the set/setting/ips endpoint silently drops the nested suppression field and the data lives under the standalone ips_suppression setting key, so the provider's writes never landed and every plan re-showed the whole list. The provider now re-reads the ips setting after writing it; when the controller did not persist the nested field, it writes the entries to the ips_suppression setting (and refresh reads them back from there). Controllers that still nest suppression under ips keep using the nested path unchanged, and controllers that support neither shape now fail loudly instead of drifting silently (#​381)

  • unifi_setting.usg: geo_ip_filtering_* now actually configures Region Blocking on current controllers instead of applying without effect. Newer controllers (observed on Network 10.4.x) ignore the geo_ip_filtering_* fields on the usg setting: the live Region Blocking configuration is stored under the standalone usg_geo setting key (as ip_filtering.{action,countries,enabled,traffic_direction}), so applies never changed anything and OpenTofu/Terraform reported an inconsistent result. The provider now also writes the configured fields to usg_geo (mapping geo_ip_filtering_block to action), treats a stored usg_geo setting as authoritative on refresh, and keeps existing configurations working unchanged on older controllers that reject the usg_geo key and persist the fields on usg itself — no configuration changes needed on either controller generation (#​374)

  • unifi_network: stop ip_aliases and nat_outbound_ip_addresses always failing apply with "provider produced inconsistent result after apply". Read hardcoded both attributes to null regardless of what the API returned, so any network with a non-empty value configured failed every apply, unconditionally. Both now round-trip from the controller's response. ipv6_aliases remains unsupported — go-unifi's Network struct has no field for it even though the controller accepts and returns it — but a configured value is now rejected with a clear error at plan time instead of failing apply with a confusing inconsistent-result error (#​413)

  • unifi_client: fix every in-place update failing with Provider produced inconsistent result after apply: .last_ip. last_ip and hostname are values the controller reports from live observation, not derived from any configured attribute, yet both used UseStateForUnknown. That plan modifier pins the planned value to the prior state whenever config doesn't set the attribute — appropriate for values that only change when the practitioner changes them, but wrong here, since the controller can legitimately report a new value between plan and apply (the client re-associates, a DHCP lease renews, etc.). Terraform then requires the applied value to exactly match the pinned plan value, so any update — regardless of which attribute actually changed — failed once last_ip or hostname drifted. Both are now plain Computed attributes that plan as (known after apply) on update, so the real post-apply value from the controller is always accepted (#​428)

  • unifi_network: make dhcp_guarding actually take effect on corporate/guest/vlan-only networks. Two independent drops hid dhcp_guarding from the controller. First, go-unifi historically only marshaled dhcpd_ip_1..3 for purpose = "vlan-only" networks — fixed upstream (go-unifi#68) and already picked up by the go-unifi bump on main, which serializes them for corporate and guest too. Second — and still present until now — the provider defaults setting_preference to auto, and the controller force-resets dhcpguard_enabled to false on any write to an auto-managed network, so guarding either silently never took effect or apply failed with Provider produced inconsistent result after apply: .dhcp_guarding.enabled. ModifyPlan now pins setting_preference to manual whenever dhcp_guarding.enabled is planned true on a corporate/guest network (vlan-only networks keep guarding under auto) and the practitioner has not set setting_preference explicitly, mirroring the existing DHCP relay behavior; an explicit setting_preference = "auto" combined with enabled guarding now gets a plan-time warning explaining the controller will reset it. Also fixes the perpetual non-empty plan this pinning previously caused for DHCP relay networks on controllers without zone-based firewalling: the setting_preference default flapping auto→manual made every plan an update, which re-planned the null firewall_zone_id as (known after apply) forever; ModifyPlan now pins the plan back to null when neither state nor config carry a zone (#​419)

  • unifi_network: stop updates silently disabling DHCP guarding configured outside Terraform. The update PUT is assembled from the Terraform model alone, so when the dhcp_guarding block is absent from configuration the body carries dhcpguard_enabled: false (with the trusted-server fields empty or, for corporate/guest networks on current go-unifi, absent from the wire entirely) — any unrelated update (changing the DHCP pool, DNS, anything) wiped guarding that was enabled on the controller, with no plan diff and no error. When the block is unmanaged the provider now reads the network first and carries the controller's current guarding fields through the update; removing the block therefore preserves guarding rather than disabling it — disable explicitly with enabled = false. Managing dhcp_guarding end-to-end additionally requires go-unifi to marshal dhcpd_ip_1..3 for corporate/guest networks (go-unifi#68) — without that fix the controller rejects an enabled guard with api.err.MissingIPAddress (#​439)

  • unifi_device: pin down and guard the fix that stops zero declared port_override blocks wiping live switch overrides. A switch with live controller-side overrides, updated while config declares zero port_override blocks (e.g. a name-only change), must send the controller's current overrides unchanged — not port_overrides: null (rejected by some controllers with api.err.InvalidPayload, 400) and not [] (which would silently reset every live override, #​436 is only safe when the device truly has none). This behavior already existed in updateDevice but was untested and duplicated across an if/else; it is now a single resolvePortOverridesForUpdate helper with direct regression coverage (#​438)

  • unifi_device: stop a declared port_override stripping settings from every port on the device. op_mode is only written when it is not "switch" (gateways reject it, #​213) and DevicePortOverrides.OpMode is omitempty, so declaring a port that carries op_mode: "switch" on the controller produced an entry with the field missing. UpdateDevice PUTs getDeviceDiff(existing, target) and compares port_overrides as a single JSON value, so that one difference sent the whole array — full-replaced from a copy round-tripped through DevicePortOverrides, which drops the fields it does not model (stp_edge_state, stp_bpdu_guard_enabled, multicast_router_mode, sd_wan_underlay_port) and every field at its zero value. Undeclared ports were stripped along with declared ones, the plan showed nothing, and the apply reported success. The merge now carries a controller-side op_mode forward onto the declared entry, so the marshalled array stays identical and nothing is written; a config-supplied non-switch op_mode still wins, and no value is ever sourced from config, so #​213 stays fixed (#​430, #​266, #​213)

  • unifi_setting.ntp: stop empty NTP server slots causing perpetual diffs or inconsistent results. The controller stores unused ntp_server_1..4 values as empty strings, but the provider read them back as null, conflicting with an explicitly configured "". The server attributes now preserve prior state during unrelated plans and normalize controller empty strings to known empty Terraform values (#​382)


Configuration

📅 Schedule: (in timezone America/New_York)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the type/minor label Sep 23, 2026
@renovate
renovate Bot force-pushed the renovate/unifi-0.x branch from a1bf4ec to 0ae39d9 Compare September 24, 2026 20:39
@renovate renovate Bot changed the title feat(deps): update terraform unifi ( 0.55.0 → 0.56.0 ) feat(deps): update terraform unifi ( 0.55.0 → 0.56.1 ) Sep 24, 2026
@renovate
renovate Bot force-pushed the renovate/unifi-0.x branch from 0ae39d9 to 0fe126a Compare September 29, 2026 14:44
@renovate renovate Bot changed the title feat(deps): update terraform unifi ( 0.55.0 → 0.56.1 ) feat(deps): update terraform unifi ( 0.55.0 → 0.57.0 ) Sep 29, 2026
@renovate renovate Bot changed the title feat(deps): update terraform unifi ( 0.55.0 → 0.57.0 ) feat(deps): update terraform unifi ( 0.55.0 → 0.58.0 ) Oct 3, 2026
@renovate
renovate Bot force-pushed the renovate/unifi-0.x branch from 0fe126a to a116d3e Compare October 3, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants