diff --git a/private-vpc-native/CHANGELOG.md b/private-vpc-native/CHANGELOG.md index e69de29..c08fd17 100644 --- a/private-vpc-native/CHANGELOG.md +++ b/private-vpc-native/CHANGELOG.md @@ -0,0 +1,10 @@ + +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## 1.0.0 +### Added +* Ability to configure private clusters \ No newline at end of file diff --git a/private-vpc-native/Makefile b/private-vpc-native/Makefile new file mode 100644 index 0000000..0205a68 --- /dev/null +++ b/private-vpc-native/Makefile @@ -0,0 +1,15 @@ +# This constructs README.md, including Terraform documentation in its middle. +# THIs requires `terraform-docs` to be installed from: https://github.com/segmentio/terraform-docs + +# The sed command below increases the markdown heading level of Terraform docs. +README.md:README.pre_terraform_inputs.md README.post_terraform_inputs.md + @echo Creating ReadMe with Terraform docs. . . + cat README.pre_tf_inputs.md >README.md + echo >>README.md + terraform-docs --with-aggregate-type-defaults md document . |sed 's/^#/##/g' >>README.md + echo >>README.md + cat README.post_tf_inputs.md >>README.md + +README.pre_terraform_inputs.md: +README.post_terraform_inputs.md: + diff --git a/private-vpc-native/README.md b/private-vpc-native/README.md index e69de29..dfcc21e 100644 --- a/private-vpc-native/README.md +++ b/private-vpc-native/README.md @@ -0,0 +1,22 @@ +# Terraform Private VPC Native GKE Cluster Module + +This module manages a private Google Kubernetes Engine (GKE) VPC Native cluster. The subnet CIDRs used for cluster nodes, pods, and services, are specified in the form of existing Google Compute secondary IP ranges. Use a separate Terraform module, such as [this `terraform-gcp-vpc-native/cloud-nat` one](https://github.com/FairwindsOps/terraform-gcp-vpc-native/tree/master/cloud-nat), to create these network resources in advance. + +By default, the cluster will be provisioned with a private kubernetes api and a private node group. These are both configurable inputs. To have a Public API and private node groups, set `enable_private_endpoint` to `false`. + +See the file [example-usage](./example-usage) for an example of how to use this module. Below are the available module inputs: +| Parameter | Description | Default | +|------------------------------------|-----------------------------------------------------|-----------------| +| `region` | GKE region | `None` | +| `name` | Name of the GKE cluster | `None` | +| `project` | GCP Project | `""` | +| `network_name` | Existing google_compute_network | `None` | +| `nodes_subnetwork_name` | Existing google_compute_subnetwork | `None` | +| `kubernetes_version` | minimum version of master nodes | `None` | +| `pods_secondary_ip_range_name` | IP range to be used for pods | `None` | +| `services_secondary_ip_range_name` | IP range to be used for services | `None` | +| `master_authorized_network_cidrs` | List of maps with authorized cidrs and descriptions | `see inputs.tf` | +| `maintenance_policy_start_time` | Maintenance Window (GMT) | `06:00` | +| `enable_private_endpoint` | Private Kube API endpoint | `true` | +| `enable_private_nodes` | Private compute instances | `true` | +| `master_ipv4_cidr_block` | IPV4 CIDR block for controlplane (must be /28) | `None` | diff --git a/private-vpc-native/README.pre_tf_inputs.md b/private-vpc-native/README.pre_tf_inputs.md new file mode 100644 index 0000000..be009a1 --- /dev/null +++ b/private-vpc-native/README.pre_tf_inputs.md @@ -0,0 +1,7 @@ +# Terraform Public VPC Native GKE Cluster Module + +This module manages a private Google Kubernetes Engine (GKE) VPC Native cluster. The subnet CIDRs used for cluster nodes, pods, and services, are specified in the form of existing Google Compute secondary IP ranges. Use a separate Terraform module, such as [this `terraform-gcp-vpc-native` one](https://github.com/FairwindsOps/terraform-gcp-vpc-native), to create these network resources in advance. + +## Using The Terraform Module + +This module requires version 2.0.0 or above of the Google Terraform provider. diff --git a/private-vpc-native/example-usage b/private-vpc-native/example-usage new file mode 100644 index 0000000..ad2d032 --- /dev/null +++ b/private-vpc-native/example-usage @@ -0,0 +1,36 @@ +# These local variables can be used as inputs to both a network and this GKE VPC Native cluster module. +locals { + region = "us-central1" + network_name = "customername-test" + kubernetes_version = "1.13.9-gke.3" + master_ipv4_cidr_block = "10.128.254.0/28" +} + + +# The `module.customername_vpc` below refers to an instance of a VPC module. +# Ref: https://github.com/FairwindsOps/terraform-gcp-vpc-native +module "customername_cluster" { + # Change the ref below to use a vX.Y.Z release instead of master. + source = "git@github.com:/FairwindsOps/terraform-gke//private-vpc-native?ref=master" + + name = "customername-cluster1" + region = "${local.region}" + project = "customername-dev" + kubernetes_version = "${local.kubernetes_version}" + network_name = "${local.network_name}" + nodes_subnetwork_name = "${module.customername_vpc.subnetwork}" + pods_secondary_ip_range_name = "${module.customername_vpc.gke_pods_1}" + services_secondary_ip_range_name = "${module.customername_vpc.gke_services_1}" + # private cluster options + enable_private_endpoint = false + enable_private_nodes = true + master_ipv4_cidr_block = "${local.master_ipv4_cidr_block}" + + master_authorized_network_cidrs = [ + { + # This is the module default, but demonstrates specifying this input. + cidr_block = "0.0.0.0/0" + display_name = "from the Internet" + }, + ] +} diff --git a/private-vpc-native/inputs.tf b/private-vpc-native/inputs.tf new file mode 100644 index 0000000..8cc89b5 --- /dev/null +++ b/private-vpc-native/inputs.tf @@ -0,0 +1,64 @@ +variable "name" { + description = "The name of the GKE cluster" +} + +variable "region" { + description = "The region where the GKE cluster will be created." +} + +variable "project" { + description = "The project where the GKE cluster will be created. Leave unspecified to use the project from the provider." + default = "" +} + +variable "network_name" { + description = "The name of an existing google_compute_network resource to which the cluster will be connected." +} + +variable "nodes_subnetwork_name" { + description = "The name of an existing google_compute_subnetwork resource where cluster compute instances are launched." +} + +variable "kubernetes_version" { + description = "The minimum version of master nodes. This can be changed to upgrade the cluster - remember to upgrade the Kubernetes version for node pools (managed separately)." +} + +variable "pods_secondary_ip_range_name" { + description = "The name of an existing network secondary IP range to be used for pods." +} + +variable "services_secondary_ip_range_name" { + description = "The name of an existing network secondary IP range to be used for services." +} + +variable "master_authorized_network_cidrs" { + type = "list" + description = "A list of up to 20 maps containing `master_authorized_network_cidrs` and `display_name` keys, representing source network CIDRs that are allowed to connect master nodes over HTTPS." + + default = [ + { + ## this needs to be changed when enable_private_endpoint is true + cidr_block = "0.0.0.0/0" + display_name = "everywhere" + }, + ] +} + +variable "maintenance_policy_start_time" { + description = "The time (in GMT) when the cluster maintenance window will start." + default = "06:00" +} + +variable "enable_private_endpoint" { + description = "A boolean to enable private (non public) kube-api endpoints" + default = true +} + +variable "enable_private_nodes" { + description = "A boolean to enable private (non public) nodes" + default = true +} + +variable "master_ipv4_cidr_block" { + description = "The /28 range for the master instances. Must be set if enable_private_nodes or enable_private_endpoint is true" +} diff --git a/private-vpc-native/main.tf b/private-vpc-native/main.tf new file mode 100644 index 0000000..48c79e7 --- /dev/null +++ b/private-vpc-native/main.tf @@ -0,0 +1,66 @@ +resource "google_container_cluster" "cluster" { + name = "${var.name}" + location = "${var.region}" + min_master_version = "${var.kubernetes_version}" + network = "${var.network_name}" + subnetwork = "${var.nodes_subnetwork_name}" + + ip_allocation_policy { + cluster_secondary_range_name = "${var.pods_secondary_ip_range_name}" + services_secondary_range_name = "${var.services_secondary_ip_range_name}" + } + + # This is believed to apply to the default node pool, which gets created then deleted. + initial_node_count = 1 + remove_default_node_pool = true + + # The absence of a user and password here disables basic auth + master_auth { + username = "" + password = "" + + client_certificate_config { + issue_client_certificate = false + } + } + + private_cluster_config { + enable_private_endpoint = "${var.enable_private_endpoint}" + enable_private_nodes = "${var.enable_private_nodes}" + master_ipv4_cidr_block = "${var.master_ipv4_cidr_block}" + } + + # Disable automatic kubernetes dashboard + addons_config { + kubernetes_dashboard { + disabled = true + } + } + + network_policy { + enabled = true + } + + master_authorized_networks_config = { + cidr_blocks = "${var.master_authorized_network_cidrs}" + } + + maintenance_policy { + daily_maintenance_window { + start_time = "${var.maintenance_policy_start_time}" + } + } + + resource_labels { + kubernetescluster = "${var.name}" + } + + lifecycle { + # ignore changes to node_pool specifically so it doesn't + # try to recreate default node pool with every change + # ignore changes to network and subnetwork so it doesn't + # clutter up diff with dumb changes like: + # projects/[name]/regions/us-central1/subnetworks/[name]" => "name" + ignore_changes = ["node_pool", "network", "subnetwork"] + } +} diff --git a/private-vpc-native/outputs.tf b/private-vpc-native/outputs.tf new file mode 100644 index 0000000..f277655 --- /dev/null +++ b/private-vpc-native/outputs.tf @@ -0,0 +1,25 @@ +output "name" { + description = "The static name of the GKE cluster" + value = "${google_container_cluster.cluster.name}" +} + +output "endpoint" { + description = "The GKE Cluster Endpoints IP" + value = "${google_container_cluster.cluster.endpoint}" +} + +## This is passed back out in case it's needed to inherit for node pools +output "kubernetes_version" { + description = "The Kubernetes version used when creating or upgrading this cluster. This does not reflect the current version of master or worker nodes." + value = "${var.kubernetes_version}" +} + +output "master_version" { + description = "The current version of the Kubernetes master nodes, which will differ from the kubernetes_version output if GKE upgrades masters automatically." + value = "${google_container_cluster.cluster.master_version}" +} + +output "region" { + description = "The region in which this cluster exists" + value = "${var.region}" +}