From cf16eda6e503ffe133c75160f608bf8765fae56d Mon Sep 17 00:00:00 2001 From: Manoj Kumar Date: Fri, 28 Aug 2026 15:04:11 +0530 Subject: [PATCH] Fix internet_protocol/routing_mode case mismatch causing perpetual replace on cloudstack_vpc_offering CloudStack's API normalizes these ForceNew fields' casing on write (e.g. ipv4 -> IPv4, static -> Static), which produced a permanent diff and proposed a destroy/recreate on every subsequent plan. Add a case-insensitive DiffSuppressFunc to both fields. network_mode is unaffected: the API rejects incorrect casing outright instead of silently normalizing it, so no fix is needed there. --- cloudstack/resource_cloudstack_vpc_offering.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cloudstack/resource_cloudstack_vpc_offering.go b/cloudstack/resource_cloudstack_vpc_offering.go index fdcd2e46..3914b6e2 100644 --- a/cloudstack/resource_cloudstack_vpc_offering.go +++ b/cloudstack/resource_cloudstack_vpc_offering.go @@ -22,6 +22,7 @@ package cloudstack import ( "fmt" "log" + "strings" "github.com/apache/cloudstack-go/v2/cloudstack" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -82,6 +83,9 @@ func resourceCloudStackVPCOffering() *schema.Resource { Computed: true, Description: "The internet protocol of the VPC offering. Options are ipv4 and dualstack. Default is ipv4. dualstack will create a VPC offering that supports both IPv4 and IPv6", ForceNew: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return strings.EqualFold(old, new) + }, }, "network_mode": { Type: schema.TypeString, @@ -96,6 +100,9 @@ func resourceCloudStackVPCOffering() *schema.Resource { Computed: true, Description: "the routing mode for the VPC offering. Supported types are: Static or Dynamic.", ForceNew: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return strings.EqualFold(old, new) + }, }, "specify_as_number": { Type: schema.TypeBool,