From 116da0f91e9aa280d4671ef6e3c4dee063e91f3f Mon Sep 17 00:00:00 2001 From: Marko Vlahovic Date: Tue, 2 Jul 2019 10:02:51 -0700 Subject: [PATCH 1/4] Restrict node access to cluster metadata service --- autogen/cluster_regional.tf | 11 +++++++++++ autogen/cluster_zonal.tf | 6 ++++++ autogen/variables.tf | 5 +++++ modules/beta-private-cluster/README.md | 1 + modules/beta-private-cluster/cluster_regional.tf | 7 +++++++ modules/beta-private-cluster/cluster_zonal.tf | 4 ++++ modules/beta-private-cluster/variables.tf | 5 +++++ modules/beta-public-cluster/README.md | 1 + modules/beta-public-cluster/cluster_regional.tf | 7 +++++++ modules/beta-public-cluster/cluster_zonal.tf | 4 ++++ modules/beta-public-cluster/variables.tf | 5 +++++ 11 files changed, 56 insertions(+) diff --git a/autogen/cluster_regional.tf b/autogen/cluster_regional.tf index a63b7c8a91..ff3aee7a94 100644 --- a/autogen/cluster_regional.tf +++ b/autogen/cluster_regional.tf @@ -106,6 +106,11 @@ resource "google_container_cluster" "primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" + {% if beta_cluster %} + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } + {% endif %} } } {% if private_cluster %} @@ -168,6 +173,12 @@ resource "google_container_node_pool" "pools" { type = "${lookup(var.node_pools[count.index], "accelerator_type", "")}" count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } + {% if beta_cluster %} + + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } + {% endif %} } lifecycle { diff --git a/autogen/cluster_zonal.tf b/autogen/cluster_zonal.tf index 575f65f011..1740aa1ba4 100644 --- a/autogen/cluster_zonal.tf +++ b/autogen/cluster_zonal.tf @@ -169,6 +169,12 @@ resource "google_container_node_pool" "zonal_pools" { type = "${lookup(var.node_pools[count.index], "accelerator_type", "")}" count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } + {% if beta_cluster %} + + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } + {% endif %} } lifecycle { diff --git a/autogen/variables.tf b/autogen/variables.tf index 45dff454ae..98264daf9e 100644 --- a/autogen/variables.tf +++ b/autogen/variables.tf @@ -300,6 +300,11 @@ variable "pod_security_policy_config" { "enabled" = false }] } + +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "UNSPECIFIED" +} {% endif %} variable "basic_auth_username" { diff --git a/modules/beta-private-cluster/README.md b/modules/beta-private-cluster/README.md index 004db9aca7..0ceca593e4 100644 --- a/modules/beta-private-cluster/README.md +++ b/modules/beta-private-cluster/README.md @@ -154,6 +154,7 @@ In either case, upgrading to module version `v1.0.0` will trigger a recreation o | network\_policy | Enable network policy addon | string | `"false"` | no | | network\_policy\_provider | The network policy provider. | string | `"CALICO"` | no | | network\_project\_id | The project ID of the shared VPC's host (for shared vpc support) | string | `""` | no | +| node\_metadata | Specifies how node metadata is exposed to the workload running on the node | string | `"UNSPECIFIED"` | no | | node\_pools | List of maps containing node pools | list | `` | no | | node\_pools\_labels | Map of maps containing node labels by node-pool name | map | `` | no | | node\_pools\_metadata | Map of maps containing node metadata by node-pool name | map | `` | no | diff --git a/modules/beta-private-cluster/cluster_regional.tf b/modules/beta-private-cluster/cluster_regional.tf index 9e95d2e35b..938bbe1734 100644 --- a/modules/beta-private-cluster/cluster_regional.tf +++ b/modules/beta-private-cluster/cluster_regional.tf @@ -102,6 +102,9 @@ resource "google_container_cluster" "primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } } } @@ -160,6 +163,10 @@ resource "google_container_node_pool" "pools" { type = "${lookup(var.node_pools[count.index], "accelerator_type", "")}" count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } + + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } } lifecycle { diff --git a/modules/beta-private-cluster/cluster_zonal.tf b/modules/beta-private-cluster/cluster_zonal.tf index d867b915b6..c5d615dd58 100644 --- a/modules/beta-private-cluster/cluster_zonal.tf +++ b/modules/beta-private-cluster/cluster_zonal.tf @@ -161,6 +161,10 @@ resource "google_container_node_pool" "zonal_pools" { type = "${lookup(var.node_pools[count.index], "accelerator_type", "")}" count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } + + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } } lifecycle { diff --git a/modules/beta-private-cluster/variables.tf b/modules/beta-private-cluster/variables.tf index 39e694e832..44762bd81c 100644 --- a/modules/beta-private-cluster/variables.tf +++ b/modules/beta-private-cluster/variables.tf @@ -302,6 +302,11 @@ variable "pod_security_policy_config" { }] } +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "UNSPECIFIED" +} + variable "basic_auth_username" { description = "The username to be used with Basic Authentication. An empty value will disable Basic Authentication, which is the recommended configuration." default = "" diff --git a/modules/beta-public-cluster/README.md b/modules/beta-public-cluster/README.md index c898bb2e74..af91bd12f8 100644 --- a/modules/beta-public-cluster/README.md +++ b/modules/beta-public-cluster/README.md @@ -145,6 +145,7 @@ In either case, upgrading to module version `v1.0.0` will trigger a recreation o | network\_policy | Enable network policy addon | string | `"false"` | no | | network\_policy\_provider | The network policy provider. | string | `"CALICO"` | no | | network\_project\_id | The project ID of the shared VPC's host (for shared vpc support) | string | `""` | no | +| node\_metadata | Specifies how node metadata is exposed to the workload running on the node | string | `"UNSPECIFIED"` | no | | node\_pools | List of maps containing node pools | list | `` | no | | node\_pools\_labels | Map of maps containing node labels by node-pool name | map | `` | no | | node\_pools\_metadata | Map of maps containing node metadata by node-pool name | map | `` | no | diff --git a/modules/beta-public-cluster/cluster_regional.tf b/modules/beta-public-cluster/cluster_regional.tf index c745074eff..2676427617 100644 --- a/modules/beta-public-cluster/cluster_regional.tf +++ b/modules/beta-public-cluster/cluster_regional.tf @@ -102,6 +102,9 @@ resource "google_container_cluster" "primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } } } @@ -154,6 +157,10 @@ resource "google_container_node_pool" "pools" { type = "${lookup(var.node_pools[count.index], "accelerator_type", "")}" count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } + + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } } lifecycle { diff --git a/modules/beta-public-cluster/cluster_zonal.tf b/modules/beta-public-cluster/cluster_zonal.tf index d2ed15413c..635afb20c0 100644 --- a/modules/beta-public-cluster/cluster_zonal.tf +++ b/modules/beta-public-cluster/cluster_zonal.tf @@ -155,6 +155,10 @@ resource "google_container_node_pool" "zonal_pools" { type = "${lookup(var.node_pools[count.index], "accelerator_type", "")}" count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } + + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } } lifecycle { diff --git a/modules/beta-public-cluster/variables.tf b/modules/beta-public-cluster/variables.tf index 244fd9c345..fb9c5225fe 100644 --- a/modules/beta-public-cluster/variables.tf +++ b/modules/beta-public-cluster/variables.tf @@ -282,6 +282,11 @@ variable "pod_security_policy_config" { }] } +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "UNSPECIFIED" +} + variable "basic_auth_username" { description = "The username to be used with Basic Authentication. An empty value will disable Basic Authentication, which is the recommended configuration." default = "" From 06820a4ca7a641731572e239760b7e3b8d5558e2 Mon Sep 17 00:00:00 2001 From: Marko Vlahovic Date: Tue, 2 Jul 2019 12:24:20 -0700 Subject: [PATCH 2/4] Adding missing config in zonal default node pool --- autogen/cluster_zonal.tf | 5 +++++ modules/beta-private-cluster/cluster_zonal.tf | 3 +++ modules/beta-public-cluster/cluster_zonal.tf | 3 +++ 3 files changed, 11 insertions(+) diff --git a/autogen/cluster_zonal.tf b/autogen/cluster_zonal.tf index 1740aa1ba4..a551ffebbf 100644 --- a/autogen/cluster_zonal.tf +++ b/autogen/cluster_zonal.tf @@ -107,6 +107,11 @@ resource "google_container_cluster" "zonal_primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" + {% if beta_cluster %} + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } + {% endif %} } } {% if private_cluster %} diff --git a/modules/beta-private-cluster/cluster_zonal.tf b/modules/beta-private-cluster/cluster_zonal.tf index c5d615dd58..7d73fa9ef9 100644 --- a/modules/beta-private-cluster/cluster_zonal.tf +++ b/modules/beta-private-cluster/cluster_zonal.tf @@ -103,6 +103,9 @@ resource "google_container_cluster" "zonal_primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } } } diff --git a/modules/beta-public-cluster/cluster_zonal.tf b/modules/beta-public-cluster/cluster_zonal.tf index 635afb20c0..e25f61e7ed 100644 --- a/modules/beta-public-cluster/cluster_zonal.tf +++ b/modules/beta-public-cluster/cluster_zonal.tf @@ -103,6 +103,9 @@ resource "google_container_cluster" "zonal_primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" + workload_metadata_config { + node_metadata = "${var.node_metadata}" + } } } From d5df31f7571c776efca7adbe7e83dfae69ce45d3 Mon Sep 17 00:00:00 2001 From: Marko Vlahovic Date: Tue, 2 Jul 2019 15:57:02 -0700 Subject: [PATCH 3/4] Adding tests --- .kitchen.yml | 7 +++ examples/workload_metadata_config/README.md | 46 +++++++++++++++ examples/workload_metadata_config/main.tf | 57 ++++++++++++++++++ examples/workload_metadata_config/outputs.tf | 34 +++++++++++ .../workload_metadata_config/test_outputs.tf | 1 + .../workload_metadata_config/variables.tf | 53 +++++++++++++++++ test/ci/workload-metadata-config.yml | 18 ++++++ .../workload_metadata_config/example.tf | 29 ++++++++++ .../workload_metadata_config/network.tf | 49 ++++++++++++++++ .../workload_metadata_config/outputs.tf | 1 + .../workload_metadata_config/terraform.tfvars | 1 + .../workload_metadata_config/variables.tf | 1 + .../controls/gcloud.rb | 58 +++++++++++++++++++ .../workload_metadata_config/inspec.yml | 11 ++++ 14 files changed, 366 insertions(+) create mode 100644 examples/workload_metadata_config/README.md create mode 100644 examples/workload_metadata_config/main.tf create mode 100644 examples/workload_metadata_config/outputs.tf create mode 120000 examples/workload_metadata_config/test_outputs.tf create mode 100644 examples/workload_metadata_config/variables.tf create mode 100644 test/ci/workload-metadata-config.yml create mode 100644 test/fixtures/workload_metadata_config/example.tf create mode 100644 test/fixtures/workload_metadata_config/network.tf create mode 120000 test/fixtures/workload_metadata_config/outputs.tf create mode 120000 test/fixtures/workload_metadata_config/terraform.tfvars create mode 120000 test/fixtures/workload_metadata_config/variables.tf create mode 100644 test/integration/workload_metadata_config/controls/gcloud.rb create mode 100644 test/integration/workload_metadata_config/inspec.yml diff --git a/.kitchen.yml b/.kitchen.yml index 7c3e2fea07..da159806dc 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -104,3 +104,10 @@ suites: systems: - name: stub_domains_private backend: local + - name: "workload_metadata_config" + driver: + root_module_directory: test/fixtures/workload_metadata_config + verifier: + systems: + - name: workload_metadata_config + backend: local diff --git a/examples/workload_metadata_config/README.md b/examples/workload_metadata_config/README.md new file mode 100644 index 0000000000..19b990d963 --- /dev/null +++ b/examples/workload_metadata_config/README.md @@ -0,0 +1,46 @@ +# Workload Metadata Config Cluster + +This example illustrates how to use a cluster with `workload_metadata_config` defined. + +[^]: (autogen_docs_start) + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|:----:|:-----:|:-----:| +| cluster\_name\_suffix | A suffix to append to the default cluster name | string | `""` | no | +| compute\_engine\_service\_account | Service account to associate to the nodes in the cluster | string | n/a | yes | +| ip\_range\_pods | The secondary ip range to use for pods | string | n/a | yes | +| ip\_range\_services | The secondary ip range to use for pods | string | n/a | yes | +| network | The VPC network to host the cluster in | string | n/a | yes | +| project\_id | The project ID to host the cluster in | string | n/a | yes | +| region | The region to host the cluster in | string | n/a | yes | +| subnetwork | The subnetwork to host the cluster in | string | n/a | yes | +| zones | The zone to host the cluster in (required if is a zonal cluster) | list | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| ca\_certificate | | +| client\_token | | +| cluster\_name | Cluster name | +| ip\_range\_pods | The secondary IP range used for pods | +| ip\_range\_services | The secondary IP range used for services | +| kubernetes\_endpoint | | +| location | | +| master\_kubernetes\_version | The master Kubernetes version | +| network | | +| project\_id | | +| region | | +| service\_account | The service account to default running nodes as if not overridden in `node_pools`. | +| subnetwork | | +| zones | List of zones in which the cluster resides | + +[^]: (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/workload_metadata_config/main.tf b/examples/workload_metadata_config/main.tf new file mode 100644 index 0000000000..09df6fbe6d --- /dev/null +++ b/examples/workload_metadata_config/main.tf @@ -0,0 +1,57 @@ +/** + * 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 = "workload-metadata-private" +} + +provider "google-beta" { + version = "~> 2.9.0" + region = "${var.region}" +} + +data "google_compute_subnetwork" "subnetwork" { + name = "${var.subnetwork}" + project = "${var.project_id}" + region = "${var.region}" +} + +module "gke" { + source = "../../modules/beta-private-cluster/" + project_id = "${var.project_id}" + name = "${local.cluster_type}-cluster${var.cluster_name_suffix}" + 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}" + service_account = "${var.compute_engine_service_account}" + enable_private_endpoint = true + enable_private_nodes = true + master_ipv4_cidr_block = "172.16.0.0/28" + node_metadata = "SECURE" + + master_authorized_networks_config = [{ + cidr_blocks = [{ + cidr_block = "${data.google_compute_subnetwork.subnetwork.ip_cidr_range}" + display_name = "VPC" + }] + }] +} + +data "google_client_config" "default" {} diff --git a/examples/workload_metadata_config/outputs.tf b/examples/workload_metadata_config/outputs.tf new file mode 100644 index 0000000000..9881585a48 --- /dev/null +++ b/examples/workload_metadata_config/outputs.tf @@ -0,0 +1,34 @@ +/** + * 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}" +} + +output "service_account" { + description = "The service account to default running nodes as if not overridden in `node_pools`." + value = "${module.gke.service_account}" +} diff --git a/examples/workload_metadata_config/test_outputs.tf b/examples/workload_metadata_config/test_outputs.tf new file mode 120000 index 0000000000..17b34213ba --- /dev/null +++ b/examples/workload_metadata_config/test_outputs.tf @@ -0,0 +1 @@ +../../test/fixtures/all_examples/test_outputs.tf \ No newline at end of file diff --git a/examples/workload_metadata_config/variables.tf b/examples/workload_metadata_config/variables.tf new file mode 100644 index 0000000000..847277a5ba --- /dev/null +++ b/examples/workload_metadata_config/variables.tf @@ -0,0 +1,53 @@ +/** + * 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 "cluster_name_suffix" { + description = "A suffix to append to the default cluster name" + default = "" +} + +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/test/ci/workload-metadata-config.yml b/test/ci/workload-metadata-config.yml new file mode 100644 index 0000000000..23874671db --- /dev/null +++ b/test/ci/workload-metadata-config.yml @@ -0,0 +1,18 @@ +--- + +platform: linux + +inputs: +- name: pull-request + path: terraform-google-kubernetes-engine + +run: + path: make + args: ['test_integration'] + dir: terraform-google-kubernetes-engine + +params: + SUITE: "workload-metadata-config-local" + COMPUTE_ENGINE_SERVICE_ACCOUNT: "" + REGION: "us-east4" + ZONES: '["us-east4-a", "us-east4-b", "us-east4-c"]' \ No newline at end of file diff --git a/test/fixtures/workload_metadata_config/example.tf b/test/fixtures/workload_metadata_config/example.tf new file mode 100644 index 0000000000..3007ba4163 --- /dev/null +++ b/test/fixtures/workload_metadata_config/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/workload_metadata_config" + + project_id = "${var.project_id}" + cluster_name_suffix = "-${random_string.suffix.result}" + region = "${var.region}" + zones = ["${slice(var.zones,0,1)}"] + 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/workload_metadata_config/network.tf b/test/fixtures/workload_metadata_config/network.tf new file mode 100644 index 0000000000..0f7492d884 --- /dev/null +++ b/test/fixtures/workload_metadata_config/network.tf @@ -0,0 +1,49 @@ +/** + * 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. + */ + +resource "random_string" "suffix" { + length = 4 + special = false + upper = false +} + +provider "google-beta" { + project = "${var.project_id}" +} + +resource "google_compute_network" "main" { + project = "${var.project_id}" + name = "cft-gke-test-${random_string.suffix.result}" + auto_create_subnetworks = "false" +} + +resource "google_compute_subnetwork" "main" { + project = "${var.project_id}" + 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/workload_metadata_config/outputs.tf b/test/fixtures/workload_metadata_config/outputs.tf new file mode 120000 index 0000000000..726bdc722f --- /dev/null +++ b/test/fixtures/workload_metadata_config/outputs.tf @@ -0,0 +1 @@ +../shared/outputs.tf \ No newline at end of file diff --git a/test/fixtures/workload_metadata_config/terraform.tfvars b/test/fixtures/workload_metadata_config/terraform.tfvars new file mode 120000 index 0000000000..08ac6f4724 --- /dev/null +++ b/test/fixtures/workload_metadata_config/terraform.tfvars @@ -0,0 +1 @@ +../shared/terraform.tfvars \ No newline at end of file diff --git a/test/fixtures/workload_metadata_config/variables.tf b/test/fixtures/workload_metadata_config/variables.tf new file mode 120000 index 0000000000..c113c00a3d --- /dev/null +++ b/test/fixtures/workload_metadata_config/variables.tf @@ -0,0 +1 @@ +../shared/variables.tf \ No newline at end of file diff --git a/test/integration/workload_metadata_config/controls/gcloud.rb b/test/integration/workload_metadata_config/controls/gcloud.rb new file mode 100644 index 0000000000..ea9c3627ce --- /dev/null +++ b/test/integration/workload_metadata_config/controls/gcloud.rb @@ -0,0 +1,58 @@ +# 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') + +control "gcloud" do + title "Google Compute Engine GKE configuration" + describe command("gcloud beta --project=#{project_id} container clusters --zone=#{location} describe #{cluster_name} --format=json --format=\"json(nodePools[0].config.workloadMetadataConfig.nodeMetadata)\"") 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 "workload metada config" do + it "is secure" do + expect(data['nodePools'][0]["config"]["workloadMetadataConfig"]["nodeMetadata"]).to eq 'SECURE' + end + end + end + + describe command("gcloud beta --project=#{project_id} container clusters --zone=#{location} describe #{cluster_name} --format=json --format=\"json(nodeConfig.workloadMetadataConfig)\"") 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 "workload metada config" do + it "is secure" do + expect(data["nodeConfig"]["workloadMetadataConfig"]["nodeMetadata"]).to eq 'SECURE' + end + end + end +end diff --git a/test/integration/workload_metadata_config/inspec.yml b/test/integration/workload_metadata_config/inspec.yml new file mode 100644 index 0000000000..f6f3811afa --- /dev/null +++ b/test/integration/workload_metadata_config/inspec.yml @@ -0,0 +1,11 @@ +name: workload_metadata_config +attributes: + - name: cluster_name + required: true + type: string + - name: location + required: true + type: string + - name: project_id + required: true + type: string From 589e7c933a9ec317a47900f8c906fc66dab292ca Mon Sep 17 00:00:00 2001 From: Marko Vlahovic Date: Wed, 3 Jul 2019 13:03:21 -0700 Subject: [PATCH 4/4] Preventing node-pool recreting if switching from regular to beta module --- autogen/cluster_regional.tf | 8 ++------ autogen/cluster_zonal.tf | 8 ++------ autogen/main.tf | 7 +++++++ modules/beta-private-cluster/cluster_regional.tf | 8 ++------ modules/beta-private-cluster/cluster_zonal.tf | 8 ++------ modules/beta-private-cluster/main.tf | 8 ++++++++ modules/beta-public-cluster/cluster_regional.tf | 8 ++------ modules/beta-public-cluster/cluster_zonal.tf | 8 ++------ modules/beta-public-cluster/main.tf | 8 ++++++++ 9 files changed, 35 insertions(+), 36 deletions(-) diff --git a/autogen/cluster_regional.tf b/autogen/cluster_regional.tf index ff3aee7a94..847d2808fe 100644 --- a/autogen/cluster_regional.tf +++ b/autogen/cluster_regional.tf @@ -107,9 +107,7 @@ resource "google_container_cluster" "primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" {% if beta_cluster %} - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" {% endif %} } } @@ -175,9 +173,7 @@ resource "google_container_node_pool" "pools" { } {% if beta_cluster %} - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" {% endif %} } diff --git a/autogen/cluster_zonal.tf b/autogen/cluster_zonal.tf index a551ffebbf..c03c57a0f8 100644 --- a/autogen/cluster_zonal.tf +++ b/autogen/cluster_zonal.tf @@ -108,9 +108,7 @@ resource "google_container_cluster" "zonal_primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" {% if beta_cluster %} - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" {% endif %} } } @@ -176,9 +174,7 @@ resource "google_container_node_pool" "zonal_pools" { } {% if beta_cluster %} - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" {% endif %} } diff --git a/autogen/main.tf b/autogen/main.tf index adc2a5cd1a..690658f3b4 100644 --- a/autogen/main.tf +++ b/autogen/main.tf @@ -52,7 +52,14 @@ locals { enabled = [{disabled = "false"}] disabled = [] } +{% if beta_cluster %} + + cluster_node_metadata_config = { + specified = [{node_metadata = "${var.node_metadata}"}] + unspecified = [] + } +{% endif %} 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)}" diff --git a/modules/beta-private-cluster/cluster_regional.tf b/modules/beta-private-cluster/cluster_regional.tf index 938bbe1734..97ca1475af 100644 --- a/modules/beta-private-cluster/cluster_regional.tf +++ b/modules/beta-private-cluster/cluster_regional.tf @@ -102,9 +102,7 @@ resource "google_container_cluster" "primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" } } @@ -164,9 +162,7 @@ resource "google_container_node_pool" "pools" { count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" } lifecycle { diff --git a/modules/beta-private-cluster/cluster_zonal.tf b/modules/beta-private-cluster/cluster_zonal.tf index 7d73fa9ef9..f9bded28f8 100644 --- a/modules/beta-private-cluster/cluster_zonal.tf +++ b/modules/beta-private-cluster/cluster_zonal.tf @@ -103,9 +103,7 @@ resource "google_container_cluster" "zonal_primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" } } @@ -165,9 +163,7 @@ resource "google_container_node_pool" "zonal_pools" { count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" } lifecycle { diff --git a/modules/beta-private-cluster/main.tf b/modules/beta-private-cluster/main.tf index 564136315b..761aab9a5b 100644 --- a/modules/beta-private-cluster/main.tf +++ b/modules/beta-private-cluster/main.tf @@ -59,6 +59,14 @@ locals { disabled = [] } + cluster_node_metadata_config = { + specified = [{ + node_metadata = "${var.node_metadata}" + }] + + unspecified = [] + } + 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)}" diff --git a/modules/beta-public-cluster/cluster_regional.tf b/modules/beta-public-cluster/cluster_regional.tf index 2676427617..88f2aa089c 100644 --- a/modules/beta-public-cluster/cluster_regional.tf +++ b/modules/beta-public-cluster/cluster_regional.tf @@ -102,9 +102,7 @@ resource "google_container_cluster" "primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" } } @@ -158,9 +156,7 @@ resource "google_container_node_pool" "pools" { count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" } lifecycle { diff --git a/modules/beta-public-cluster/cluster_zonal.tf b/modules/beta-public-cluster/cluster_zonal.tf index e25f61e7ed..66d0352011 100644 --- a/modules/beta-public-cluster/cluster_zonal.tf +++ b/modules/beta-public-cluster/cluster_zonal.tf @@ -103,9 +103,7 @@ resource "google_container_cluster" "zonal_primary" { node_config { service_account = "${lookup(var.node_pools[0], "service_account", local.service_account)}" - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" } } @@ -159,9 +157,7 @@ resource "google_container_node_pool" "zonal_pools" { count = "${lookup(var.node_pools[count.index], "accelerator_count", 0)}" } - workload_metadata_config { - node_metadata = "${var.node_metadata}" - } + workload_metadata_config = "${local.cluster_node_metadata_config["${var.node_metadata == "UNSPECIFIED" ? "unspecified" : "specified"}"]}" } lifecycle { diff --git a/modules/beta-public-cluster/main.tf b/modules/beta-public-cluster/main.tf index 712b943b67..30f48438dc 100644 --- a/modules/beta-public-cluster/main.tf +++ b/modules/beta-public-cluster/main.tf @@ -59,6 +59,14 @@ locals { disabled = [] } + cluster_node_metadata_config = { + specified = [{ + node_metadata = "${var.node_metadata}" + }] + + unspecified = [] + } + 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)}"