diff --git a/examples/gke-regional-public-cluster/main.tf b/examples/gke-regional-public-cluster/main.tf index b730b67..e50124c 100644 --- a/examples/gke-regional-public-cluster/main.tf +++ b/examples/gke-regional-public-cluster/main.tf @@ -21,26 +21,25 @@ module "gke_cluster" { # source = "git::git@github.com:gruntwork-io/gke-cluster.git//modules/gke-cluster?ref=v0.0.1" source = "../../modules/gke-cluster" - project = "${var.project}" - region = "${var.region}" - name = "${var.cluster_name}" + name = "${var.cluster_name}" - network = "${google_compute_network.main.name}" - subnetwork = "${google_compute_subnetwork.main.name}" - ip_range_pods = "${google_compute_subnetwork.main.secondary_ip_range.0.range_name}" - ip_range_services = "${google_compute_subnetwork.main.secondary_ip_range.1.range_name}" - - #service_account = "${var.compute_engine_service_account}" + project = "${var.project}" + region = "${var.region}" + network = "${google_compute_network.main.name}" + subnetwork = "${google_compute_subnetwork.main.name}" } # Node Pool // Node Pool Resource resource "google_container_node_pool" "node_pool" { - name = "main-pool" - project = "${var.project}" - region = "${var.region}" - cluster = "${module.gke_cluster.name}" + provider = "google-beta" + + name = "main-pool" + project = "${var.project}" + region = "${var.region}" + cluster = "${module.gke_cluster.name}" + initial_node_count = "1" autoscaling { @@ -61,23 +60,11 @@ resource "google_container_node_pool" "node_pool" { all-pools-example = "true" } - # for custom shutdown scripts etc - # metadata = "" - - - #[DEPRECATED] This field is in beta and will be removed from this provider. Use it in the the google-beta provider instead. - # See https://terraform.io/docs/providers/google/provider_versions.html for more details. - #taint = { - # key = "main-pool-example" - # value = "true" - # effect = "PREFER_NO_SCHEDULE" - #} - tags = ["main-pool-example"] disk_size_gb = "30" disk_type = "pd-standard" - #service_account = "${lookup(var.node_pools[count.index], "service_account", var.service_account)}" - preemptible = false + preemptible = false + oauth_scopes = [ "https://www.googleapis.com/auth/cloud-platform", ] @@ -94,8 +81,7 @@ resource "google_container_node_pool" "node_pool" { } } -# Network - +# TODO(rileykarson): Add proper VPC network config once we've made a VPC module resource "random_string" "suffix" { length = 4 special = false @@ -103,23 +89,13 @@ resource "random_string" "suffix" { } resource "google_compute_network" "main" { - name = "cft-gke-test-${random_string.suffix.result}" + name = "${var.cluster_name}-network-${random_string.suffix.result}" auto_create_subnetworks = "false" } resource "google_compute_subnetwork" "main" { - name = "cft-gke-test-${random_string.suffix.result}" + name = "${var.cluster_name}-subnetwork-${random_string.suffix.result}" ip_cidr_range = "10.0.0.0/17" region = "${var.region}" network = "${google_compute_network.main.self_link}" - - secondary_ip_range { - range_name = "cft-gke-test-pods-${random_string.suffix.result}" - ip_cidr_range = "192.168.0.0/18" - } - - secondary_ip_range { - range_name = "cft-gke-test-services-${random_string.suffix.result}" - ip_cidr_range = "192.168.64.0/18" - } } diff --git a/examples/gke-regional-public-cluster/outputs.tf b/examples/gke-regional-public-cluster/outputs.tf index a63131e..86bf70d 100644 --- a/examples/gke-regional-public-cluster/outputs.tf +++ b/examples/gke-regional-public-cluster/outputs.tf @@ -1,5 +1,11 @@ output "cluster_endpoint" { - #sensitive = true - description = "Cluster endpoint" + description = "The IP address of the cluster master." + sensitive = true value = "${module.gke_cluster.endpoint}" } + +output "cluster_ca_certificate" { + description = "The public certificate that is the root of trust for the cluster. Encoded as base64." + sensitive = true + value = "${module.gke_cluster.cluster_ca_certificate}" +} diff --git a/examples/gke-regional-public-cluster/variables.tf b/examples/gke-regional-public-cluster/variables.tf index 9c6c24b..d9beee1 100644 --- a/examples/gke-regional-public-cluster/variables.tf +++ b/examples/gke-regional-public-cluster/variables.tf @@ -20,17 +20,3 @@ variable "cluster_name" { description = "The name of the Kubernetes cluster." default = "example-cluster" } - -#variable "ip_range_pods" { -# description = "The secondary ip range to use for pods" -#} - - -#variable "ip_range_services" { -# description = "The secondary ip range to use for pods" -#} - - -#variable "compute_engine_service_account" { -# description = "Service account to associate to the nodes in the cluster" -#} diff --git a/modules/gke-cluster/main.tf b/modules/gke-cluster/main.tf index 71a04f1..1366bfa 100644 --- a/modules/gke-cluster/main.tf +++ b/modules/gke-cluster/main.tf @@ -1,13 +1,14 @@ resource "google_container_cluster" "cluster" { name = "${var.name}" description = "${var.description}" - project = "${var.project}" - region = "${var.region}" - additional_zones = ["${coalescelist(compact(var.zones), sort(random_shuffle.available_zones.result))}"] + project = "${var.project}" + region = "${var.region}" + network = "${replace(data.google_compute_network.gke_network.self_link, "https://www.googleapis.com/compute/v1/", "")}" + subnetwork = "${replace(data.google_compute_subnetwork.gke_subnetwork.self_link, "https://www.googleapis.com/compute/v1/", "")}" - network = "${replace(data.google_compute_network.gke_network.self_link, "https://www.googleapis.com/compute/v1/", "")}" - subnetwork = "${replace(data.google_compute_subnetwork.gke_subnetwork.self_link, "https://www.googleapis.com/compute/v1/", "")}" + logging_service = "${var.logging_service}" + monitoring_service = "${var.monitoring_service}" min_master_version = "${local.kubernetes_version}" # We want to make a cluster with no node pools, and manage them all with the @@ -23,11 +24,6 @@ resource "google_container_cluster" "cluster" { initial_node_count = 1 - logging_service = "${var.logging_service}" - monitoring_service = "${var.monitoring_service}" - - master_authorized_networks_config = "${var.master_authorized_networks_config}" - addons_config { http_load_balancing { disabled = "${var.http_load_balancing ? 0 : 1}" @@ -38,29 +34,38 @@ resource "google_container_cluster" "cluster" { } kubernetes_dashboard { - disabled = "${var.kubernetes_dashboard ? 0 : 1}" + disabled = "${var.enable_kubernetes_dashboard ? 0 : 1}" } network_policy_config { - disabled = "${var.network_policy ? 0 : 1}" + disabled = "${var.enable_network_policy ? 0 : 1}" } } - ip_allocation_policy { - cluster_secondary_range_name = "${var.ip_range_pods}" - services_secondary_range_name = "${var.ip_range_services}" + network_policy { + enabled = "${var.enable_network_policy}" + + # Tigera (Calico Felix) is the only provider + provider = "CALICO" + } + + master_auth { + username = "${var.basic_auth_username}" + password = "${var.basic_auth_password}" + + client_certificate_config { + issue_client_certificate = "${var.enable_kubernetes_dashboard}" + } } + master_authorized_networks_config = "${var.master_authorized_networks_config}" + maintenance_policy { daily_maintenance_window { start_time = "${var.maintenance_start_time}" } } - lifecycle { - ignore_changes = ["node_pool"] - } - # Version 2.0.0 will set the default timeouts to these values. timeouts { create = "30m" @@ -69,19 +74,11 @@ resource "google_container_cluster" "cluster" { } } -// TODO -// Add Data Source to get the latest k8s version -// Use this is k8s version is not set. locals { kubernetes_version = "${var.kubernetes_version != "latest" ? var.kubernetes_version : data.google_container_engine_versions.region.latest_node_version}" network_project = "${var.network_project != "" ? var.network_project : var.project}" } -data "google_compute_zones" "available" { - project = "${var.project}" - region = "${var.region}" -} - data "google_compute_network" "gke_network" { name = "${var.network}" project = "${local.network_project}" @@ -93,14 +90,7 @@ data "google_compute_subnetwork" "gke_subnetwork" { project = "${local.network_project}" } -resource "random_shuffle" "available_zones" { - input = ["${data.google_compute_zones.available.names}"] - result_count = 3 -} - -/****************************************** - Get available container engine versions - *****************************************/ +// Get available master versions in our region to determine the latest version data "google_container_engine_versions" "region" { region = "${var.region}" project = "${var.project}" diff --git a/modules/gke-cluster/outputs.tf b/modules/gke-cluster/outputs.tf index 2471b5d..20da6e6 100644 --- a/modules/gke-cluster/outputs.tf +++ b/modules/gke-cluster/outputs.tf @@ -1,40 +1,30 @@ output "name" { - description = "Cluster name" + # This may seem redundant with the `name` input, but it serves an important + # purpose. Terraform won't establish a dependency graph without this to interpolate on. + description = "The name of the cluster master. This output is used for interpolation with node pools, other modules." value = "${google_container_cluster.cluster.name}" } -output "region" { - description = "Cluster region" - value = "${google_container_cluster.cluster.region}" + +output "master_version" { + description = "The Kubernetes master version." + value = "${google_container_cluster.cluster.master_version}" } output "endpoint" { + description = "The IP address of the cluster master." sensitive = true - description = "Cluster endpoint" value = "${google_container_cluster.cluster.endpoint}" } -output "min_master_version" { - description = "Minimum master kubernetes version" - value = "${google_container_cluster.cluster.min_master_version}" -} - -output "logging_service" { - description = "Logging service used" - value = "${google_container_cluster.cluster.logging_service}" -} - -output "monitoring_service" { - description = "Monitoring service used" - value = "${google_container_cluster.cluster.monitoring_service}" +output "cluster_ca_certificate" { + description = "The public certificate that is the root of trust for the cluster. Encoded as base64." + sensitive = true + value = "${google_container_cluster.cluster.master_auth.0.cluster_ca_certificate}" } +// TODO(robmorgan): Is this a useful output? output "master_authorized_networks_config" { description = "Networks from which access to master is permitted" value = "${var.master_authorized_networks_config}" } - -output "kubernetes_dashboard_enabled" { - description = "Whether kubernetes dashboard enabled" - value = "${element(concat(google_container_cluster.cluster.*.addons_config.0.kubernetes_dashboard.0.disabled, list("")), 0)}" -} diff --git a/modules/gke-cluster/variables.tf b/modules/gke-cluster/variables.tf index 2eb059f..463be08 100644 --- a/modules/gke-cluster/variables.tf +++ b/modules/gke-cluster/variables.tf @@ -8,27 +8,19 @@ variable "project" { } variable "region" { - description = "The region to host the cluster in (required)" + description = "The region to host the cluster in" } variable "name" { - description = "The name of the cluster (required)" + description = "The name of the cluster" } variable "network" { - description = "The VPC network to host the cluster in (required)" + description = "The VPC network to host the cluster in" } variable "subnetwork" { - description = "The subnetwork to host the cluster in (required)" -} - -variable "ip_range_pods" { - description = "The secondary ip range to use for pods" -} - -variable "ip_range_services" { - description = "The secondary ip range to use for pods" + description = "The subnetwork to host the cluster in" } # --------------------------------------------------------------------------------------------------------------------- @@ -41,22 +33,38 @@ variable "description" { default = "" } -variable "zones" { - type = "list" - description = "TODO" - default = [] +variable "kubernetes_version" { + description = "The Kubernetes version of the masters. If set to 'latest' it will pull latest available version in the selected region." + default = "latest" +} + +variable "logging_service" { + description = "The logging service that the cluster should write logs to. Available options include logging.googleapis.com, logging.googleapis.com/kubernetes (beta), and none" + default = "logging.googleapis.com" +} + +variable "monitoring_service" { + description = "The monitoring service that the cluster should write metrics to. Automatically send metrics from pods in the cluster to the Google Cloud Monitoring API. VM metrics will be collected by Google Compute Engine regardless of this setting Available options include monitoring.googleapis.com, monitoring.googleapis.com/kubernetes (beta) and none" + default = "monitoring.googleapis.com" +} + +variable "horizontal_pod_autoscaling" { + description = "Whether to enable the horizontal pod autoscaling addon" + default = true +} + +variable "http_load_balancing" { + description = "Whether to enable the http (L7) load balancing addon" + default = true } +// TODO(robmorgan): Are we using these values below? We should understand them more fully before adding them to configs. + variable "network_project" { description = "The project ID of the shared VPC's host (for shared vpc support)" default = "" } -variable "kubernetes_version" { - description = "The Kubernetes version of the masters. If set to 'latest' it will pull latest available version in the selected region." - default = "latest" -} - variable "master_authorized_networks_config" { type = "list" @@ -74,26 +82,6 @@ variable "master_authorized_networks_config" { default = [] } -variable "horizontal_pod_autoscaling" { - description = "Enable horizontal pod autoscaling addon" - default = true -} - -variable "http_load_balancing" { - description = "Enable httpload balancer addon" - default = true -} - -variable "kubernetes_dashboard" { - description = "Enable kubernetes dashboard addon" - default = false -} - -variable "network_policy" { - description = "Enable network policy addon" - default = false -} - variable "maintenance_start_time" { description = "Time window specified for daily maintenance operations in RFC3339 format" default = "05:00" @@ -121,17 +109,37 @@ variable "ip_masq_link_local" { default = "false" } -variable "logging_service" { - description = "The logging service that the cluster should write logs to. Available options include logging.googleapis.com, logging.googleapis.com/kubernetes (beta), and none" - default = "logging.googleapis.com" +# --------------------------------------------------------------------------------------------------------------------- +# OPTIONAL PARAMETERS - RECOMMENDED DEFAULTS +# These values shouldn't be changed; they're following the best practices defined at https://cloud.google.com/kubernetes-engine/docs/how-to/hardening-your-cluster +# --------------------------------------------------------------------------------------------------------------------- + +variable "enable_kubernetes_dashboard" { + description = "Whether to enable the Kubernetes Web UI (Dashboard). The Web UI requires a highly privileged security account." + default = false } -variable "monitoring_service" { - description = "The monitoring service that the cluster should write metrics to. Automatically send metrics from pods in the cluster to the Google Cloud Monitoring API. VM metrics will be collected by Google Compute Engine regardless of this setting Available options include monitoring.googleapis.com, monitoring.googleapis.com/kubernetes (beta) and none" - default = "monitoring.googleapis.com" +variable "enable_legacy_abac" { + description = "Whether to enable legacy Attribute-Based Access Control (ABAC). RBAC has significant security advantages over ABAC." + default = false +} + +variable "enable_network_policy" { + description = "Whether to enable Kubernetes NetworkPolicy on the master, which is required to be enabled to be used on Nodes." + default = true } -#variable "service_account" { -# description = "The service account to default running nodes as if not overridden in `node_pools`. Defaults to the compute engine default service account" -# default = "" -#} +variable "basic_auth_username" { + description = "The username used for basic auth; set both this and `basic_auth_password` to \"\" to disable basic auth." + default = "" +} + +variable "basic_auth_password" { + description = "The password used for basic auth; set both this and `basic_auth_username` to \"\" to disable basic auth." + default = "" +} + +variable "enable_client_certificate_authentication" { + description = "Whether to enable authentication by x509 certificates. With ABAC disabled, these certificates are effectively useless." + default = false +}