@@ -22,17 +22,23 @@ import (
22
22
var (
23
23
instanceGroupManagerURL = regexp .MustCompile (fmt .Sprintf ("projects/(%s)/zones/([a-z0-9-]*)/instanceGroupManagers/([^/]*)" , ProjectRegex ))
24
24
25
- networkConfig = & schema.Resource {
25
+ masterAuthorizedNetworksConfig = & schema.Resource {
26
26
Schema : map [string ]* schema.Schema {
27
27
"cidr_blocks" : {
28
28
Type : schema .TypeSet ,
29
- // Despite being the only entry in a nested block, this should be kept
30
- // Optional. Expressing the parent with no entries and omitting the
29
+ // This should be kept Optional. Expressing the
30
+ // parent with no entries and omitting the
31
31
// parent entirely are semantically different.
32
32
Optional : true ,
33
33
Elem : cidrBlockConfig ,
34
34
Description : `External networks that can access the Kubernetes cluster master through HTTPS.` ,
35
35
},
36
+ "gcp_public_cidrs_access_enabled" : {
37
+ Type : schema .TypeBool ,
38
+ Optional : true ,
39
+ Computed : true ,
40
+ Description : `Whether master is accessbile via Google Compute Engine Public IP addresses.` ,
41
+ },
36
42
},
37
43
}
38
44
cidrBlockConfig = & schema.Resource {
64
70
"addons_config.0.gce_persistent_disk_csi_driver_config" ,
65
71
}
66
72
73
+ privateClusterConfigKeys = []string {
74
+ "private_cluster_config.0.enable_private_endpoint" ,
75
+ "private_cluster_config.0.enable_private_nodes" ,
76
+ "private_cluster_config.0.master_ipv4_cidr_block" ,
77
+ "private_cluster_config.0.private_endpoint_subnetwork" ,
78
+ "private_cluster_config.0.master_global_access_config" ,
79
+ }
80
+
67
81
forceNewClusterNodeConfigFields = []string {
68
82
"workload_metadata_config" ,
69
83
}
@@ -918,8 +932,9 @@ func resourceContainerCluster() *schema.Resource {
918
932
"master_authorized_networks_config" : {
919
933
Type : schema .TypeList ,
920
934
Optional : true ,
935
+ Computed : true ,
921
936
MaxItems : 1 ,
922
- Elem : networkConfig ,
937
+ Elem : masterAuthorizedNetworksConfig ,
923
938
Description : `The desired configuration options for master authorized networks. Omit the nested cidr_blocks attribute to disallow external access (except the cluster node IPs, which GKE automatically whitelists).` ,
924
939
},
925
940
@@ -1114,17 +1129,23 @@ func resourceContainerCluster() *schema.Resource {
1114
1129
Description : `Configuration for private clusters, clusters with private nodes.` ,
1115
1130
Elem : & schema.Resource {
1116
1131
Schema : map [string ]* schema.Schema {
1132
+ // enable_private_endpoint is orthogonal to private_endpoint_subnetwork.
1133
+ // User can create a private_cluster_config block without including
1134
+ // either one of those two fields. Both fields are optional.
1135
+ // At the same time, we use 'AtLeastOneOf' to prevent an empty block
1136
+ // like 'private_cluster_config{}'
1117
1137
"enable_private_endpoint" : {
1118
1138
Type : schema .TypeBool ,
1119
- Required : true ,
1120
- ForceNew : true ,
1139
+ Optional : true ,
1140
+ AtLeastOneOf : privateClusterConfigKeys ,
1121
1141
DiffSuppressFunc : containerClusterPrivateClusterConfigSuppress ,
1122
1142
Description : `When true, the cluster's private endpoint is used as the cluster endpoint and access through the public endpoint is disabled. When false, either endpoint can be used. This field only applies to private clusters, when enable_private_nodes is true.` ,
1123
1143
},
1124
1144
"enable_private_nodes" : {
1125
1145
Type : schema .TypeBool ,
1126
1146
Optional : true ,
1127
1147
ForceNew : true ,
1148
+ AtLeastOneOf : privateClusterConfigKeys ,
1128
1149
DiffSuppressFunc : containerClusterPrivateClusterConfigSuppress ,
1129
1150
Description : `Enables the private cluster feature, creating a private endpoint on the cluster. In a private cluster, nodes only have RFC 1918 private addresses and communicate with the master's private endpoint via private networking.` ,
1130
1151
},
@@ -1133,6 +1154,7 @@ func resourceContainerCluster() *schema.Resource {
1133
1154
Computed : true ,
1134
1155
Optional : true ,
1135
1156
ForceNew : true ,
1157
+ AtLeastOneOf : privateClusterConfigKeys ,
1136
1158
ValidateFunc : orEmpty (validation .IsCIDRNetwork (28 , 28 )),
1137
1159
Description : `The IP range in CIDR notation to use for the hosted master network. This range will be used for assigning private IP addresses to the cluster master(s) and the ILB VIP. This range must not overlap with any other ranges in use within the cluster's network, and it must be a /28 subnet. See Private Cluster Limitations for more details. This field only applies to private clusters, when enable_private_nodes is true.` ,
1138
1160
},
@@ -1146,17 +1168,26 @@ func resourceContainerCluster() *schema.Resource {
1146
1168
Computed : true ,
1147
1169
Description : `The internal IP address of this cluster's master endpoint.` ,
1148
1170
},
1171
+ "private_endpoint_subnetwork" : {
1172
+ Type : schema .TypeString ,
1173
+ Optional : true ,
1174
+ ForceNew : true ,
1175
+ AtLeastOneOf : privateClusterConfigKeys ,
1176
+ DiffSuppressFunc : compareSelfLinkOrResourceName ,
1177
+ Description : `Subnetwork in cluster's network where master's endpoint will be provisioned.` ,
1178
+ },
1149
1179
"public_endpoint" : {
1150
1180
Type : schema .TypeString ,
1151
1181
Computed : true ,
1152
1182
Description : `The external IP address of this cluster's master endpoint.` ,
1153
1183
},
1154
1184
"master_global_access_config" : {
1155
- Type : schema .TypeList ,
1156
- MaxItems : 1 ,
1157
- Optional : true ,
1158
- Computed : true ,
1159
- Description : "Controls cluster master global access settings." ,
1185
+ Type : schema .TypeList ,
1186
+ MaxItems : 1 ,
1187
+ Optional : true ,
1188
+ Computed : true ,
1189
+ AtLeastOneOf : privateClusterConfigKeys ,
1190
+ Description : "Controls cluster master global access settings." ,
1160
1191
Elem : & schema.Resource {
1161
1192
Schema : map [string ]* schema.Schema {
1162
1193
"enabled" : {
@@ -1535,7 +1566,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
1535
1566
Name : clusterName ,
1536
1567
InitialNodeCount : int64 (d .Get ("initial_node_count" ).(int )),
1537
1568
MaintenancePolicy : expandMaintenancePolicy (d , meta ),
1538
- MasterAuthorizedNetworksConfig : expandMasterAuthorizedNetworksConfig (d .Get ("master_authorized_networks_config" )),
1569
+ MasterAuthorizedNetworksConfig : expandMasterAuthorizedNetworksConfig (d .Get ("master_authorized_networks_config" ), d ),
1539
1570
InitialClusterVersion : d .Get ("min_master_version" ).(string ),
1540
1571
ClusterIpv4Cidr : d .Get ("cluster_ipv4_cidr" ).(string ),
1541
1572
Description : d .Get ("description" ).(string ),
@@ -2098,7 +2129,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
2098
2129
c := d .Get ("master_authorized_networks_config" )
2099
2130
req := & container.UpdateClusterRequest {
2100
2131
Update : & container.ClusterUpdate {
2101
- DesiredMasterAuthorizedNetworksConfig : expandMasterAuthorizedNetworksConfig (c ),
2132
+ DesiredMasterAuthorizedNetworksConfig : expandMasterAuthorizedNetworksConfig (c , d ),
2102
2133
},
2103
2134
}
2104
2135
@@ -2162,6 +2193,24 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
2162
2193
log .Printf ("[INFO] GKE cluster %s's binary authorization has been updated to %v" , d .Id (), enabled )
2163
2194
}
2164
2195
2196
+ if d .HasChange ("private_cluster_config.0.enable_private_endpoint" ) {
2197
+ enabled := d .Get ("private_cluster_config.0.enable_private_endpoint" ).(bool )
2198
+ req := & container.UpdateClusterRequest {
2199
+ Update : & container.ClusterUpdate {
2200
+ DesiredEnablePrivateEndpoint : enabled ,
2201
+ ForceSendFields : []string {"DesiredEnablePrivateEndpoint" },
2202
+ },
2203
+ }
2204
+
2205
+ updateF := updateFunc (req , "updating enable private endpoint" )
2206
+ // Call update serially.
2207
+ if err := lockedCall (lockKey , updateF ); err != nil {
2208
+ return err
2209
+ }
2210
+
2211
+ log .Printf ("[INFO] GKE cluster %s's enable private endpoint has been updated to %v" , d .Id (), enabled )
2212
+ }
2213
+
2165
2214
if d .HasChange ("binary_authorization" ) {
2166
2215
req := & container.UpdateClusterRequest {
2167
2216
Update : & container.ClusterUpdate {
@@ -3537,7 +3586,7 @@ func expandMasterAuth(configured interface{}) *container.MasterAuth {
3537
3586
return result
3538
3587
}
3539
3588
3540
- func expandMasterAuthorizedNetworksConfig (configured interface {}) * container.MasterAuthorizedNetworksConfig {
3589
+ func expandMasterAuthorizedNetworksConfig (configured interface {}, d * schema. ResourceData ) * container.MasterAuthorizedNetworksConfig {
3541
3590
l := configured .([]interface {})
3542
3591
if len (l ) == 0 {
3543
3592
return & container.MasterAuthorizedNetworksConfig {
@@ -3559,6 +3608,10 @@ func expandMasterAuthorizedNetworksConfig(configured interface{}) *container.Mas
3559
3608
})
3560
3609
}
3561
3610
}
3611
+ if v , ok := d .GetOkExists ("master_authorized_networks_config.0.gcp_public_cidrs_access_enabled" ); ok {
3612
+ result .GcpPublicCidrsAccessEnabled = v .(bool )
3613
+ result .ForceSendFields = []string {"GcpPublicCidrsAccessEnabled" }
3614
+ }
3562
3615
}
3563
3616
return result
3564
3617
}
@@ -3586,11 +3639,12 @@ func expandPrivateClusterConfig(configured interface{}) *container.PrivateCluste
3586
3639
}
3587
3640
config := l [0 ].(map [string ]interface {})
3588
3641
return & container.PrivateClusterConfig {
3589
- EnablePrivateEndpoint : config ["enable_private_endpoint" ].(bool ),
3590
- EnablePrivateNodes : config ["enable_private_nodes" ].(bool ),
3591
- MasterIpv4CidrBlock : config ["master_ipv4_cidr_block" ].(string ),
3592
- MasterGlobalAccessConfig : expandPrivateClusterConfigMasterGlobalAccessConfig (config ["master_global_access_config" ]),
3593
- ForceSendFields : []string {"EnablePrivateEndpoint" , "EnablePrivateNodes" , "MasterIpv4CidrBlock" , "MasterGlobalAccessConfig" },
3642
+ EnablePrivateEndpoint : config ["enable_private_endpoint" ].(bool ),
3643
+ EnablePrivateNodes : config ["enable_private_nodes" ].(bool ),
3644
+ MasterIpv4CidrBlock : config ["master_ipv4_cidr_block" ].(string ),
3645
+ MasterGlobalAccessConfig : expandPrivateClusterConfigMasterGlobalAccessConfig (config ["master_global_access_config" ]),
3646
+ PrivateEndpointSubnetwork : config ["private_endpoint_subnetwork" ].(string ),
3647
+ ForceSendFields : []string {"EnablePrivateEndpoint" , "EnablePrivateNodes" , "MasterIpv4CidrBlock" , "MasterGlobalAccessConfig" },
3594
3648
}
3595
3649
}
3596
3650
@@ -4020,6 +4074,7 @@ func flattenPrivateClusterConfig(c *container.PrivateClusterConfig) []map[string
4020
4074
"master_global_access_config" : flattenPrivateClusterConfigMasterGlobalAccessConfig (c .MasterGlobalAccessConfig ),
4021
4075
"peering_name" : c .PeeringName ,
4022
4076
"private_endpoint" : c .PrivateEndpoint ,
4077
+ "private_endpoint_subnetwork" : c .PrivateEndpointSubnetwork ,
4023
4078
"public_endpoint" : c .PublicEndpoint ,
4024
4079
},
4025
4080
}
@@ -4263,16 +4318,15 @@ func flattenMasterAuthorizedNetworksConfig(c *container.MasterAuthorizedNetworks
4263
4318
return nil
4264
4319
}
4265
4320
result := make (map [string ]interface {})
4266
- if c .Enabled {
4267
- cidrBlocks := make ([]interface {}, 0 , len (c .CidrBlocks ))
4268
- for _ , v := range c .CidrBlocks {
4269
- cidrBlocks = append (cidrBlocks , map [string ]interface {}{
4270
- "cidr_block" : v .CidrBlock ,
4271
- "display_name" : v .DisplayName ,
4272
- })
4273
- }
4274
- result ["cidr_blocks" ] = schema .NewSet (schema .HashResource (cidrBlockConfig ), cidrBlocks )
4321
+ cidrBlocks := make ([]interface {}, 0 , len (c .CidrBlocks ))
4322
+ for _ , v := range c .CidrBlocks {
4323
+ cidrBlocks = append (cidrBlocks , map [string ]interface {}{
4324
+ "cidr_block" : v .CidrBlock ,
4325
+ "display_name" : v .DisplayName ,
4326
+ })
4275
4327
}
4328
+ result ["cidr_blocks" ] = schema .NewSet (schema .HashResource (cidrBlockConfig ), cidrBlocks )
4329
+ result ["gcp_public_cidrs_access_enabled" ] = c .GcpPublicCidrsAccessEnabled
4276
4330
return []map [string ]interface {}{result }
4277
4331
}
4278
4332
@@ -4491,12 +4545,15 @@ func containerClusterPrivateClusterConfigSuppress(k, old, new string, d *schema.
4491
4545
o , n = d .GetChange ("private_cluster_config.0.enable_private_nodes" )
4492
4546
suppressNodes := ! o .(bool ) && ! n .(bool )
4493
4547
4548
+ // Do not suppress diffs when private_endpoint_subnetwork is configured
4549
+ _ , hasSubnet := d .GetOk ("private_cluster_config.0.private_endpoint_subnetwork" )
4550
+
4494
4551
if k == "private_cluster_config.0.enable_private_endpoint" {
4495
- return suppressEndpoint
4552
+ return suppressEndpoint && ! hasSubnet
4496
4553
} else if k == "private_cluster_config.0.enable_private_nodes" {
4497
- return suppressNodes
4554
+ return suppressNodes && ! hasSubnet
4498
4555
} else if k == "private_cluster_config.#" {
4499
- return suppressEndpoint && suppressNodes
4556
+ return suppressEndpoint && suppressNodes && ! hasSubnet
4500
4557
}
4501
4558
return false
4502
4559
}
0 commit comments