Add support for internal service account to GKE nodepool module (#156)

* add support for internal service account to GKE nodepool module, fixes #62

* update shared vpc example to use internally managed service account

* update shared vpc example to use internally managed service account

* update hub and spoke peering example to use renamed gke nodepool variables
This commit is contained in:
Ludovico Magnocavallo
2020-11-07 10:48:12 +01:00
committed by GitHub
parent c31764fa7e
commit b3ae7c9454
13 changed files with 284 additions and 82 deletions

View File

@@ -4,6 +4,10 @@ This module allows simplified creation and management of individual GKE nodepool
## Example usage
### Module defaults
If no specific node configuration is set via variables, the module uses the provider's defaults only setting OAuth scopes to a minimal working set (devstorage read-only, logging and monitoring write) and the node machine type to `n1-standard-1`. The service account set by the provider in this case is the GCE default service account.
```hcl
module "cluster-1-nodepool-1" {
source = "../modules/gke-nodepool"
@@ -14,6 +18,21 @@ module "cluster-1-nodepool-1" {
}
```
### Internally managed service account
To have the module auto-create a service account for the nodes, set the `node_service_account_create` variable to `true`. When a service account is created by the module, OAuth scopes are set to `cloud-platform` by default. The service account resource and email (in both plain and IAM formats) are then available in outputs to assign IAM roles from your own code.
```hcl
module "cluster-1-nodepool-1" {
source = "../modules/gke-nodepool"
project_id = "myproject"
cluster_name = "cluster-1"
location = "europe-west1-b"
name = "nodepool-1"
node_service_account_create = true
}
```
<!-- BEGIN TFDOC -->
## Variables
@@ -28,23 +47,24 @@ module "cluster-1-nodepool-1" {
| *management_config* | Optional node management configuration. | <code title="object&#40;&#123;&#10;auto_repair &#61; bool&#10;auto_upgrade &#61; bool&#10;&#125;&#41;">object({...})</code> | | <code title="">null</code> |
| *max_pods_per_node* | Maximum number of pods per node. | <code title="">number</code> | | <code title="">null</code> |
| *name* | Optional nodepool name. | <code title="">string</code> | | <code title="">null</code> |
| *node_config_disk_size* | Node disk size, defaults to 100GB. | <code title="">number</code> | | <code title="">100</code> |
| *node_config_disk_type* | Node disk type, defaults to pd-standard. | <code title="">string</code> | | <code title="">pd-standard</code> |
| *node_config_guest_accelerator* | Map of type and count of attached accelerator cards. | <code title="map&#40;number&#41;">map(number)</code> | | <code title="">{}</code> |
| *node_config_image_type* | Nodes image type. | <code title="">string</code> | | <code title="">null</code> |
| *node_config_labels* | Kubernetes labels attached to nodes. | <code title="map&#40;string&#41;">map(string)</code> | | <code title="">{}</code> |
| *node_config_local_ssd_count* | Number of local SSDs attached to nodes. | <code title="">number</code> | | <code title="">0</code> |
| *node_config_machine_type* | Nodes machine type. | <code title="">string</code> | | <code title="">n1-standard-1</code> |
| *node_config_metadata* | Metadata key/value pairs assigned to nodes. Set disable-legacy-endpoints to true when using this variable. | <code title="map&#40;string&#41;">map(string)</code> | | <code title="">null</code> |
| *node_config_min_cpu_platform* | Minimum CPU platform for nodes. | <code title="">string</code> | | <code title="">null</code> |
| *node_config_oauth_scopes* | Set of Google API scopes for the nodes service account. Include logging-write, monitoring, and storage-ro when using this variable. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">["logging-write", "monitoring", "monitoring-write", "storage-ro"]</code> |
| *node_config_preemptible* | Use preemptible VMs for nodes. | <code title="">bool</code> | | <code title="">null</code> |
| *node_config_sandbox_config* | GKE Sandbox configuration. Needs image_type set to COS_CONTAINERD and node_version set to 1.12.7-gke.17 when using this variable. | <code title="">string</code> | | <code title="">null</code> |
| *node_config_service_account* | Service account used for nodes. | <code title="">string</code> | | <code title="">null</code> |
| *node_config_shielded_instance_config* | Shielded instance options. | <code title="object&#40;&#123;&#10;enable_secure_boot &#61; bool&#10;enable_integrity_monitoring &#61; bool&#10;&#125;&#41;">object({...})</code> | | <code title="">null</code> |
| *node_config_tags* | Network tags applied to nodes. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">null</code> |
| *node_count* | Number of nodes per instance group, can be updated after creation. Ignored when autoscaling is set. | <code title="">number</code> | | <code title="">null</code> |
| *node_disk_size* | Node disk size, defaults to 100GB. | <code title="">number</code> | | <code title="">100</code> |
| *node_disk_type* | Node disk type, defaults to pd-standard. | <code title="">string</code> | | <code title="">pd-standard</code> |
| *node_guest_accelerator* | Map of type and count of attached accelerator cards. | <code title="map&#40;number&#41;">map(number)</code> | | <code title="">{}</code> |
| *node_image_type* | Nodes image type. | <code title="">string</code> | | <code title="">null</code> |
| *node_labels* | Kubernetes labels attached to nodes. | <code title="map&#40;string&#41;">map(string)</code> | | <code title="">{}</code> |
| *node_local_ssd_count* | Number of local SSDs attached to nodes. | <code title="">number</code> | | <code title="">0</code> |
| *node_locations* | Optional list of zones in which nodes should be located. Uses cluster locations if unset. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">null</code> |
| *node_machine_type* | Nodes machine type. | <code title="">string</code> | | <code title="">n1-standard-1</code> |
| *node_metadata* | Metadata key/value pairs assigned to nodes. Set disable-legacy-endpoints to true when using this variable. | <code title="map&#40;string&#41;">map(string)</code> | | <code title="">null</code> |
| *node_min_cpu_platform* | Minimum CPU platform for nodes. | <code title="">string</code> | | <code title="">null</code> |
| *node_preemptible* | Use preemptible VMs for nodes. | <code title="">bool</code> | | <code title="">null</code> |
| *node_sandbox_config* | GKE Sandbox configuration. Needs image_type set to COS_CONTAINERD and node_version set to 1.12.7-gke.17 when using this variable. | <code title="">string</code> | | <code title="">null</code> |
| *node_service_account* | Service account email. Unused if service account is auto-created. | <code title="">string</code> | | <code title="">null</code> |
| *node_service_account_create* | Auto-create service account. | <code title="">bool</code> | | <code title="">false</code> |
| *node_service_account_scopes* | Scopes applied to service account. Default to: 'cloud-platform' when creating a service account; 'devstorage.read_only', 'logging.write', 'monitoring.write' otherwise. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">[]</code> |
| *node_shielded_instance_config* | Shielded instance options. | <code title="object&#40;&#123;&#10;enable_secure_boot &#61; bool&#10;enable_integrity_monitoring &#61; bool&#10;&#125;&#41;">object({...})</code> | | <code title="">null</code> |
| *node_tags* | Network tags applied to nodes. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">null</code> |
| *upgrade_config* | Optional node upgrade configuration. | <code title="object&#40;&#123;&#10;max_surge &#61; number&#10;max_unavailable &#61; number&#10;&#125;&#41;">object({...})</code> | | <code title="">null</code> |
| *workload_metadata_config* | Metadata configuration to expose to workloads on the node pool. | <code title="">string</code> | | <code title="">GKE_METADATA_SERVER</code> |
@@ -53,4 +73,7 @@ module "cluster-1-nodepool-1" {
| name | description | sensitive |
|---|---|:---:|
| name | Nodepool name. | |
| service_account | Service account resource. | |
| service_account_email | Service account email. | |
| service_account_iam_email | Service account email. | |
<!-- END TFDOC -->

View File

@@ -14,6 +14,38 @@
* limitations under the License.
*/
locals {
service_account_email = (
var.node_service_account_create
? (
length(google_service_account.service_account) > 0
? google_service_account.service_account[0].email
: null
)
: var.node_service_account
)
service_account_scopes = (
length(var.node_service_account_scopes) > 0
? var.node_service_account_scopes
: (
var.node_service_account_create
? ["https://www.googleapis.com/auth/cloud-platform"]
: [
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write"
]
)
)
}
resource "google_service_account" "service_account" {
count = var.node_service_account_create ? 1 : 0
project = var.project_id
account_id = "tf-gke-${var.cluster_name}-${var.name}"
display_name = "Terraform GKE ${var.cluster_name} ${var.name}."
}
resource "google_container_node_pool" "nodepool" {
provider = google-beta
@@ -29,21 +61,21 @@ resource "google_container_node_pool" "nodepool" {
version = var.gke_version
node_config {
disk_size_gb = var.node_config_disk_size
disk_type = var.node_config_disk_type
image_type = var.node_config_image_type
labels = var.node_config_labels
local_ssd_count = var.node_config_local_ssd_count
machine_type = var.node_config_machine_type
metadata = var.node_config_metadata
min_cpu_platform = var.node_config_min_cpu_platform
oauth_scopes = var.node_config_oauth_scopes
preemptible = var.node_config_preemptible
service_account = var.node_config_service_account
tags = var.node_config_tags
disk_size_gb = var.node_disk_size
disk_type = var.node_disk_type
image_type = var.node_image_type
labels = var.node_labels
local_ssd_count = var.node_local_ssd_count
machine_type = var.node_machine_type
metadata = var.node_metadata
min_cpu_platform = var.node_min_cpu_platform
oauth_scopes = local.service_account_scopes
preemptible = var.node_preemptible
service_account = local.service_account_email
tags = var.node_tags
dynamic guest_accelerator {
for_each = var.node_config_guest_accelerator
for_each = var.node_guest_accelerator
iterator = config
content {
type = config.key
@@ -53,8 +85,8 @@ resource "google_container_node_pool" "nodepool" {
dynamic sandbox_config {
for_each = (
var.node_config_sandbox_config != null
? [var.node_config_sandbox_config]
var.node_sandbox_config != null
? [var.node_sandbox_config]
: []
)
iterator = config
@@ -65,8 +97,8 @@ resource "google_container_node_pool" "nodepool" {
dynamic shielded_instance_config {
for_each = (
var.node_config_shielded_instance_config != null
? [var.node_config_shielded_instance_config]
var.node_shielded_instance_config != null
? [var.node_shielded_instance_config]
: []
)
iterator = config

View File

@@ -18,3 +18,25 @@ output "name" {
description = "Nodepool name."
value = google_container_node_pool.nodepool.name
}
output "service_account" {
description = "Service account resource."
value = (
var.node_service_account_create
? google_service_account.service_account[0]
: null
)
}
output "service_account_email" {
description = "Service account email."
value = local.service_account_email
}
output "service_account_iam_email" {
description = "Service account email."
value = join("", [
"serviceAccount:",
local.service_account_email == null ? "" : local.service_account_email
])
}

View File

@@ -66,85 +66,93 @@ variable "name" {
default = null
}
variable "node_config_disk_size" {
variable "node_disk_size" {
description = "Node disk size, defaults to 100GB."
type = number
default = 100
}
variable "node_config_disk_type" {
variable "node_disk_type" {
description = "Node disk type, defaults to pd-standard."
type = string
default = "pd-standard"
}
variable "node_config_guest_accelerator" {
variable "node_guest_accelerator" {
description = "Map of type and count of attached accelerator cards."
type = map(number)
default = {}
}
variable "node_config_image_type" {
variable "node_image_type" {
description = "Nodes image type."
type = string
default = null
}
variable "node_config_labels" {
variable "node_labels" {
description = "Kubernetes labels attached to nodes."
type = map(string)
default = {}
}
variable "node_config_local_ssd_count" {
variable "node_local_ssd_count" {
description = "Number of local SSDs attached to nodes."
type = number
default = 0
}
variable "node_config_machine_type" {
variable "node_machine_type" {
description = "Nodes machine type."
type = string
default = "n1-standard-1"
}
variable "node_config_metadata" {
variable "node_metadata" {
description = "Metadata key/value pairs assigned to nodes. Set disable-legacy-endpoints to true when using this variable."
type = map(string)
default = null
}
variable "node_config_min_cpu_platform" {
variable "node_min_cpu_platform" {
description = "Minimum CPU platform for nodes."
type = string
default = null
}
variable "node_config_oauth_scopes" {
description = "Set of Google API scopes for the nodes service account. Include logging-write, monitoring, and storage-ro when using this variable."
type = list(string)
default = ["logging-write", "monitoring", "monitoring-write", "storage-ro"]
}
variable "node_config_preemptible" {
variable "node_preemptible" {
description = "Use preemptible VMs for nodes."
type = bool
default = null
}
variable "node_config_sandbox_config" {
variable "node_sandbox_config" {
description = "GKE Sandbox configuration. Needs image_type set to COS_CONTAINERD and node_version set to 1.12.7-gke.17 when using this variable."
type = string
default = null
}
variable "node_config_service_account" {
description = "Service account used for nodes."
variable "node_service_account" {
description = "Service account email. Unused if service account is auto-created."
type = string
default = null
}
variable "node_config_shielded_instance_config" {
variable "node_service_account_create" {
description = "Auto-create service account."
type = bool
default = false
}
# scopes and scope aliases list
# https://cloud.google.com/sdk/gcloud/reference/compute/instances/create#--scopes
variable "node_service_account_scopes" {
description = "Scopes applied to service account. Default to: 'cloud-platform' when creating a service account; 'devstorage.read_only', 'logging.write', 'monitoring.write' otherwise."
type = list(string)
default = []
}
variable "node_shielded_instance_config" {
description = "Shielded instance options."
type = object({
enable_secure_boot = bool
@@ -153,13 +161,13 @@ variable "node_config_shielded_instance_config" {
default = null
}
variable "node_config_tags" {
variable "node_tags" {
description = "Network tags applied to nodes."
type = list(string)
default = null
}
# variable "node_config_taint" {
# variable "node_taint" {
# description = "Kubernetes taints applied to nodes."
# type = string
# default = null