Skip to content

Commit 8c1fa2c

Browse files
TF: plan -refresh=false for google_compute_ha_vpn_gateway with gcs backend has resource replacement (#12422) (#20682)
[upstream:2905156431af01acf9eaf0e1d3ec5181e3bec801] Signed-off-by: Modular Magician <[email protected]>
1 parent ffa4f77 commit 8c1fa2c

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

.changelog/12422.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
bug: fixed an issue where `terraform plan -refresh=false` with `google_compute_ha_vpn_gateway.gateway_ip_version` would plan a resource replacement if a full refresh had not been run yet. Terraform now assumes that the value is the default value, `IPV4`, until a refresh is completed.
3+
```

google/services/compute/resource_compute_ha_vpn_gateway.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package compute
1919

2020
import (
21+
"context"
2122
"fmt"
2223
"log"
2324
"net/http"
@@ -47,6 +48,15 @@ func ResourceComputeHaVpnGateway() *schema.Resource {
4748
Delete: schema.DefaultTimeout(20 * time.Minute),
4849
},
4950

51+
SchemaVersion: 1,
52+
53+
StateUpgraders: []schema.StateUpgrader{
54+
{
55+
Type: resourceComputeHaVpnGatewayResourceV0().CoreConfigSchema().ImpliedType(),
56+
Upgrade: ResourceComputeHaVpnGatewayUpgradeV0,
57+
Version: 0,
58+
},
59+
},
5060
CustomizeDiff: customdiff.All(
5161
tpgresource.DefaultProviderProject,
5262
),
@@ -576,3 +586,122 @@ func expandComputeHaVpnGatewayRegion(v interface{}, d tpgresource.TerraformResou
576586
}
577587
return f.RelativeLink(), nil
578588
}
589+
590+
func resourceComputeHaVpnGatewayResourceV0() *schema.Resource {
591+
return &schema.Resource{
592+
Schema: map[string]*schema.Schema{
593+
"name": {
594+
Type: schema.TypeString,
595+
Required: true,
596+
ForceNew: true,
597+
ValidateFunc: verify.ValidateGCEName,
598+
Description: `Name of the resource. Provided by the client when the resource is
599+
created. The name must be 1-63 characters long, and comply with
600+
RFC1035. Specifically, the name must be 1-63 characters long and
601+
match the regular expression '[a-z]([-a-z0-9]*[a-z0-9])?' which means
602+
the first character must be a lowercase letter, and all following
603+
characters must be a dash, lowercase letter, or digit, except the last
604+
character, which cannot be a dash.`,
605+
},
606+
"network": {
607+
Type: schema.TypeString,
608+
Required: true,
609+
ForceNew: true,
610+
DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName,
611+
Description: `The network this VPN gateway is accepting traffic for.`,
612+
},
613+
"description": {
614+
Type: schema.TypeString,
615+
Optional: true,
616+
ForceNew: true,
617+
Description: `An optional description of this resource.`,
618+
},
619+
"gateway_ip_version": {
620+
Type: schema.TypeString,
621+
Optional: true,
622+
ForceNew: true,
623+
ValidateFunc: verify.ValidateEnum([]string{"IPV4", "IPV6", ""}),
624+
Description: `The IP family of the gateway IPs for the HA-VPN gateway interfaces. If not specified, IPV4 will be used. Default value: "IPV4" Possible values: ["IPV4", "IPV6"]`,
625+
Default: "IPV4",
626+
},
627+
"region": {
628+
Type: schema.TypeString,
629+
Computed: true,
630+
Optional: true,
631+
ForceNew: true,
632+
DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName,
633+
Description: `The region this gateway should sit in.`,
634+
},
635+
"stack_type": {
636+
Type: schema.TypeString,
637+
Optional: true,
638+
ForceNew: true,
639+
ValidateFunc: verify.ValidateEnum([]string{"IPV4_ONLY", "IPV4_IPV6", "IPV6_ONLY", ""}),
640+
Description: `The stack type for this VPN gateway to identify the IP protocols that are enabled.
641+
If not specified, IPV4_ONLY will be used. Default value: "IPV4_ONLY" Possible values: ["IPV4_ONLY", "IPV4_IPV6", "IPV6_ONLY"]`,
642+
Default: "IPV4_ONLY",
643+
},
644+
"vpn_interfaces": {
645+
Type: schema.TypeList,
646+
Computed: true,
647+
Optional: true,
648+
ForceNew: true,
649+
Description: `A list of interfaces on this VPN gateway.`,
650+
Elem: &schema.Resource{
651+
Schema: map[string]*schema.Schema{
652+
"id": {
653+
Type: schema.TypeInt,
654+
Optional: true,
655+
ForceNew: true,
656+
Description: `The numeric ID of this VPN gateway interface.`,
657+
},
658+
"interconnect_attachment": {
659+
Type: schema.TypeString,
660+
Optional: true,
661+
ForceNew: true,
662+
DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName,
663+
Description: `URL of the interconnect attachment resource. When the value
664+
of this field is present, the VPN Gateway will be used for
665+
IPsec-encrypted Cloud Interconnect; all Egress or Ingress
666+
traffic for this VPN Gateway interface will go through the
667+
specified interconnect attachment resource.
668+
669+
Not currently available publicly.`,
670+
},
671+
"ip_address": {
672+
Type: schema.TypeString,
673+
Computed: true,
674+
Description: `The external IP address for this VPN gateway interface.`,
675+
},
676+
},
677+
},
678+
},
679+
"project": {
680+
Type: schema.TypeString,
681+
Optional: true,
682+
Computed: true,
683+
ForceNew: true,
684+
},
685+
"self_link": {
686+
Type: schema.TypeString,
687+
Computed: true,
688+
},
689+
},
690+
UseJSONNumber: true,
691+
}
692+
}
693+
694+
func ResourceComputeHaVpnGatewayUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
695+
log.Printf("[DEBUG] Attributes before migration: %#v", rawState)
696+
697+
// Check if "gateway_ip_version" already exists
698+
if _, ok := rawState["gateway_ip_version"]; !ok {
699+
// Add the missing attribute with the default value
700+
rawState["gateway_ip_version"] = "IPV4"
701+
} else {
702+
log.Printf("[DEBUG] 'gateway_ip_version' already exists: %#v", rawState["gateway_ip_version"])
703+
}
704+
705+
log.Printf("[DEBUG] Attributes after migration: %#v", rawState)
706+
return rawState, nil
707+
}

0 commit comments

Comments
 (0)