Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for GKE Autopilot in google_container_cluster resource #3101

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions .changelog/4591.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
```release-note:enhancement
container: add support for GKE Autopilot in `google_container_cluster`
container: promoted `networking_mode` to GA in `google_container_cluster`
```
2 changes: 2 additions & 0 deletions google-beta/data_source_google_container_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func TestAccContainerClusterDatasource_zonal(t *testing.T) {
"google_container_cluster.kubes",
// Remove once https://github.com/hashicorp/terraform/issues/21347 is fixed.
map[string]struct{}{
"enable_autopilot": {},
"enable_tpu": {},
"enable_binary_authorization": {},
"pod_security_policy_config.#": {},
Expand All @@ -48,6 +49,7 @@ func TestAccContainerClusterDatasource_regional(t *testing.T) {
"google_container_cluster.kubes",
// Remove once https://github.com/hashicorp/terraform/issues/21347 is fixed.
map[string]struct{}{
"enable_autopilot": {},
"enable_tpu": {},
"enable_binary_authorization": {},
"pod_security_policy_config.#": {},
Expand Down
141 changes: 96 additions & 45 deletions google-beta/resource_container_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func resourceContainerCluster() *schema.Resource {
resourceNodeConfigEmptyGuestAccelerator,
containerClusterPrivateClusterConfigCustomDiff,
customdiff.ForceNewIfChange("enable_l4_ilb_subsetting", isBeenEnabled),
containerClusterAutopilotCustomizeDiff,
),

Timeouts: &schema.ResourceTimeout{
Expand Down Expand Up @@ -229,12 +230,13 @@ func resourceContainerCluster() *schema.Resource {
},
},
"network_policy_config": {
Type: schema.TypeList,
Optional: true,
Computed: true,
AtLeastOneOf: addonsConfigKeys,
MaxItems: 1,
Description: `Whether we should enable the network policy addon for the master. This must be enabled in order to enable network policy for the nodes. To enable this, you must also define a network_policy block, otherwise nothing will happen. It can only be disabled if the nodes already do not have network policies enabled. Defaults to disabled; set disabled = false to enable.`,
Type: schema.TypeList,
Optional: true,
Computed: true,
AtLeastOneOf: addonsConfigKeys,
MaxItems: 1,
Description: `Whether we should enable the network policy addon for the master. This must be enabled in order to enable network policy for the nodes. To enable this, you must also define a network_policy block, otherwise nothing will happen. It can only be disabled if the nodes already do not have network policies enabled. Defaults to disabled; set disabled = false to enable.`,
ConflictsWith: []string{"enable_autopilot"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"disabled": {
Expand Down Expand Up @@ -363,9 +365,10 @@ func resourceContainerCluster() *schema.Resource {
MaxItems: 1,
// This field is Optional + Computed because we automatically set the
// enabled value to false if the block is not returned in API responses.
Optional: true,
Computed: true,
Description: `Per-cluster configuration of Node Auto-Provisioning with Cluster Autoscaler to automatically adjust the size of the cluster and create/delete node pools based on the current needs of the cluster's workload. See the guide to using Node Auto-Provisioning for more details.`,
Optional: true,
Computed: true,
Description: `Per-cluster configuration of Node Auto-Provisioning with Cluster Autoscaler to automatically adjust the size of the cluster and create/delete node pools based on the current needs of the cluster's workload. See the guide to using Node Auto-Provisioning for more details.`,
ConflictsWith: []string{"enable_autopilot"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enabled": {
Expand Down Expand Up @@ -457,10 +460,11 @@ func resourceContainerCluster() *schema.Resource {
},

"enable_binary_authorization": {
Default: false,
Type: schema.TypeBool,
Optional: true,
Description: `Enable Binary Authorization for this cluster. If enabled, all container images will be validated by Google Binary Authorization.`,
Default: false,
Type: schema.TypeBool,
Optional: true,
Description: `Enable Binary Authorization for this cluster. If enabled, all container images will be validated by Google Binary Authorization.`,
ConflictsWith: []string{"enable_autopilot"},
},

"enable_kubernetes_alpha": {
Expand All @@ -487,19 +491,29 @@ func resourceContainerCluster() *schema.Resource {
},

"enable_shielded_nodes": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: `Enable Shielded Nodes features on all nodes in this cluster.`,
ConflictsWith: []string{"enable_autopilot"},
},

"enable_autopilot": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: `Enable Shielded Nodes features on all nodes in this cluster. Defaults to false.`,
ForceNew: true,
Description: `Enable Autopilot for this cluster.`,
// ConflictsWith: many fields, see https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview#comparison. The conflict is only set one-way, on other fields w/ this field.
},

"authenticator_groups_config": {
Type: schema.TypeList,
Optional: true,
Computed: true,
ForceNew: true,
MaxItems: 1,
Description: `Configuration for the Google Groups for GKE feature.`,
Type: schema.TypeList,
Optional: true,
Computed: true,
ForceNew: true,
MaxItems: 1,
Description: `Configuration for the Google Groups for GKE feature.`,
ConflictsWith: []string{"enable_autopilot"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"security_group": {
Expand Down Expand Up @@ -769,11 +783,12 @@ func resourceContainerCluster() *schema.Resource {
},

"network_policy": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Description: `Configuration options for the NetworkPolicy feature.`,
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Description: `Configuration options for the NetworkPolicy feature.`,
ConflictsWith: []string{"enable_autopilot"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enabled": {
Expand Down Expand Up @@ -803,7 +818,8 @@ func resourceContainerCluster() *schema.Resource {
Elem: &schema.Resource{
Schema: schemaNodePool,
},
Description: `List of node pools associated with this cluster. See google_container_node_pool for schema. Warning: node pools defined inside a cluster can't be changed (or added/removed) after cluster creation without deleting and recreating the entire cluster. Unless you absolutely need the ability to say "these are the only node pools associated with this cluster", use the google_container_node_pool resource instead of this property.`,
Description: `List of node pools associated with this cluster. See google_container_node_pool for schema. Warning: node pools defined inside a cluster can't be changed (or added/removed) after cluster creation without deleting and recreating the entire cluster. Unless you absolutely need the ability to say "these are the only node pools associated with this cluster", use the google_container_node_pool resource instead of this property.`,
ConflictsWith: []string{"enable_autopilot"},
},

"node_version": {
Expand Down Expand Up @@ -882,6 +898,7 @@ func resourceContainerCluster() *schema.Resource {
Type: schema.TypeList,
MaxItems: 1,
ForceNew: true,
Computed: true,
Optional: true,
ConflictsWith: []string{"cluster_ipv4_cidr"},
Description: `Configuration of cluster IP allocation for VPC-native clusters. Adding this block enables IP aliasing, making the cluster VPC-native instead of routes-based.`,
Expand Down Expand Up @@ -940,9 +957,10 @@ func resourceContainerCluster() *schema.Resource {
},

"remove_default_node_pool": {
Type: schema.TypeBool,
Optional: true,
Description: `If true, deletes the default node pool upon cluster creation. If you're using google_container_node_pool resources with no default node pool, this should be set to true, alongside setting initial_node_count to at least 1.`,
Type: schema.TypeBool,
Optional: true,
Description: `If true, deletes the default node pool upon cluster creation. If you're using google_container_node_pool resources with no default node pool, this should be set to true, alongside setting initial_node_count to at least 1.`,
ConflictsWith: []string{"enable_autopilot"},
},

"private_cluster_config": {
Expand Down Expand Up @@ -1024,11 +1042,12 @@ func resourceContainerCluster() *schema.Resource {
},

"default_max_pods_per_node": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Computed: true,
Description: `The default maximum number of pods per node in this cluster. This doesn't work on "routes-based" clusters, clusters that don't have IP Aliasing enabled.`,
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Computed: true,
Description: `The default maximum number of pods per node in this cluster. This doesn't work on "routes-based" clusters, clusters that don't have IP Aliasing enabled.`,
ConflictsWith: []string{"enable_autopilot"},
},

"vertical_pod_autoscaling": {
Expand All @@ -1047,10 +1066,12 @@ func resourceContainerCluster() *schema.Resource {
},
},
"workload_identity_config": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Description: `Configuration for the use of Kubernetes Service Accounts in GCP IAM policies.`,
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Computed: true,
Description: `Configuration for the use of Kubernetes Service Accounts in GCP IAM policies.`,
ConflictsWith: []string{"enable_autopilot"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"identity_namespace": {
Expand Down Expand Up @@ -1158,10 +1179,11 @@ func resourceContainerCluster() *schema.Resource {
},

"enable_intranode_visibility": {
Type: schema.TypeBool,
Optional: true,
Description: `Whether Intra-node visibility is enabled for this cluster. This makes same node pod to pod traffic visible for VPC network.`,
Default: false,
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: `Whether Intra-node visibility is enabled for this cluster. This makes same node pod to pod traffic visible for VPC network.`,
ConflictsWith: []string{"enable_autopilot"},
},
"enable_l4_ilb_subsetting": {
Type: schema.TypeBool,
Expand Down Expand Up @@ -1322,8 +1344,8 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
Enabled: d.Get("enable_binary_authorization").(bool),
ForceSendFields: []string{"Enabled"},
},
ShieldedNodes: &containerBeta.ShieldedNodes{
Enabled: d.Get("enable_shielded_nodes").(bool),
Autopilot: &containerBeta.Autopilot{
Enabled: d.Get("enable_autopilot").(bool),
ForceSendFields: []string{"Enabled"},
},
ReleaseChannel: expandReleaseChannel(d.Get("release_channel")),
Expand All @@ -1342,6 +1364,13 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
ResourceLabels: expandStringMap(d, "resource_labels"),
}

if v, ok := d.GetOk("enable_shielded_nodes"); ok {
cluster.ShieldedNodes = &containerBeta.ShieldedNodes{
Enabled: v.(bool),
ForceSendFields: []string{"Enabled"},
}
}

if v, ok := d.GetOk("default_max_pods_per_node"); ok {
cluster.DefaultMaxPodsConstraint = expandDefaultMaxPodsConstraint(v)
}
Expand Down Expand Up @@ -1651,6 +1680,11 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro
if err := d.Set("enable_binary_authorization", cluster.BinaryAuthorization != nil && cluster.BinaryAuthorization.Enabled); err != nil {
return fmt.Errorf("Error setting enable_binary_authorization: %s", err)
}
if cluster.Autopilot != nil {
if err := d.Set("enable_autopilot", cluster.Autopilot.Enabled); err != nil {
return fmt.Errorf("Error setting enable_autopilot: %s", err)
}
}
if cluster.ShieldedNodes != nil {
if err := d.Set("enable_shielded_nodes", cluster.ShieldedNodes.Enabled); err != nil {
return fmt.Errorf("Error setting enable_shielded_nodes: %s", err)
Expand Down Expand Up @@ -3021,6 +3055,9 @@ func expandMaintenancePolicy(d *schema.ResourceData, meta interface{}) *containe
func expandClusterAutoscaling(configured interface{}, d *schema.ResourceData) *containerBeta.ClusterAutoscaling {
l, ok := configured.([]interface{})
if !ok || l == nil || len(l) == 0 || l[0] == nil {
if v, ok := d.GetOk("enable_autopilot"); ok && v == true {
return nil
}
return &containerBeta.ClusterAutoscaling{
EnableNodeAutoprovisioning: false,
ForceSendFields: []string{"EnableNodeAutoprovisioning"},
Expand Down Expand Up @@ -3936,6 +3973,20 @@ func containerClusterPrivateClusterConfigCustomDiff(_ context.Context, d *schema
return nil
}

// Autopilot clusters have preconfigured defaults: https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview#comparison.
// This function modifies the diff so users can see what these will be during plan time.
func containerClusterAutopilotCustomizeDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error {
if d.HasChange("enable_autopilot") && d.Get("enable_autopilot").(bool) {
if err := d.SetNew("enable_intranode_visibility", true); err != nil {
return err
}
if err := d.SetNew("enable_shielded_nodes", true); err != nil {
return err
}
}
return nil
}

func podSecurityPolicyCfgSuppress(k, old, new string, r *schema.ResourceData) bool {
if k == "pod_security_policy_config.#" && old == "1" && new == "0" {
if v, ok := r.GetOk("pod_security_policy_config"); ok {
Expand Down
Loading