Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
f233324
Add support for GKE Accelerator Network Profile
ellenjzh Oct 22, 2025
5d92815
Merge branch 'main' into GKE-ANP-support
ellenjzh Oct 22, 2025
34ed6bb
Unset the local container client
ellenjzh Oct 22, 2025
9a150ce
changing the visibility to private
ellenjzh Oct 22, 2025
b157711
chang visibility of the TestAccContainerNodePool_acceleratorNetworkPr…
ellenjzh Oct 23, 2025
5dcce91
change visibility of accelerator_network_profile in meta.yaml file to…
ellenjzh Oct 23, 2025
4142462
chang visibility of the TestAccContainerNodePool_acceleratorNetworkPr…
ellenjzh Oct 23, 2025
a632037
change visibility of accelerator_network_profile in meta.yaml file to…
ellenjzh Oct 23, 2025
22c5448
Merge branch 'main' into GKE-ANP-support
ellenjzh Oct 28, 2025
c84be68
Add ForceNew to additional_node_network_configs
ellenjzh Nov 4, 2025
d6db86b
Change accelerator_network_profile Version Guard to V1Beta1
ellenjzh Nov 4, 2025
0279c7c
change config for accelerator_network_profile
ellenjzh Nov 4, 2025
ddcb650
Adding test for checking accelerator_network_profile and additional_n…
ellenjzh Nov 5, 2025
7f217ab
Update Test Case
ellenjzh Nov 5, 2025
5306804
Update Test Case
ellenjzh Nov 6, 2025
8ac77f8
Update Test Case
ellenjzh Nov 6, 2025
6d59673
Update Test Case
ellenjzh Nov 6, 2025
07b8147
Merge branch 'main' into GKE-ANP-support
ellenjzh Nov 7, 2025
9030c54
Update machine type to a2-highgpu-1g
ellenjzh Nov 7, 2025
b991e1c
Change machine type
ellenjzh Nov 7, 2025
04c946f
Change machine type to a3-highgpu-8g
ellenjzh Nov 8, 2025
57fb041
add test
ellenjzh Dec 8, 2025
e239557
Added ANP CustomizeDiff
ellenjzh Dec 15, 2025
f93ce25
Added ANP CustomizeDiff function
ellenjzh Dec 15, 2025
a5feeda
Updated ANP tests
ellenjzh Dec 17, 2025
9b26e66
Added version guard to nodePoolAcceleratorNetworkProfileCustomizeDiff
ellenjzh Dec 17, 2025
6ac4b40
Enable Flex-start for A3-highgpu-8g machine
ellenjzh Jan 8, 2026
acdbfef
Enable Flex-start for A3-highgpu-8g machine
ellenjzh Jan 8, 2026
da880fa
Enable Flex-start for A3-highgpu-8g machine
ellenjzh Jan 8, 2026
92f631b
Enable Flex-start for A3-highgpu-8g machine
ellenjzh Jan 8, 2026
afe6d83
Enable Flex-start for A3-highgpu-8g machine
ellenjzh Jan 8, 2026
15788a5
Enable Flex-start for A3-highgpu-8g machine
ellenjzh Jan 9, 2026
7eb4e4c
acctest.VcrTest to enable request recording
ellenjzh Jan 13, 2026
6b19f15
acctest.VcrTest to enable request recording
ellenjzh Jan 13, 2026
e0daabc
Added ANP in cluster meta.yaml
ellenjzh Jan 13, 2026
a2fea2f
Updated ANP in cluster meta yaml
ellenjzh Jan 13, 2026
f8d272a
Added ANP cluster tests
ellenjzh Jan 14, 2026
326b968
Merge branch 'main' into GKE-ANP-support
ellenjzh Jan 14, 2026
da20cba
Added ANP clusters tests
ellenjzh Jan 14, 2026
d577f38
Added ANP clusters tests
ellenjzh Jan 15, 2026
6c9e632
Updated ANP cluster customizeDiff func
ellenjzh Jan 15, 2026
a7e075d
Merge branch 'main' into GKE-ANP-support
ellenjzh Jan 15, 2026
256c83c
Added api field in node pool meta yaml
ellenjzh Jan 16, 2026
3045323
Fix: restore missing node_drain_config schema and add ANP api_field
ellenjzh Jan 16, 2026
02e46af
Fix: restore missing node_drain_config schema
ellenjzh Jan 16, 2026
06e9dde
Updated test cases
ellenjzh Jan 20, 2026
65081de
Updated test cases
ellenjzh Jan 20, 2026
024be3e
Separate config/import steps
melinath Jan 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ func ResourceContainerNodePool() *schema.Resource {
CustomizeDiff: customdiff.All(
tpgresource.DefaultProviderProject,
resourceNodeConfigEmptyGuestAccelerator,
nodePoolAcceleratorNetworkProfileCustomizeDiff,
),

UseJSONNumber: true,
Expand Down Expand Up @@ -522,6 +523,14 @@ var schemaNodePool = map[string]*schema.Schema{
Description: `Networking configuration for this NodePool. If specified, it overrides the cluster-level defaults.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
{{ if ne $.TargetVersionName `ga` }}
"accelerator_network_profile": {
Type: schema.TypeString,
Description: "The accelerator network profile to use for this node pool.",
Optional: true,
ForceNew: true,
},
{{- end }}
"create_pod_range": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -552,20 +561,23 @@ var schemaNodePool = map[string]*schema.Schema{
"additional_node_network_configs": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Computed: true,
ForceNew: true,
Description: `We specify the additional node networks for this node pool using this list. Each node network corresponds to an additional interface`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"network": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been a while, so just to triple-check before we make these changes: Optional+Computed means that if the user has a value set for this field and then removes the field from their config, Terraform will consider it to still be set to the last value returned from the API (the last value the user had set).

Will that cause any problems on any of these fields?

Potential impacts could include:

  • User thinks that network is unset but actually it's still set to the last value they had here.
  • User thinks that the resource will be recreated (because it's ForceNew) after removing a value but nothing happens (because Terraform silently persists their previous value)
  • There's an error at the API layer because this field conflicts with some other field, and we keep sending the previous value for this field in addition to the new value for the other field. (This would only matter if the other field isn't ForceNew - so I think we're good.)

The flipside, just for my own reference / to make sure I've got it right, is that all these fields will have API defaults if accelerator_network_profile is set - so having O+C is necessary to avoid permadiffs (which would cause resource destruction!) in that case.

ForceNew: true,
Description: `Name of the VPC where the additional interface belongs.`,
},
"subnetwork": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ForceNew: true,
Description: `Name of the subnetwork where the additional interface belongs.`,
},
},
Expand Down Expand Up @@ -639,7 +651,6 @@ var schemaNodePool = map[string]*schema.Schema{
},
},
},

}

type NodePoolInformation struct {
Expand Down Expand Up @@ -1438,6 +1449,9 @@ func flattenNodeNetworkConfig(c *container.NodeNetworkConfig, d *schema.Resource
"additional_node_network_configs": flattenAdditionalNodeNetworkConfig(c.AdditionalNodeNetworkConfigs),
"additional_pod_network_configs": flattenAdditionalPodNetworkConfig(c.AdditionalPodNetworkConfigs),
"subnetwork": c.Subnetwork,
{{ if ne $.TargetVersionName `ga` }}
"accelerator_network_profile": c.AcceleratorNetworkProfile,
{{- end }}
})
}
return result
Expand Down Expand Up @@ -1552,7 +1566,11 @@ func expandNodeNetworkConfig(v interface{}) *container.NodeNetworkConfig {
nnc.NetworkPerformanceConfig.TotalEgressBandwidthTier = total_egress_bandwidth_tier.(string)
}
}

{{ if ne $.TargetVersionName `ga` }}
if v, ok := networkNodeConfig["accelerator_network_profile"]; ok {
nnc.AcceleratorNetworkProfile = v.(string)
}
{{- end }}
return nnc
}

Expand Down Expand Up @@ -1917,3 +1935,97 @@ func retryWhileIncompatibleOperation(timeout time.Duration, lockKey string, f fu
return nil
})
}

func nodePoolAcceleratorNetworkProfileCustomizeDiff(_ context.Context, diff *schema.ResourceDiff, meta any) error {
log.Printf("[DEBUG] ANP CustomizeDiff: Running...")

// 1. SKIP ON CREATE
if diff.Id() == "" {
log.Printf("[DEBUG] ANP CustomizeDiff: SKIP - Resource is being created (no ID).")
return nil
}

// 2. DETECT USER CONFIG
userHasAdditionalConfigs := false
rawConfig := diff.GetRawConfig()
rawNetworkConfig := rawConfig.GetAttr("network_config")

if !rawNetworkConfig.IsNull() {
if rawNetworkConfig.Type().IsCollectionType() {
it := rawNetworkConfig.ElementIterator()
for it.Next() {
_, val := it.Element()
userConfig := val.GetAttr("additional_node_network_configs")
if !userConfig.IsNull() && userConfig.LengthInt() > 0 {
userHasAdditionalConfigs = true
break
}
}
}
}

// 3. LOGIC CHECK
shouldClear := false

oldProfile, newProfile := diff.GetChange("network_config.0.accelerator_network_profile")
anpIsActive := newProfile.(string) != ""
anpIsChanging := oldProfile.(string) != newProfile.(string)

if !userHasAdditionalConfigs {
if anpIsActive && anpIsChanging {
shouldClear = true
}
if !anpIsActive {
shouldClear = true
}
}

// Check the OLD state to avoid "Plan Not Empty" on defaults
currentCount := 0
if c, ok := diff.Get("network_config.0.additional_node_network_configs.#").(int); ok {
currentCount = c
}

log.Printf("[DEBUG] ANP CustomizeDiff: ANALYSIS: ID=%s, UserHasConfig=%v, ANP=%v, CurrentCount=%d",
diff.Id(), userHasAdditionalConfigs, anpIsActive, currentCount)

if shouldClear {
if currentCount == 0 {
log.Printf("[DEBUG] ANP CustomizeDiff: ACTION SKIPPED - Config is already empty (Count is 0). Avoiding drift.")
shouldClear = false
} else {
log.Printf("[DEBUG] ANP CustomizeDiff: ACTION REQUIRED - Sticky value detected (Count is %d). Clearing it.", currentCount)
}
} else {
log.Printf("[DEBUG] ANP CustomizeDiff: NO ACTION - Conditions not met.")
}

// 4. EXECUTE THE FIX
if shouldClear {
log.Printf("[DEBUG] ANP CustomizeDiff: EXECUTING FIX - Rewriting network_config block...")
var newConfigMap map[string]interface{}
existingConfigs := diff.Get("network_config").([]interface{})

if len(existingConfigs) > 0 && existingConfigs[0] != nil {
currentMap := existingConfigs[0].(map[string]interface{})
newConfigMap = make(map[string]interface{})
for k, v := range currentMap {
newConfigMap[k] = v
}
} else {
newConfigMap = make(map[string]interface{})
}

newConfigMap["additional_node_network_configs"] = []interface{}{}
if !anpIsActive {
newConfigMap["accelerator_network_profile"] = ""
}

err := diff.SetNew("network_config", []interface{}{newConfigMap})
if err != nil {
return fmt.Errorf("Error updating network_config: %s", err)
}
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ fields:
- api_field: 'name'
- field: 'name_prefix'
provider_only: true
{{ if ne $.TargetVersionName `ga` }}
- field: 'network_config.accelerator_network_profile'
{{- end }}
- api_field: 'networkConfig.additionalNodeNetworkConfigs.network'
- api_field: 'networkConfig.additionalNodeNetworkConfigs.subnetwork'
- field: 'network_config.additional_pod_network_configs.max_pods_per_node'
Expand Down
Loading
Loading