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 #4591

Merged
merged 7 commits into from
Mar 30, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ func resourceContainerCluster() *schema.Resource {
<% unless version == 'ga' -%>
customdiff.ForceNewIfChange("enable_l4_ilb_subsetting", isBeenEnabled),
<% end -%>
containerClusterAutopilotCustomizeDiff,
),

Timeouts: &schema.ResourceTimeout{
Expand Down Expand Up @@ -241,6 +242,7 @@ func resourceContainerCluster() *schema.Resource {
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 @@ -375,6 +377,7 @@ func resourceContainerCluster() *schema.Resource {
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 @@ -474,6 +477,7 @@ func resourceContainerCluster() *schema.Resource {
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 Down Expand Up @@ -504,8 +508,17 @@ func resourceContainerCluster() *schema.Resource {
"enable_shielded_nodes": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: `Enable Shielded Nodes features on all nodes in this cluster. Defaults to false.`,
Computed: true,
Description: `Enable Shielded Nodes features on all nodes in this cluster.`,
ConflictsWith: []string{"enable_autopilot"},
},

"enable_autopilot": {
Type: schema.TypeBool,
Optional: true,
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": {
Expand All @@ -515,6 +528,7 @@ func resourceContainerCluster() *schema.Resource {
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 @@ -797,6 +811,7 @@ func resourceContainerCluster() *schema.Resource {
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 @@ -827,6 +842,7 @@ func resourceContainerCluster() *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.`,
ConflictsWith: []string{"enable_autopilot"},
},

"node_version": {
Expand Down Expand Up @@ -907,6 +923,7 @@ func resourceContainerCluster() *schema.Resource {
Type: schema.TypeList,
MaxItems: 1,
ForceNew: true,
Computed: true,
c2thorn marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -955,7 +972,6 @@ func resourceContainerCluster() *schema.Resource {
},
},

<% unless version == 'ga' -%>
"networking_mode": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -964,12 +980,12 @@ func resourceContainerCluster() *schema.Resource {
ValidateFunc: validation.StringInSlice([]string{"VPC_NATIVE", "ROUTES"}, false),
Description: `Determines whether alias IPs or routes will be used for pod IPs in the cluster.`,
},
<% end -%>

"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.`,
ConflictsWith: []string{"enable_autopilot"},
},

"private_cluster_config": {
Expand Down Expand Up @@ -1056,6 +1072,7 @@ func resourceContainerCluster() *schema.Resource {
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 @@ -1077,7 +1094,9 @@ func resourceContainerCluster() *schema.Resource {
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 @@ -1189,10 +1208,9 @@ func resourceContainerCluster() *schema.Resource {
"enable_intranode_visibility": {
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.`,
<% unless version == 'ga' -%>
Default: false,
<% end -%>
ConflictsWith: []string{"enable_autopilot"},
},
<% unless version == 'ga' -%>
"enable_l4_ilb_subsetting": {
Expand Down Expand Up @@ -1326,17 +1344,10 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er

clusterName := d.Get("name").(string)

<% unless version == 'ga' -%>
ipAllocationBlock, err := expandIPAllocationPolicy(d.Get("ip_allocation_policy"), d.Get("networking_mode").(string))
if err != nil {
return err
}
<% else -%>
ipAllocationBlock, err := expandIPAllocationPolicy(d.Get("ip_allocation_policy"))
if err != nil {
return err
}
<% end -%>

cluster := &containerBeta.Cluster{
Name: clusterName,
Expand All @@ -1362,8 +1373,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 @@ -1390,6 +1401,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 @@ -1699,6 +1717,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 @@ -2965,18 +2988,12 @@ func expandClusterAddonsConfig(configured interface{}) *containerBeta.AddonsConf
return ac
}

<% unless version == 'ga' -%>
func expandIPAllocationPolicy(configured interface{}, networkingMode string) (*containerBeta.IPAllocationPolicy, error) {
<% else -%>
func expandIPAllocationPolicy(configured interface{}) (*containerBeta.IPAllocationPolicy, error) {
<% end -%>
l := configured.([]interface{})
if len(l) == 0 || l[0] == nil {
<% unless version == 'ga' -%>
if networkingMode == "VPC_NATIVE" {
return nil, fmt.Errorf("`ip_allocation_policy` block is required for VPC_NATIVE clusters.")
}
<% end -%>
return &containerBeta.IPAllocationPolicy{
UseIpAliases: false,
ForceSendFields: []string{"UseIpAliases"},
Expand All @@ -2985,20 +3002,14 @@ func expandIPAllocationPolicy(configured interface{}) (*containerBeta.IPAllocati

config := l[0].(map[string]interface{})
return &containerBeta.IPAllocationPolicy{
<% unless version == 'ga' -%>
UseIpAliases: networkingMode == "VPC_NATIVE" || networkingMode == "",
<% else -%>
UseIpAliases: true,
<% end -%>
ClusterIpv4CidrBlock: config["cluster_ipv4_cidr_block"].(string),
ServicesIpv4CidrBlock: config["services_ipv4_cidr_block"].(string),

ClusterSecondaryRangeName: config["cluster_secondary_range_name"].(string),
ServicesSecondaryRangeName: config["services_secondary_range_name"].(string),
ForceSendFields: []string{"UseIpAliases"},
<% unless version == 'ga' -%>
UseRoutes: networkingMode == "ROUTES",
<% end -%>
}, nil
}

Expand Down Expand Up @@ -3096,6 +3107,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 @@ -3689,18 +3703,14 @@ func flattenWorkloadIdentityConfig(c *containerBeta.WorkloadIdentityConfig) []ma
func flattenIPAllocationPolicy(c *containerBeta.Cluster, d *schema.ResourceData, config *Config) ([]map[string]interface{}, error) {
// If IP aliasing isn't enabled, none of the values in this block can be set.
if c == nil || c.IpAllocationPolicy == nil || !c.IpAllocationPolicy.UseIpAliases {
<% unless version == 'ga' -%>
if err := d.Set("networking_mode", "ROUTES"); err != nil {
return nil, fmt.Errorf("Error setting networking_mode: %s", err)
}
<% end -%>
return nil, nil
}
<% unless version == 'ga' -%>
if err := d.Set("networking_mode", "VPC_NATIVE"); err != nil {
return nil, fmt.Errorf("Error setting networking_mode: %s", err)
}
<% end -%>

p := c.IpAllocationPolicy
return []map[string]interface{}{
Expand Down Expand Up @@ -4048,6 +4058,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
}

<% unless version == 'ga' -%>
func podSecurityPolicyCfgSuppress(k, old, new string, r *schema.ResourceData) bool {
if k == "pod_security_policy_config.#" && old == "1" && new == "0" {
Expand Down
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
Loading