The Tailscale API supports renaming a VIP service without deleting and recreating it by sending PUT /tailnet/{tailnet}/vip-services/{oldName} with a different name in the request body. This preserves the service's assigned VIPs.
CreateOrUpdate cannot do this because it always derives the URL path from svc.Name:
req, err := vr.buildRequest(ctx, http.MethodPut, vr.buildTailnetURL("vip-services", svc.Name), requestBody(svc))
So if svc.Name is the new name, the request goes to the new name's URL — which creates a new service rather than renaming the existing one.
The Tailscale API supports renaming a VIP service without deleting and recreating it by sending PUT
/tailnet/{tailnet}/vip-services/{oldName}with a different name in the request body. This preserves the service's assigned VIPs.CreateOrUpdatecannot do this because it always derives the URL path from svc.Name:So if svc.Name is the new name, the request goes to the new name's URL — which creates a new service rather than renaming the existing one.