Skip to content

Commit

Permalink
Add support for GKE Autopilot in google_container_cluster resource (#…
Browse files Browse the repository at this point in the history
…4591) (#3101)

Co-authored-by: Paul Jones <[email protected]>
Signed-off-by: Modular Magician <[email protected]>

Co-authored-by: Paul Jones <[email protected]>
  • Loading branch information
modular-magician and paulwilljones authored Mar 30, 2021
1 parent 38ba450 commit 5ceb93e
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 45 deletions.
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

0 comments on commit 5ceb93e

Please sign in to comment.