diff --git a/.kitchen.yml b/.kitchen.yml index 5cd1359866..e805d0ba97 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -72,6 +72,18 @@ suites: backend: local provisioner: name: terraform + - name: "simple_regional_private" + driver: + name: "terraform" + command_timeout: 1800 + root_module_directory: test/fixtures/simple_regional_private + verifier: + name: terraform + systems: + - name: simple_regional_private + backend: local + provisioner: + name: terraform - name: "simple_zonal" driver: name: "terraform" @@ -84,6 +96,18 @@ suites: backend: local provisioner: name: terraform + - name: "simple_zonal_private" + driver: + name: "terraform" + command_timeout: 1800 + root_module_directory: test/fixtures/simple_zonal_private + verifier: + name: terraform + systems: + - name: simple_zonal_private + backend: local + provisioner: + name: terraform - name: "stub_domains" driver: name: "terraform" diff --git a/cluster_regional.tf b/cluster_regional.tf index cfcba59eab..d23c7725a0 100644 --- a/cluster_regional.tf +++ b/cluster_regional.tf @@ -19,7 +19,7 @@ *****************************************/ resource "google_container_cluster" "primary" { provider = "google-beta" - count = "${var.regional ? 1 : 0}" + count = "${(local.cluster_deployment_type == "regional") ? 1 : 0}" name = "${var.name}" description = "${var.description}" project = "${var.project_id}" @@ -34,7 +34,7 @@ resource "google_container_cluster" "primary" { logging_service = "${var.logging_service}" monitoring_service = "${var.monitoring_service}" - master_authorized_networks_config = "${var.master_authorized_networks_config}" + master_authorized_networks_config = ["${var.master_authorized_networks_config}"] addons_config { http_load_balancing { @@ -89,7 +89,7 @@ resource "google_container_cluster" "primary" { *****************************************/ resource "google_container_node_pool" "pools" { provider = "google-beta" - count = "${var.regional ? length(var.node_pools) : 0}" + count = "${(local.cluster_deployment_type == "regional") ? length(var.node_pools) : 0}" name = "${lookup(var.node_pools[count.index], "name")}" project = "${var.project_id}" region = "${var.region}" @@ -138,7 +138,7 @@ resource "google_container_node_pool" "pools" { } resource "null_resource" "wait_for_regional_cluster" { - count = "${var.regional ? 1 : 0}" + count = "${(local.cluster_deployment_type == "regional") ? 1 : 0}" provisioner "local-exec" { command = "${path.module}/scripts/wait-for-cluster.sh ${var.project_id} ${var.name}" diff --git a/cluster_regional_private.tf b/cluster_regional_private.tf new file mode 100644 index 0000000000..64d9fbfecf --- /dev/null +++ b/cluster_regional_private.tf @@ -0,0 +1,153 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************** + Create regional cluster + *****************************************/ +resource "google_container_cluster" "primary_private" { + provider = "google-beta" + count = "${(local.cluster_deployment_type == "regional_private") ? 1 : 0}" + name = "${var.name}" + description = "${var.description}" + project = "${var.project_id}" + + region = "${var.region}" + additional_zones = ["${coalescelist(compact(var.zones), sort(random_shuffle.available_zones.result))}"] + + network = "${data.google_compute_network.gke_network.self_link}" + subnetwork = "${data.google_compute_subnetwork.gke_subnetwork.self_link}" + min_master_version = "${local.kubernetes_version}" + + 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}" + } + + horizontal_pod_autoscaling { + disabled = "${var.horizontal_pod_autoscaling ? 0 : 1}" + } + + kubernetes_dashboard { + disabled = "${var.kubernetes_dashboard ? 0 : 1}" + } + + network_policy_config { + disabled = "${var.network_policy ? 0 : 1}" + } + } + + ip_allocation_policy { + cluster_secondary_range_name = "${var.ip_range_pods}" + services_secondary_range_name = "${var.ip_range_services}" + } + + maintenance_policy { + daily_maintenance_window { + start_time = "${var.maintenance_start_time}" + } + } + + lifecycle { + ignore_changes = ["node_pool"] + } + + timeouts { + create = "30m" + update = "30m" + delete = "30m" + } + + node_pool { + name = "default-pool" + + node_config { + service_account = "${lookup(var.node_pools[0], "service_account", var.service_account)}" + } + } +} + +/****************************************** + Create regional node pools + *****************************************/ +resource "google_container_node_pool" "pools_private" { + provider = "google-beta" + count = "${(local.cluster_deployment_type == "regional_private") ? length(var.node_pools) : 0}" + name = "${lookup(var.node_pools[count.index], "name")}" + project = "${var.project_id}" + region = "${var.region}" + cluster = "${var.name}" + version = "${lookup(var.node_pools[count.index], "auto_upgrade", false) ? "" : lookup(var.node_pools[count.index], "version", local.node_version)}" + initial_node_count = "${lookup(var.node_pools[count.index], "min_count", 1)}" + + autoscaling { + min_node_count = "${lookup(var.node_pools[count.index], "min_count", 1)}" + max_node_count = "${lookup(var.node_pools[count.index], "max_count", 100)}" + } + + management { + auto_repair = "${lookup(var.node_pools[count.index], "auto_repair", true)}" + auto_upgrade = "${lookup(var.node_pools[count.index], "auto_upgrade", true)}" + } + + node_config { + image_type = "${lookup(var.node_pools[count.index], "image_type", "COS")}" + machine_type = "${lookup(var.node_pools[count.index], "machine_type", "n1-standard-2")}" + labels = "${merge(map("cluster_name", var.name), map("node_pool", lookup(var.node_pools[count.index], "name")), var.node_pools_labels["all"], var.node_pools_labels[lookup(var.node_pools[count.index], "name")])}" + taint = "${concat(var.node_pools_taints["all"], var.node_pools_taints[lookup(var.node_pools[count.index], "name")])}" + tags = "${concat(list("gke-${var.name}"), list("gke-${var.name}-${lookup(var.node_pools[count.index], "name")}"), var.node_pools_tags["all"], var.node_pools_tags[lookup(var.node_pools[count.index], "name")])}" + + disk_size_gb = "${lookup(var.node_pools[count.index], "disk_size_gb", 100)}" + disk_type = "${lookup(var.node_pools[count.index], "disk_type", "pd-standard")}" + service_account = "${lookup(var.node_pools[count.index], "service_account", var.service_account)}" + preemptible = "${lookup(var.node_pools[count.index], "preemptible", false)}" + + oauth_scopes = [ + "https://www.googleapis.com/auth/cloud-platform", + ] + } + + lifecycle { + ignore_changes = ["initial_node_count"] + } + + timeouts { + create = "30m" + update = "30m" + delete = "30m" + } + + depends_on = ["google_container_cluster.primary_private"] +} + +resource "null_resource" "wait_for_private_regional_cluster" { + count = "${(local.cluster_deployment_type == "regional_private") ? 1 : 0}" + + provisioner "local-exec" { + command = "${path.module}/scripts/wait-for-cluster.sh ${var.project_id} ${var.name}" + } + + provisioner "local-exec" { + when = "destroy" + command = "${path.module}/scripts/wait-for-cluster.sh ${var.project_id} ${var.name}" + } + + depends_on = ["google_container_cluster.primary_private", "google_container_node_pool.pools_private"] +} diff --git a/cluster_zonal.tf b/cluster_zonal.tf index 4cff1859ab..f2c6fe4f42 100644 --- a/cluster_zonal.tf +++ b/cluster_zonal.tf @@ -19,7 +19,7 @@ *****************************************/ resource "google_container_cluster" "zonal_primary" { provider = "google-beta" - count = "${var.regional ? 0 : 1}" + count = "${(local.cluster_deployment_type == "zonal") ? 1 : 0}" name = "${var.name}" description = "${var.description}" project = "${var.project_id}" @@ -34,7 +34,7 @@ resource "google_container_cluster" "zonal_primary" { logging_service = "${var.logging_service}" monitoring_service = "${var.monitoring_service}" - master_authorized_networks_config = "${var.master_authorized_networks_config}" + master_authorized_networks_config = ["${var.master_authorized_networks_config}"] addons_config { http_load_balancing { @@ -89,7 +89,7 @@ resource "google_container_cluster" "zonal_primary" { *****************************************/ resource "google_container_node_pool" "zonal_pools" { provider = "google-beta" - count = "${var.regional ? 0 : length(var.node_pools)}" + count = "${(local.cluster_deployment_type == "zonal") ? length(var.node_pools) : 0}" name = "${lookup(var.node_pools[count.index], "name")}" project = "${var.project_id}" zone = "${var.zones[0]}" @@ -138,7 +138,7 @@ resource "google_container_node_pool" "zonal_pools" { } resource "null_resource" "wait_for_zonal_cluster" { - count = "${var.regional ? 0 : 1}" + count = "${(local.cluster_deployment_type == "zonal") ? 1 : 0}" provisioner "local-exec" { command = "${path.module}/scripts/wait-for-cluster.sh ${var.project_id} ${var.name}" diff --git a/cluster_zonal_private.tf b/cluster_zonal_private.tf new file mode 100644 index 0000000000..00be1120d2 --- /dev/null +++ b/cluster_zonal_private.tf @@ -0,0 +1,153 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************** + Create zonal cluster + *****************************************/ +resource "google_container_cluster" "zonal_primary_private" { + provider = "google-beta" + count = "${(local.cluster_deployment_type == "zonal_private") ? 1 : 0}" + name = "${var.name}" + description = "${var.description}" + project = "${var.project_id}" + + zone = "${var.zones[0]}" + additional_zones = ["${slice(var.zones,1,length(var.zones))}"] + + network = "${data.google_compute_network.gke_network.self_link}" + subnetwork = "${data.google_compute_subnetwork.gke_subnetwork.self_link}" + min_master_version = "${local.kubernetes_version}" + + 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}" + } + + horizontal_pod_autoscaling { + disabled = "${var.horizontal_pod_autoscaling ? 0 : 1}" + } + + kubernetes_dashboard { + disabled = "${var.kubernetes_dashboard ? 0 : 1}" + } + + network_policy_config { + disabled = "${var.network_policy ? 0 : 1}" + } + } + + ip_allocation_policy { + cluster_secondary_range_name = "${var.ip_range_pods}" + services_secondary_range_name = "${var.ip_range_services}" + } + + maintenance_policy { + daily_maintenance_window { + start_time = "${var.maintenance_start_time}" + } + } + + lifecycle { + ignore_changes = ["node_pool"] + } + + timeouts { + create = "30m" + update = "30m" + delete = "30m" + } + + node_pool { + name = "default-pool" + + node_config { + service_account = "${lookup(var.node_pools[0], "service_account", var.service_account)}" + } + } +} + +/****************************************** + Create zonal node pools + *****************************************/ +resource "google_container_node_pool" "zonal_pools_private" { + provider = "google-beta" + count = "${(local.cluster_deployment_type == "zonal_private") ? length(var.node_pools) : 0}" + name = "${lookup(var.node_pools[count.index], "name")}" + project = "${var.project_id}" + zone = "${var.zones[0]}" + cluster = "${var.name}" + version = "${lookup(var.node_pools[count.index], "auto_upgrade", false) ? "" : lookup(var.node_pools[count.index], "version", local.node_version)}" + initial_node_count = "${lookup(var.node_pools[count.index], "min_count", 1)}" + + autoscaling { + min_node_count = "${lookup(var.node_pools[count.index], "min_count", 1)}" + max_node_count = "${lookup(var.node_pools[count.index], "max_count", 100)}" + } + + management { + auto_repair = "${lookup(var.node_pools[count.index], "auto_repair", true)}" + auto_upgrade = "${lookup(var.node_pools[count.index], "auto_upgrade", false)}" + } + + node_config { + image_type = "${lookup(var.node_pools[count.index], "image_type", "COS")}" + machine_type = "${lookup(var.node_pools[count.index], "machine_type", "n1-standard-2")}" + labels = "${merge(map("cluster_name", var.name), map("node_pool", lookup(var.node_pools[count.index], "name")), var.node_pools_labels["all"], var.node_pools_labels[lookup(var.node_pools[count.index], "name")])}" + taint = "${concat(var.node_pools_taints["all"], var.node_pools_taints[lookup(var.node_pools[count.index], "name")])}" + tags = "${concat(list("gke-${var.name}"), list("gke-${var.name}-${lookup(var.node_pools[count.index], "name")}"), var.node_pools_tags["all"], var.node_pools_tags[lookup(var.node_pools[count.index], "name")])}" + + disk_size_gb = "${lookup(var.node_pools[count.index], "disk_size_gb", 100)}" + disk_type = "${lookup(var.node_pools[count.index], "disk_type", "pd-standard")}" + service_account = "${lookup(var.node_pools[count.index], "service_account", var.service_account)}" + preemptible = "${lookup(var.node_pools[count.index], "preemptible", false)}" + + oauth_scopes = [ + "https://www.googleapis.com/auth/cloud-platform", + ] + } + + lifecycle { + ignore_changes = ["initial_node_count"] + } + + timeouts { + create = "30m" + update = "30m" + delete = "30m" + } + + depends_on = ["google_container_cluster.zonal_primary_private"] +} + +resource "null_resource" "wait_for_private_zonal_cluster" { + count = "${(local.cluster_deployment_type == "zonal_private") ? 1 : 0}" + + provisioner "local-exec" { + command = "${path.module}/scripts/wait-for-cluster.sh ${var.project_id} ${var.name}" + } + + provisioner "local-exec" { + when = "destroy" + command = "${path.module}/scripts/wait-for-cluster.sh ${var.project_id} ${var.name}" + } + + depends_on = ["google_container_cluster.zonal_primary_private", "google_container_node_pool.zonal_pools_private"] +} diff --git a/examples/simple_regional_private/README.md b/examples/simple_regional_private/README.md new file mode 100644 index 0000000000..2bee35a4df --- /dev/null +++ b/examples/simple_regional_private/README.md @@ -0,0 +1,13 @@ +# Simple Regional Cluster + +This example illustrates how to create a simple private cluster. + +[^]: (autogen_docs_start) + +[^]: (autogen_docs_end) + +To provision this example, run the following from within this directory: +- `terraform init` to get the plugins +- `terraform plan` to see the infrastructure plan +- `terraform apply` to apply the infrastructure build +- `terraform destroy` to destroy the built infrastructure diff --git a/examples/simple_regional_private/main.tf b/examples/simple_regional_private/main.tf new file mode 100644 index 0000000000..08cf1c381d --- /dev/null +++ b/examples/simple_regional_private/main.tf @@ -0,0 +1,61 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + cluster_type = "simple-regional-private" +} + +provider "google-beta" { + credentials = "${file(var.credentials_path)}" + region = "${var.region}" +} + +data "google_compute_subnetwork" "subnetwork" { + provider = "google-beta" + name = "${var.subnetwork}" + project = "${var.project_id}" + region = "${var.region}" +} + +module "gke" { + source = "../../" + project_id = "${var.project_id}" + name = "${local.cluster_type}-cluster" + regional = true + region = "${var.region}" + network = "${var.network}" + subnetwork = "${var.subnetwork}" + ip_range_pods = "${var.ip_range_pods}" + ip_range_services = "${var.ip_range_services}" + kubernetes_version = "1.11.5-gke.4" + node_version = "1.11.5-gke.4" + service_account = "${var.compute_engine_service_account}" + private = true + private_enable_private_endpoint = true + private_enable_private_nodes = true + private_master_ipv4_cidr_block = "172.16.0.0/28" + + master_authorized_networks_config = [{ + cidr_blocks = [{ + cidr_block = "${data.google_compute_subnetwork.subnetwork.ip_cidr_range}" + display_name = "VPC" + }] + }] +} + +data "google_client_config" "default" { + provider = "google-beta" +} diff --git a/examples/simple_regional_private/outputs.tf b/examples/simple_regional_private/outputs.tf new file mode 100644 index 0000000000..b48cab862e --- /dev/null +++ b/examples/simple_regional_private/outputs.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +output "kubernetes_endpoint" { + sensitive = true + value = "${module.gke.endpoint}" +} + +output "client_token" { + sensitive = true + value = "${base64encode(data.google_client_config.default.access_token)}" +} + +output "ca_certificate" { + value = "${module.gke.ca_certificate}" +} diff --git a/examples/simple_regional_private/test_outputs.tf b/examples/simple_regional_private/test_outputs.tf new file mode 120000 index 0000000000..17b34213ba --- /dev/null +++ b/examples/simple_regional_private/test_outputs.tf @@ -0,0 +1 @@ +../../test/fixtures/all_examples/test_outputs.tf \ No newline at end of file diff --git a/examples/simple_regional_private/variables.tf b/examples/simple_regional_private/variables.tf new file mode 100644 index 0000000000..a0c006e4f0 --- /dev/null +++ b/examples/simple_regional_private/variables.tf @@ -0,0 +1,47 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "project_id" { + description = "The project ID to host the cluster in" +} + +variable "credentials_path" { + description = "The path to the GCP credentials JSON file" +} + +variable "region" { + description = "The region to host the cluster in" +} + +variable "network" { + description = "The VPC network to host the cluster in" +} + +variable "subnetwork" { + description = "The subnetwork to host the cluster in" +} + +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/examples/simple_zonal_private/README.md b/examples/simple_zonal_private/README.md new file mode 100644 index 0000000000..7a5a94984a --- /dev/null +++ b/examples/simple_zonal_private/README.md @@ -0,0 +1,13 @@ +# Simple Zonal Cluster + +This example illustrates how to create a simple private cluster. + +[^]: (autogen_docs_start) + +[^]: (autogen_docs_end) + +To provision this example, run the following from within this directory: +- `terraform init` to get the plugins +- `terraform plan` to see the infrastructure plan +- `terraform apply` to apply the infrastructure build +- `terraform destroy` to destroy the built infrastructure diff --git a/examples/simple_zonal_private/main.tf b/examples/simple_zonal_private/main.tf new file mode 100644 index 0000000000..64537618ff --- /dev/null +++ b/examples/simple_zonal_private/main.tf @@ -0,0 +1,62 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + cluster_type = "simple-zonal-private" +} + +provider "google-beta" { + credentials = "${file(var.credentials_path)}" + region = "${var.region}" +} + +data "google_compute_subnetwork" "subnetwork" { + provider = "google-beta" + name = "${var.subnetwork}" + project = "${var.project_id}" + region = "${var.region}" +} + +module "gke" { + source = "../../" + project_id = "${var.project_id}" + name = "${local.cluster_type}-cluster" + regional = false + region = "${var.region}" + zones = "${var.zones}" + network = "${var.network}" + subnetwork = "${var.subnetwork}" + ip_range_pods = "${var.ip_range_pods}" + ip_range_services = "${var.ip_range_services}" + kubernetes_version = "1.11.4-gke.13" + node_version = "1.11.4-gke.13" + service_account = "${var.compute_engine_service_account}" + private = true + private_enable_private_endpoint = true + private_enable_private_nodes = true + private_master_ipv4_cidr_block = "172.16.0.0/28" + + master_authorized_networks_config = [{ + cidr_blocks = [{ + cidr_block = "${data.google_compute_subnetwork.subnetwork.ip_cidr_range}" + display_name = "VPC" + }] + }] +} + +data "google_client_config" "default" { + provider = "google-beta" +} diff --git a/examples/simple_zonal_private/outputs.tf b/examples/simple_zonal_private/outputs.tf new file mode 100644 index 0000000000..b48cab862e --- /dev/null +++ b/examples/simple_zonal_private/outputs.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +output "kubernetes_endpoint" { + sensitive = true + value = "${module.gke.endpoint}" +} + +output "client_token" { + sensitive = true + value = "${base64encode(data.google_client_config.default.access_token)}" +} + +output "ca_certificate" { + value = "${module.gke.ca_certificate}" +} diff --git a/examples/simple_zonal_private/test_outputs.tf b/examples/simple_zonal_private/test_outputs.tf new file mode 120000 index 0000000000..17b34213ba --- /dev/null +++ b/examples/simple_zonal_private/test_outputs.tf @@ -0,0 +1 @@ +../../test/fixtures/all_examples/test_outputs.tf \ No newline at end of file diff --git a/examples/simple_zonal_private/variables.tf b/examples/simple_zonal_private/variables.tf new file mode 100644 index 0000000000..62d3ec4cc3 --- /dev/null +++ b/examples/simple_zonal_private/variables.tf @@ -0,0 +1,52 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "project_id" { + description = "The project ID to host the cluster in" +} + +variable "credentials_path" { + description = "The path to the GCP credentials JSON file" +} + +variable "region" { + description = "The region to host the cluster in" +} + +variable "zones" { + type = "list" + description = "The zone to host the cluster in (required if is a zonal cluster)" +} + +variable "network" { + description = "The VPC network to host the cluster in" +} + +variable "subnetwork" { + description = "The subnetwork to host the cluster in" +} + +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/main.tf b/main.tf index 2a003c87da..6a0bbd9fca 100644 --- a/main.tf +++ b/main.tf @@ -34,113 +34,148 @@ locals { custom_kube_dns_config = "${length(keys(var.stub_domains)) > 0 ? true : false}" network_project_id = "${var.network_project_id != "" ? var.network_project_id : var.project_id}" - cluster_type = "${var.regional ? "regional" : "zonal"}" + cluster_type = "${var.regional ? "regional" : "zonal"}" + cluster_deployment_type = "${var.private ? join("_", list(local.cluster_type, "private")) : local.cluster_type}" cluster_type_output_name = { - regional = "${element(concat(google_container_cluster.primary.*.name, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.name, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.name, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.name, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.name, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.name, list("")), 0)}" } cluster_type_output_location = { - regional = "${element(concat(google_container_cluster.primary.*.region, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.zone, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.region, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.region, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.zone, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.region, list("")), 0)}" } cluster_type_output_region = { - regional = "${element(concat(google_container_cluster.primary.*.region, list("")), 0)}" - zonal = "${var.region}" + regional = "${element(concat(google_container_cluster.primary.*.region, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.region, list("")), 0)}" + zonal = "${var.region}" + zonal_private = "${var.region}" } - cluster_type_output_regional_zones = "${concat(google_container_cluster.primary.*.additional_zones, list(list()))}" - cluster_type_output_zonal_zones = "${concat(google_container_cluster.zonal_primary.*.additional_zones, list(list()))}" + cluster_type_output_regional_zones = "${concat(google_container_cluster.primary.*.additional_zones, list(list()))}" + cluster_type_output_regional_private_zones = "${concat(google_container_cluster.primary_private.*.additional_zones, list(list()))}" + cluster_type_output_zonal_zones = "${concat(google_container_cluster.zonal_primary.*.additional_zones, list(list()))}" + cluster_type_output_zonal_private_zones = "${concat(google_container_cluster.zonal_primary_private.*.additional_zones, list(list()))}" cluster_type_output_zones = { - regional = "${local.cluster_type_output_regional_zones[0]}" - zonal = "${concat(google_container_cluster.zonal_primary.*.zone, local.cluster_type_output_zonal_zones[0])}" + regional = "${local.cluster_type_output_regional_zones[0]}" + regional_private = "${local.cluster_type_output_regional_private_zones[0]}" + zonal = "${concat(google_container_cluster.zonal_primary.*.zone, local.cluster_type_output_zonal_zones[0])}" + zonal_private = "${concat(google_container_cluster.zonal_primary_private.*.zone, local.cluster_type_output_zonal_zones[0])}" } cluster_type_output_endpoint = { - regional = "${element(concat(google_container_cluster.primary.*.endpoint, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.endpoint, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.endpoint, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.endpoint, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.endpoint, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.endpoint, list("")), 0)}" } cluster_type_output_master_auth = { - regional = "${concat(google_container_cluster.primary.*.master_auth, list())}" - zonal = "${concat(google_container_cluster.zonal_primary.*.master_auth, list())}" + regional = "${concat(google_container_cluster.primary.*.master_auth, list())}" + regional_private = "${concat(google_container_cluster.primary_private.*.master_auth, list())}" + zonal = "${concat(google_container_cluster.zonal_primary.*.master_auth, list())}" + zonal_private = "${concat(google_container_cluster.zonal_primary_private.*.master_auth, list())}" } cluster_type_output_master_version = { - regional = "${element(concat(google_container_cluster.primary.*.master_version, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.master_version, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.master_version, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.master_version, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.master_version, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.master_version, list("")), 0)}" } cluster_type_output_min_master_version = { - regional = "${element(concat(google_container_cluster.primary.*.min_master_version, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.min_master_version, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.min_master_version, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.min_master_version, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.min_master_version, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.min_master_version, list("")), 0)}" } cluster_type_output_logging_service = { - regional = "${element(concat(google_container_cluster.primary.*.logging_service, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.logging_service, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.logging_service, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.logging_service, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.logging_service, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.logging_service, list("")), 0)}" } cluster_type_output_monitoring_service = { - regional = "${element(concat(google_container_cluster.primary.*.monitoring_service, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.monitoring_service, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.monitoring_service, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.monitoring_service, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.monitoring_service, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.monitoring_service, list("")), 0)}" } cluster_type_output_network_policy_enabled = { - regional = "${element(concat(google_container_cluster.primary.*.addons_config.0.network_policy_config.0.disabled, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.addons_config.0.network_policy_config.0.disabled, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.addons_config.0.network_policy_config.0.disabled, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.addons_config.0.network_policy_config.0.disabled, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.addons_config.0.network_policy_config.0.disabled, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.addons_config.0.network_policy_config.0.disabled, list("")), 0)}" } cluster_type_output_http_load_balancing_enabled = { - regional = "${element(concat(google_container_cluster.primary.*.addons_config.0.http_load_balancing.0.disabled, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.addons_config.0.http_load_balancing.0.disabled, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.addons_config.0.http_load_balancing.0.disabled, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.addons_config.0.http_load_balancing.0.disabled, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.addons_config.0.http_load_balancing.0.disabled, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.addons_config.0.http_load_balancing.0.disabled, list("")), 0)}" } cluster_type_output_horizontal_pod_autoscaling_enabled = { - regional = "${element(concat(google_container_cluster.primary.*.addons_config.0.horizontal_pod_autoscaling.0.disabled, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.addons_config.0.horizontal_pod_autoscaling.0.disabled, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.addons_config.0.horizontal_pod_autoscaling.0.disabled, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.addons_config.0.horizontal_pod_autoscaling.0.disabled, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.addons_config.0.horizontal_pod_autoscaling.0.disabled, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.addons_config.0.horizontal_pod_autoscaling.0.disabled, list("")), 0)}" } cluster_type_output_kubernetes_dashboard_enabled = { - regional = "${element(concat(google_container_cluster.primary.*.addons_config.0.kubernetes_dashboard.0.disabled, list("")), 0)}" - zonal = "${element(concat(google_container_cluster.zonal_primary.*.addons_config.0.kubernetes_dashboard.0.disabled, list("")), 0)}" + regional = "${element(concat(google_container_cluster.primary.*.addons_config.0.kubernetes_dashboard.0.disabled, list("")), 0)}" + regional_private = "${element(concat(google_container_cluster.primary_private.*.addons_config.0.kubernetes_dashboard.0.disabled, list("")), 0)}" + zonal = "${element(concat(google_container_cluster.zonal_primary.*.addons_config.0.kubernetes_dashboard.0.disabled, list("")), 0)}" + zonal_private = "${element(concat(google_container_cluster.zonal_primary_private.*.addons_config.0.kubernetes_dashboard.0.disabled, list("")), 0)}" } cluster_type_output_node_pools_names = { - regional = "${concat(google_container_node_pool.pools.*.name, list(""))}" - zonal = "${concat(google_container_node_pool.zonal_pools.*.name, list(""))}" + regional = "${concat(google_container_node_pool.pools.*.name, list(""))}" + regional_private = "${concat(google_container_node_pool.pools_private.*.name, list(""))}" + zonal = "${concat(google_container_node_pool.zonal_pools.*.name, list(""))}" + zonal_private = "${concat(google_container_node_pool.zonal_pools_private.*.name, list(""))}" } cluster_type_output_node_pools_versions = { - regional = "${concat(google_container_node_pool.pools.*.version, list(""))}" - zonal = "${concat(google_container_node_pool.zonal_pools.*.version, list(""))}" + regional = "${concat(google_container_node_pool.pools.*.version, list(""))}" + regional_private = "${concat(google_container_node_pool.pools_private.*.version, list(""))}" + zonal = "${concat(google_container_node_pool.zonal_pools.*.version, list(""))}" + zonal_private = "${concat(google_container_node_pool.zonal_pools_private.*.version, list(""))}" } - cluster_master_auth_list_layer1 = "${local.cluster_type_output_master_auth[local.cluster_type]}" + cluster_master_auth_list_layer1 = "${local.cluster_type_output_master_auth[local.cluster_deployment_type]}" cluster_master_auth_list_layer2 = "${local.cluster_master_auth_list_layer1[0]}" cluster_master_auth_map = "${local.cluster_master_auth_list_layer2[0]}" # cluster locals - cluster_name = "${local.cluster_type_output_name[local.cluster_type]}" - cluster_location = "${local.cluster_type_output_location[local.cluster_type]}" - cluster_region = "${local.cluster_type_output_region[local.cluster_type]}" - cluster_zones = "${sort(local.cluster_type_output_zones[local.cluster_type])}" - cluster_endpoint = "${local.cluster_type_output_endpoint[local.cluster_type]}" + cluster_name = "${local.cluster_type_output_name[local.cluster_deployment_type]}" + cluster_location = "${local.cluster_type_output_location[local.cluster_deployment_type]}" + cluster_region = "${local.cluster_type_output_region[local.cluster_deployment_type]}" + cluster_zones = "${sort(local.cluster_type_output_zones[local.cluster_deployment_type])}" + cluster_endpoint = "${local.cluster_type_output_endpoint[local.cluster_deployment_type]}" cluster_ca_certificate = "${lookup(local.cluster_master_auth_map, "cluster_ca_certificate")}" - cluster_master_version = "${local.cluster_type_output_master_version[local.cluster_type]}" - cluster_min_master_version = "${local.cluster_type_output_min_master_version[local.cluster_type]}" - cluster_logging_service = "${local.cluster_type_output_logging_service[local.cluster_type]}" - cluster_monitoring_service = "${local.cluster_type_output_monitoring_service[local.cluster_type]}" - cluster_node_pools_names = "${local.cluster_type_output_node_pools_names[local.cluster_type]}" - cluster_node_pools_versions = "${local.cluster_type_output_node_pools_versions[local.cluster_type]}" - - cluster_network_policy_enabled = "${local.cluster_type_output_network_policy_enabled[local.cluster_type] ? false : true}" - cluster_http_load_balancing_enabled = "${local.cluster_type_output_http_load_balancing_enabled[local.cluster_type] ? false : true}" - cluster_horizontal_pod_autoscaling_enabled = "${local.cluster_type_output_horizontal_pod_autoscaling_enabled[local.cluster_type] ? false : true}" - cluster_kubernetes_dashboard_enabled = "${local.cluster_type_output_kubernetes_dashboard_enabled[local.cluster_type] ? false : true}" + cluster_master_version = "${local.cluster_type_output_master_version[local.cluster_deployment_type]}" + cluster_min_master_version = "${local.cluster_type_output_min_master_version[local.cluster_deployment_type]}" + cluster_logging_service = "${local.cluster_type_output_logging_service[local.cluster_deployment_type]}" + cluster_monitoring_service = "${local.cluster_type_output_monitoring_service[local.cluster_deployment_type]}" + cluster_node_pools_names = "${local.cluster_type_output_node_pools_names[local.cluster_deployment_type]}" + cluster_node_pools_versions = "${local.cluster_type_output_node_pools_versions[local.cluster_deployment_type]}" + + cluster_network_policy_enabled = "${local.cluster_type_output_network_policy_enabled[local.cluster_deployment_type] ? false : true}" + cluster_http_load_balancing_enabled = "${local.cluster_type_output_http_load_balancing_enabled[local.cluster_deployment_type] ? false : true}" + cluster_horizontal_pod_autoscaling_enabled = "${local.cluster_type_output_horizontal_pod_autoscaling_enabled[local.cluster_deployment_type] ? false : true}" + cluster_kubernetes_dashboard_enabled = "${local.cluster_type_output_kubernetes_dashboard_enabled[local.cluster_deployment_type] ? false : true}" } /****************************************** diff --git a/test/fixtures/simple_regional_private/example.tf b/test/fixtures/simple_regional_private/example.tf new file mode 100644 index 0000000000..44f8c0fa0a --- /dev/null +++ b/test/fixtures/simple_regional_private/example.tf @@ -0,0 +1,28 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module "example" { + source = "../../../examples/simple_regional_private" + + project_id = "${var.project_id}" + credentials_path = "${local.credentials_path}" + region = "${var.region}" + 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}" + compute_engine_service_account = "${var.compute_engine_service_account}" +} diff --git a/test/fixtures/simple_regional_private/network.tf b/test/fixtures/simple_regional_private/network.tf new file mode 100644 index 0000000000..9a5fb1b3d0 --- /dev/null +++ b/test/fixtures/simple_regional_private/network.tf @@ -0,0 +1,54 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + credentials_path = "${path.module}/${var.credentials_path_relative}" +} + +resource "random_string" "suffix" { + length = 4 + special = false + upper = false +} + +provider "google-beta" { + credentials = "${file(local.credentials_path)}" + project = "${var.project_id}" +} + +resource "google_compute_network" "main" { + provider = "google-beta" + name = "cft-gke-test-${random_string.suffix.result}" + auto_create_subnetworks = "false" +} + +resource "google_compute_subnetwork" "main" { + provider = "google-beta" + name = "cft-gke-test-${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/test/fixtures/simple_regional_private/outputs.tf b/test/fixtures/simple_regional_private/outputs.tf new file mode 120000 index 0000000000..726bdc722f --- /dev/null +++ b/test/fixtures/simple_regional_private/outputs.tf @@ -0,0 +1 @@ +../shared/outputs.tf \ No newline at end of file diff --git a/test/fixtures/simple_regional_private/terraform.tfvars b/test/fixtures/simple_regional_private/terraform.tfvars new file mode 120000 index 0000000000..08ac6f4724 --- /dev/null +++ b/test/fixtures/simple_regional_private/terraform.tfvars @@ -0,0 +1 @@ +../shared/terraform.tfvars \ No newline at end of file diff --git a/test/fixtures/simple_regional_private/variables.tf b/test/fixtures/simple_regional_private/variables.tf new file mode 120000 index 0000000000..c113c00a3d --- /dev/null +++ b/test/fixtures/simple_regional_private/variables.tf @@ -0,0 +1 @@ +../shared/variables.tf \ No newline at end of file diff --git a/test/fixtures/simple_zonal_private/example.tf b/test/fixtures/simple_zonal_private/example.tf new file mode 100644 index 0000000000..80a9854b9a --- /dev/null +++ b/test/fixtures/simple_zonal_private/example.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module "example" { + source = "../../../examples/simple_zonal_private" + + project_id = "${var.project_id}" + credentials_path = "${local.credentials_path}" + region = "${var.region}" + zones = ["${var.zones}"] + 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}" + compute_engine_service_account = "${var.compute_engine_service_account}" +} diff --git a/test/fixtures/simple_zonal_private/network.tf b/test/fixtures/simple_zonal_private/network.tf new file mode 100644 index 0000000000..9a5fb1b3d0 --- /dev/null +++ b/test/fixtures/simple_zonal_private/network.tf @@ -0,0 +1,54 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + credentials_path = "${path.module}/${var.credentials_path_relative}" +} + +resource "random_string" "suffix" { + length = 4 + special = false + upper = false +} + +provider "google-beta" { + credentials = "${file(local.credentials_path)}" + project = "${var.project_id}" +} + +resource "google_compute_network" "main" { + provider = "google-beta" + name = "cft-gke-test-${random_string.suffix.result}" + auto_create_subnetworks = "false" +} + +resource "google_compute_subnetwork" "main" { + provider = "google-beta" + name = "cft-gke-test-${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/test/fixtures/simple_zonal_private/outputs.tf b/test/fixtures/simple_zonal_private/outputs.tf new file mode 120000 index 0000000000..726bdc722f --- /dev/null +++ b/test/fixtures/simple_zonal_private/outputs.tf @@ -0,0 +1 @@ +../shared/outputs.tf \ No newline at end of file diff --git a/test/fixtures/simple_zonal_private/terraform.tfvars b/test/fixtures/simple_zonal_private/terraform.tfvars new file mode 120000 index 0000000000..08ac6f4724 --- /dev/null +++ b/test/fixtures/simple_zonal_private/terraform.tfvars @@ -0,0 +1 @@ +../shared/terraform.tfvars \ No newline at end of file diff --git a/test/fixtures/simple_zonal_private/variables.tf b/test/fixtures/simple_zonal_private/variables.tf new file mode 120000 index 0000000000..c113c00a3d --- /dev/null +++ b/test/fixtures/simple_zonal_private/variables.tf @@ -0,0 +1 @@ +../shared/variables.tf \ No newline at end of file diff --git a/test/integration/simple_regional_private/controls/gcloud.rb b/test/integration/simple_regional_private/controls/gcloud.rb new file mode 100644 index 0000000000..64a4f77a08 --- /dev/null +++ b/test/integration/simple_regional_private/controls/gcloud.rb @@ -0,0 +1,190 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +project_id = attribute('project_id') +location = attribute('location') +cluster_name = attribute('cluster_name') + +credentials_path = attribute('credentials_path') +ENV['CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE'] = credentials_path + +control "gcloud" do + title "Google Compute Engine GKE configuration" + describe command("gcloud --project=#{project_id} container clusters --zone=#{location} describe #{cluster_name} --format=json") do + its(:exit_status) { should eq 0 } + its(:stderr) { should eq '' } + + let!(:data) do + if subject.exit_status == 0 + JSON.parse(subject.stdout) + else + {} + end + end + + describe "cluster" do + it "is running" do + expect(data['status']).to eq 'RUNNING' + end + + it "is regional" do + expect(data['location']).to match(/^.*[1-9]$/) + end + + it "is private" do + expect(data['privateClusterConfig']['enablePrivateEndpoint']).to eq true + expect(data['privateClusterConfig']['enablePrivateNodes']).to eq true + end + + it "has the expected initial cluster version" do + expect(data['initialClusterVersion']).to eq "1.11.5-gke.4" + end + + it "has the expected addon settings" do + expect(data['addonsConfig']).to eq({ + "horizontalPodAutoscaling" => { + "disabled" => true, + }, + "httpLoadBalancing" => {}, + "kubernetesDashboard" => { + "disabled" => true, + }, + "networkPolicyConfig" => { + "disabled" => true, + }, + }) + end + end + + describe "default node pool" do + let(:default_node_pool) { data['nodePools'].select { |p| p['name'] == "default-pool" }.first } + + it "exists" do + expect(data['nodePools']).to include( + including( + "name" => "default-pool", + ) + ) + end + end + + describe "node pool" do + let(:node_pools) { data['nodePools'].reject { |p| p['name'] == "default-pool" } } + + it "is running the expected version of Kubernetes" do + expect(node_pools).to include( + including( + "version" => "1.11.5-gke.4", + ) + ) + end + + it "has autoscaling enabled" do + expect(node_pools).to include( + including( + "autoscaling" => including( + "enabled" => true, + ), + ) + ) + end + + it "has the expected minimum node count" do + expect(node_pools).to include( + including( + "autoscaling" => including( + "minNodeCount" => 1, + ), + ) + ) + end + + it "has the expected maximum node count" do + expect(node_pools).to include( + including( + "autoscaling" => including( + "maxNodeCount" => 100, + ), + ) + ) + end + + it "is the expected machine type" do + expect(node_pools).to include( + including( + "config" => including( + "machineType" => "n1-standard-2", + ), + ) + ) + end + + it "has the expected disk size" do + expect(node_pools).to include( + including( + "config" => including( + "diskSizeGb" => 100, + ), + ) + ) + end + + it "has the expected labels" do + expect(node_pools).to include( + including( + "config" => including( + "labels" => including( + "cluster_name" => cluster_name, + "node_pool" => "default-node-pool", + ), + ), + ) + ) + end + + it "has the expected network tags" do + expect(node_pools).to include( + including( + "config" => including( + "tags" => match_array([ + "gke-#{cluster_name}", + "gke-#{cluster_name}-default-node-pool", + ]), + ), + ) + ) + end + + it "has autorepair enabled" do + expect(node_pools).to include( + including( + "management" => including( + "autoRepair" => true, + ), + ) + ) + end + + it "has autoupgrade enabled" do + expect(node_pools).to include( + including( + "management" => including( + "autoUpgrade" => true, + ), + ) + ) + end + end + end +end diff --git a/test/integration/simple_regional_private/inspec.yml b/test/integration/simple_regional_private/inspec.yml new file mode 100644 index 0000000000..7ee916787d --- /dev/null +++ b/test/integration/simple_regional_private/inspec.yml @@ -0,0 +1,20 @@ +name: simple_regional_private +attributes: + - name: project_id + required: true + type: string + - name: credentials_path + required: true + type: string + - name: location + required: true + type: string + - name: cluster_name + required: true + type: string + - name: kubernetes_endpoint + required: true + type: string + - name: client_token + required: true + type: string diff --git a/test/integration/simple_zonal_private/controls/gcloud.rb b/test/integration/simple_zonal_private/controls/gcloud.rb new file mode 100644 index 0000000000..5d6ad51723 --- /dev/null +++ b/test/integration/simple_zonal_private/controls/gcloud.rb @@ -0,0 +1,180 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +project_id = attribute('project_id') +location = attribute('location') +cluster_name = attribute('cluster_name') + +credentials_path = attribute('credentials_path') +ENV['CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE'] = credentials_path + +control "gcloud" do + title "Google Compute Engine GKE configuration" + describe command("gcloud --project=#{project_id} container clusters --zone=#{location} describe #{cluster_name} --format=json") do + its(:exit_status) { should eq 0 } + its(:stderr) { should eq '' } + + let!(:data) do + if subject.exit_status == 0 + JSON.parse(subject.stdout) + else + {} + end + end + + describe "cluster" do + it "is running" do + expect(data['status']).to eq 'RUNNING' + end + + it "is zonal" do + expect(data['location']).to match(/^(.*)[1-9]-[a-z]$/) + end + + it "is private" do + expect(data['privateClusterConfig']['enablePrivateEndpoint']).to eq true + expect(data['privateClusterConfig']['enablePrivateNodes']).to eq true + end + + it "has the expected initial cluster version" do + expect(data['initialClusterVersion']).to eq "1.11.4-gke.13" + end + + it "has the expected addon settings" do + expect(data['addonsConfig']).to eq({ + "horizontalPodAutoscaling" => { + "disabled" => true, + }, + "httpLoadBalancing" => {}, + "kubernetesDashboard" => { + "disabled" => true, + }, + "networkPolicyConfig" => { + "disabled" => true, + }, + }) + end + end + + describe "default node pool" do + let(:default_node_pool) { data['nodePools'].select { |p| p['name'] == "default-pool" }.first } + + it "has no initial node count" do + expect(default_node_pool['initialNodeCount']).to eq nil + end + + it "does not have autoscaling enabled" do + expect(default_node_pool['autoscaling']).to eq nil + end + end + + describe "node pool" do + let(:node_pools) { data['nodePools'].reject { |p| p['name'] == "default-pool" } } + + it "is running the expected version of Kubernetes" do + expect(node_pools).to include( + including( + "version" => "1.11.4-gke.13", + ) + ) + end + + it "has autoscaling enabled" do + expect(node_pools).to include( + including( + "autoscaling" => including( + "enabled" => true, + ), + ) + ) + end + + it "has the expected minimum node count" do + expect(node_pools).to include( + including( + "autoscaling" => including( + "minNodeCount" => 1, + ), + ) + ) + end + + it "has the expected maximum node count" do + expect(node_pools).to include( + including( + "autoscaling" => including( + "maxNodeCount" => 100, + ), + ) + ) + end + + it "is the expected machine type" do + expect(node_pools).to include( + including( + "config" => including( + "machineType" => "n1-standard-2", + ), + ) + ) + end + + it "has the expected disk size" do + expect(node_pools).to include( + including( + "config" => including( + "diskSizeGb" => 100, + ), + ) + ) + end + + it "has the expected labels" do + expect(node_pools).to include( + including( + "config" => including( + "labels" => including( + "cluster_name" => cluster_name, + "node_pool" => "default-node-pool", + ), + ), + ) + ) + end + + it "has the expected network tags" do + expect(node_pools).to include( + including( + "config" => including( + "tags" => match_array([ + "gke-#{cluster_name}", + "gke-#{cluster_name}-default-node-pool", + ]), + ), + ) + ) + end + + it "has autorepair enabled" do + expect(node_pools).to include( + including( + "management" => including( + "autoRepair" => true, + ), + ) + ) + end + end + end +end diff --git a/test/integration/simple_zonal_private/inspec.yml b/test/integration/simple_zonal_private/inspec.yml new file mode 100644 index 0000000000..0dc67ab93a --- /dev/null +++ b/test/integration/simple_zonal_private/inspec.yml @@ -0,0 +1,23 @@ +name: simple_zonal_private +attributes: + - name: project_id + required: true + type: string + - name: credentials_path + required: true + type: string + - name: location + required: true + type: string + - name: cluster_name + required: true + type: string + - name: master_kubernetes_version + required: true + type: string + - name: kubernetes_endpoint + required: true + type: string + - name: client_token + required: true + type: string diff --git a/variables.tf b/variables.tf index c0d6a0a977..9dd54ff5d8 100644 --- a/variables.tf +++ b/variables.tf @@ -194,3 +194,23 @@ 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 "private" { + description = "(Beta) Provision as a private cluster" + default = false +} + +variable "private_enable_private_endpoint" { + description = "(Beta) Whether the master's internal IP address is used as the cluster endpoint" + default = false +} + +variable "private_enable_private_nodes" { + description = "(Beta) Whether nodes have internal IP addresses only" + default = false +} + +variable "private_master_ipv4_cidr_block" { + description = "(Beta) The IP range in CIDR notation to use for the hosted master network" + default = "10.0.0.0/28" +}